我正在分发一个带有Unix版本的makefile的C ++程序,我想知道我应该使用哪些编译器选项来获得最快的代码(它属于可以使用所有计算能力的程序类别考虑到我事先并不知道用户将拥有什么硬件,操作系统或gcc版本,他们可以得到并且仍然可以回来更多),我最重要的是要确保它至少在每个专业都能正常工作类Unix操作系统。
到目前为止,我有g++ -O3 -Wno-write-strings
,我还应该添加其他选项吗?在Windows上,Microsoft编译器可以选择快速调用约定和链接时间代码生成等值得使用的选项,gcc上有没有等价物?
(我假设它在64位平台上默认为64位,如果不是这样,请纠正我。)
答案 0 :(得分:16)
在不了解您的计划的任何细节的情况下,很难说。 O3涵盖了大多数优化。其余选项“需要付费”。如果您可以容忍一些随机舍入,并且您的代码不依赖于IEEE浮点标准,那么您可以尝试-Ofast。这忽视了标准合规性,可以为您提供更快的代码。
剩余的优化标记只能提高某些程序的性能,但甚至可能对其他程序有害。查看gcc documentation on optimisation flags中的可用标记并对其进行基准测试。
另一种选择是启用C99(-std = c99)和内联适当的函数。这是一个艺术,你不应该内联所有内容,但通过一些工作,你可以让你的代码更快(尽管以更大的可执行文件为代价)。
如果速度真的是一个问题我建议回到微软的编译器,或尝试英特尔。我已经开始意识到一些gcc编译代码的速度有多慢,特别是当它涉及math.h时。
编辑:哦等等,你说C ++?然后忽略我的C99段落,你可以内联:)答案 1 :(得分:13)
我会尝试配置文件引导优化:
-fprofile-generate
启用选项 通常用于仪表 应用程序来生成有用的配置 以后用配置文件重新编译 基于反馈的优化。你必须 两者都使用-fprofile-generate
编译和链接你的 程序。以下选项是 已启用:-fprofile-arcs
,-fprofile-values
,-fvpt
。
您还应该为编译器提供有关程序运行的体系结构的提示。
例如,如果它只能在服务器上运行,并且您可以在与服务器相同的机器上编译它,则可以使用-march=native
。
否则,您需要确定用户将拥有哪些功能,并将相应的参数传递给GCC。
(显然你的目标是64位,所以GCC可能已经包含了比通用x86更多的优化。)
答案 2 :(得分:7)
请尝试 -oFast 而不是 -o3
此处还有一个您可能希望有选择地启用的标记列表。
-ffloat-store
-fexcess精度=风格
-ffast-数学
-fno-舍入数学
-fno-信令的NaN
-fcx-有限范围
-fno-数学错误号
-funsafe-数学优化
-fassociative-数学
-freciprocal-math
-ffinite-数学仅
-fno签名3/0
-fno截留数学
-frounding-数学
-fsingle精度恒定
-fcx-FORTRAN的规则
可以使用完整的标记列表及其详细说明 here
答案 3 :(得分:6)
考虑使用-fomit-frame-pointer
,除非您需要使用gdb进行调试(yuck)。这将为编译器提供一个用于变量的寄存器(否则这个寄存器会浪费在无用的帧指针上)。
此外,您可以使用类似-march=core2
或更一般-march=native
的内容来使编译器能够使用更新的指令并进一步调整指定体系结构的代码,但为此必须确保您的代码将不要指望在较旧的处理器上运行。
答案 4 :(得分:5)
除了别人已经提出的建议外,你当然应该尝试-flto
。它可以实现链接时间优化,在某些情况下,它可以真正发挥魔力。
有关详细信息,请参阅https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
答案 5 :(得分:3)
gcc -O3不保证是最快的。 -O2通常是一个更好的起点。之后,配置文件引导优化并尝试特定选项:http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
这是一个很长的阅读,但可能是值得的。
请注意,gcc 4.5 +
中提供了“链接时间代码生成”(MSVC),即“链接时间优化”顺便说一句,Win64没有特定的“fastcall”调用约定。只有“召集”约会:http://msdn.microsoft.com/en-us/magazine/cc300794.aspx
答案 6 :(得分:1)
x86-64上没有'fastcall' - Win64和Linux ABI都将基于寄存器的调用(“fastcall”)定义为唯一的调用约定(尽管Linux使用更多寄存器)。