有谁知道是否有一份编译器优化源代码的 list ?我更喜欢 GCC 作为示例。
我想知道程序员应该如何处理代码以获得良好的优化并帮助编译器对其进行优化。程序员的一些优化可能会避免编译器做更好的优化。
例子:
replace
for (int i = 0; i < n - 1; i++ )
by
int n2 = n - 1;
for (int i = 0; i < n2; i++ )
for (int i = 0; i < n/2; i++ )
by
int n2 = n/2;
for (int i = 0; i < n2; i++ )
for (int i = 0; i < obj.calc_value(); i++ ) //calc_value() will return the same result with obj remaining unchanged.
by
int y = obj.calc_value()
for (int i = 0; i < y; i++ )
保持代码易于阅读和理解很重要。
谢谢
编辑:
其他例子:
- 内联函数
- 移除递归
最佳答案
说真的,把它留给编译器吧。我见过 gcc 在其“疯狂的”-O3
级别输出的代码,这证明编写这些优化引擎的人要么是外星人,要么来自遥远的 future 。
我还没有看到 register
或 inline
对我的代码性能产生明显影响的情况。这并不意味着它不会,只是编译器编写者在从处理器中提取最后一点性能时比我们这些凡人知道的技巧多得多。
就优化而言,只应在存在真正问题的地方进行。这意味着分析代码并发现瓶颈,但更重要的是,不优化在上下文中不被视为缓慢的操作。一次操作需要十分之一秒还是百分之一秒,对用户而言差异为零。
有时,优化可读性是您能做的最好的事情:-)
顺便说一句,这只是 gcc 为您做的绝妙技巧中的一个。考虑以下应该计算阶乘并返回它的代码:
static int fact (unsigned int n) {
if (n == 0) return 1;
return n * fact (n-1);
}
int main (void) {
return fact (6);
}
编译为(在 -O3
):
main: pushl %ebp ; stack frame setup.
movl $720, %eax ; just load 720 (6!) into eax.
movl %esp, %ebp ; stack frame
popl %ebp ; tear-down.
ret ; and return.
没错,gcc 只是在编译时完成所有工作,并将整个事情变成等同于:
int main (void) { return 720; }
将此与 -O0
(原始)版本进行对比:
main: pushl %ebp ; stack
movl %esp, %ebp ; frame
andl $-16, %esp ; set
subl $16, %esp ; up.
movl $6, (%esp) ; pass 6 as parameter.
call fact ; call factorial function.
leave ; stack frame tear down.
ret ; and exit.
fact: pushl %ebp ; stack
movl %esp, %ebp ; frame
subl $24, %esp ; set up.
cmpl $0, 8(%ebp) ; passed param zero?
jne .L2 ; no, keep going.
movl $1, %eax ; yes, set return to 1.
jmp .L3 ; goto return bit.
.L2: movl 8(%ebp), %eax ; get parameter.
subl $1, %eax ; decrement.
movl %eax, (%esp) ; pass that value to next level down.
call fact ; call factorial function.
imull 8(%ebp), %eax ; multiply return value by passed param.
.L3: leave ; stack frame tear down.
ret ; and exit.
关于c++ - 编写代码帮助编译器进行优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5467414/