如果我想最小化我的c程序运行的时间,我应该使用什么优化标志(我也想保持标准)
目前我正在使用:
-Wall -Wextra -pedantic -ansi -O3
我还应该使用
-std=c99
例如?
是否有特定的命令我应该将这些标志放在我的makefile上?这有什么不同吗?
而且,有没有理由不使用我能找到的所有优化标志?他们曾经反对过彼此或类似的东西吗?
答案 0 :(得分:3)
标记-std=c99
不会更改优化级别。它只会更改您希望编译器确认的目标语言标准。
如果希望编译器将程序视为C99程序,则使用-std=c99
。
答案 1 :(得分:1)
在您指定的内容中,唯一与优化有关的标志是=D4
。其他用于其他目的。
您可能希望添加-O3
和-funroll-loops
,但它们应该已包含在-fomit-frame-pointer
中。
答案 2 :(得分:1)
我建议使用-std=gnu11
或-std=c11
编译新代码(如果需要)。沉默所有-Wall
警告通常是个好主意,IIRC。 -Wextra
警告你可能不想改变的一些事情。
检查编译内容的好方法是查看编译器asm输出。 http://gcc.godbolt.org/很好地格式化asm输出(去除噪声)。如果您完全理解asm,那么在那里放置一些关键函数并查看不同编译器版本的作用是有用的。
使用新的编译器版本。 gcc和clang在新版本中都有显着提升。 gcc 5.3和clang 3.8是当前版本。在某些情况下,gcc5的代码明显比gcc 4.9.3好。
如果您只需要在自己的计算机上运行二进制文件,则应使用-O3 -march=native
。
如果您需要在其他计算机上运行二进制文件,请使用-mssse3 -mpopcnt
之类的内容选择指令集扩展的基线。即使在制作仍在较旧CPU上运行的代码(由-mtune=haswell
确定)时,您也可以使用-march
优化Haswell。
如果您的程序不依赖于严格的FP舍入行为,请使用-ffast-math
。如果是这样,您通常仍然可以使用-fno-math-errno
之类的东西,而不启用-funsafe-math-optimizations
。一些FP代码可以从快速数学中获得大加速,如自动矢量化。
如果您可以有用地执行程序的测试运行,该程序运行需要针对实际运行进行优化的大多数代码路径,那么使用配置文件定向优化:
gcc -fprofile-generate -Wall -Wextra -std=gnu11 -O3 -ffast-math -march=native -fwhole-program *.c -o my_program
./my_program -option1 < test_input1
./my_program -option2 < test_input2
gcc -fprofile-use -Wall -Wextra -std=gnu11 -O3 -ffast-math -march=native -fwhole-program *.c -o my_program
-fprofile-use
启用-funroll-loops
,因为它有足够的信息来决定何时实际展开。在整个地方展开循环会让事情变得更糟。但是,值得尝试-funroll-loops
以确定它是否有帮助。
如果您的测试运行不涵盖所有代码路径,那么一些重要的代码路径将被标记为&#34; cold&#34;并且优化得更少。
-O3
启用自动向量化,-O2
不会。这可以带来很大的加速
-fwhole-program
允许跨文件内联,但只有在将所有源文件放在一个gcc命令行上时才有效。 -flto
是获得相同效果的另一种方式。 (链接时优化)。 clang支持-flto
但不支持-fwhole-program
。
-fomit-frame-pointer
一直是x86-64的默认值,最近是x86(32位)的默认值。
与gcc一样,尝试使用clang编译程序。 Clang有时会比gcc做出更好的代码,有时甚至更糟。尝试两者和基准。