c++ - 编写代码帮助编译器进行优化

标签 c++ compiler-optimization

有谁知道是否有一份编译器优化源代码的 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 。

我还没有看到 registerinline 对我的代码性能产生明显影响的情况。这并不意味着它不会,只是编译器编写者在从处理器中提取最后一点性能时比我们这些凡人知道的技巧多得多。

就优化而言,只应在存在真正问题的地方进行。这意味着分析代码并发现瓶颈,但更重要的是,不优化在上下文中不被视为缓慢的操作。一次操作需要十分之一秒还是百分之一秒,对用户而言差异为零。

有时,优化可读性是您能做的最好的事情:-)


顺便说一句,这只是 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/

相关文章:

c++ - 浮点比较失败且没有任何明显原因(Linux 上的 32 位 X86)

c++ - 无法解析类型 'uint32_t'

c++ - 如何优雅高效地将文件读入vector?

python - 减少输入矩阵系数所需的时间

performance - APL 如何优化以在阵列处理方面具有出色的性能?它执行了哪些示例技巧和优化?

c - 使用 AVX 指令和 -O3 编译选项得到错误的结果

c++ - 模板实际上必须是编译时构造吗?

c++ - 为什么我的 token 粘贴用法不起作用?

c++ - 为什么 C 宏不是类型安全的?

c - 为什么clang用-O0产生效率低的asm(对于这个简单的 float 和)?