假设我有一个 CMake 项目,它生成一个 CPU 密集型应用程序。
当我为二进制分发或性能基准测试构建二进制文件时,我希望它们能够得到最大程度的优化,或者至少是高度优化。当然,某些优化是一种权衡,并不总是能提高性能,但我的意思是那些被认为“通常足够好”可以普遍应用的优化,即在没有分析的情况下应用于程序;例如,对于 GCC,这些标志可能是
-O3 -march=native
之类的标志,也可能是其他标志。
现在,当我浏览 CMake 文档时,如果我使用
Release
构建类型,我不太能保证会为我完成类似的事情。
CMAKE_<LANG>_FLAGS_RELEASE
变量,在我的具体情况下为 CMAKE_CPP_FLAGS_RELEASE
。但是 - 然后我需要:
基于此 - 以及哪些编译器提供哪种优化以及如何启用它们的知识 - 我可以设置这些标志,例如在辅助模块中。
但是 - 这些设置都不是特定于我的项目和我正在编译的程序的。我想知道为什么 CMake 不为我们做这个......
无论如何,如果我们不能把事情交给 CMake 来处理——对于许多编译器和跨多个平台来说,什么是通用的(ish)、惯用的、希望广泛使用的方法来在 CMake 中启用“完整”优化?
在 CMake 中,使用
Release
构建类型自动应用常规优化,例如针对 GCC/Clang 的 -03
。对于特定优化,例如 -march=native
,请在 CMakeLists.txt 中手动设置 CMAKE_CXX_FLAGS_RELEASE
。
为什么 CMake 不为我做这件事?
嗯,CMake 无法为您执行此操作。一般来说,没有人可以。
最佳构建标志可以随着编译器更新、硬件更新和简单代码更改而改变。
找到最佳标志的唯一方法是在干净的实验室环境中,使用您能想到的每个硬件平台、编译器版本和标志组合,运行您自己的真实代码的自动性能基准测试。这实际上并不属于构建配置工具的职权范围。
如果您确实对
-O3 -march=native
(或其他平台的同等内容)感到满意,那么这很容易做到,而且距离最大优化还有很长的路要走。
还有另一种可能等效的看待这个问题的方式。
每个人都认为他们需要的优化级别是应该内置到工具中的合理默认值,并且任何需要更具体标志的人都是一种奇异的边缘情况。
这并不意味着给定样本中的任何两个实际上都会同意这个合理的默认值是什么。如果很容易的话,一开始就不会有那么多旗帜了。