我有一个速度至关重要的项目,因此正在尝试使用编译器标志来尝试获得一些免费性能。我有两个相同的构建,除了构建 2 中的附加标志 March=native 之外。
为了完整起见,标志是:
A)-std=c++14 -g -fno-省略帧指针-O3
B) -std=c++14 -g -fno-omit-frame-pointer -O3 -march-native
在这些构建上运行基准测试会产生令人困惑的结果:
A) 61 秒
B) 160 秒
这里可能发生什么?
使用
-march=native
可以优化当前 CPU 的代码。大多数时候,它会提高执行速度。有时它可能无法生成最快的代码,因为它启用了某些 CPU 指令。
echo | clang -E - -march=native -###
将显示 clang 通过
-march=native
启用的内容。最有可能的罪魁祸首是 CMOV
,它是由 -march=native
启用的。您可以在这个问题的答案中看到为什么这可能会减慢速度的解释:gcc 优化标志 -O3 使代码比 -O2 慢。
-march=native
使clang针对您当前的CPU优化代码。在这种情况下,clang 使用尽可能多的优化,并且使用它可能会破坏与其他 CPU 的兼容性,例如,这些 CPU 不支持 AVX2、SSSE3 等某些指令集。你可以跑步
echo | clang -E - -O3 -###
和
clang -E - -march=native -O3 -###
获取在这两种情况下激活的功能列表。
march=native
为您的 CPU 微架构启用额外的 CPU 指令,但不一定有益。它可以提高某些情况下的性能,例如数值计算。但它在许多其他情况中没有好处,并且有时是有害的。 本质上,我认为启用原生 arch 指令能否提升性能取决于 AVX 等 SIMD 指令带来的加速与
AVX Downclocking带来的拖累之间的斗争。