编译器优化导致程序运行速度变慢

mta*_*med 9 c gcc compiler-optimization

我在C中编写了以下代码.它非常简单,因为它恰好x为每个for循环进行了位移.

int main() {
   int x = 1;
   for (int i = 0; i > -2; i++) {
      x >> 2;
   }
}
Run Code Online (Sandbox Code Playgroud)

现在正在发生奇怪的是,当我刚刚编译它没有任何的优化或第一级优化(-O),它运行得很好(我定时可执行文件及其有关1.4s-O5.4s没有任何优化.

现在,当我添加-O2-O3切换编译并为生成的可执行文件计时时,它不会停止(我已经测试过60s).

关于可能导致这种情况的任何想法?

Joe*_*Joe 17

优化的循环产生一个无限循环,这是您依赖于有符号整数溢出的结果.有符号整数溢出是未定义的行为,C不应该依赖.它不仅会使开发人员感到困惑,而且编译器也可能会对其进行优化.

汇编(无优化): gcc -std=c99 -S -O0 main.c

_main:
LFB2:
    pushq   %rbp
LCFI0:
    movq    %rsp, %rbp
LCFI1:
    movl    $1, -4(%rbp)
    movl    $0, -8(%rbp)
    jmp L2
L3:
    incl    -8(%rbp)
L2:
    cmpl    $-2, -8(%rbp)
    jg  L3
    movl    $0, %eax
    leave
    ret
Run Code Online (Sandbox Code Playgroud)


装配(优化级别3):gcc -std = c99 -S -O3 main.c

_main:
LFB2:
    pushq   %rbp
LCFI0:
    movq    %rsp, %rbp
LCFI1:
L2:
    jmp L2  #<- infinite loop
Run Code Online (Sandbox Code Playgroud)

  • @tskuzzy,*signed*整数溢出是UB.`unsigned`整数表现良好,只是环绕.因此,当转换为"unsigned"设置时,OP的循环将非常有效. (3认同)

Oli*_*rth 7

通过查看生成的二进制文件(使用objdump或其他东西),您将获得明确的答案.

但正如其他人所说,这可能是因为你依赖于未定义的行为.一种可能的解释是编译器可以自由地假设i永远不会小于-2,因此将完全消除条件,并将其转换为无限循环.

此外,您的代码没有可观察到的副作用,因此编译器也可以自由地优化整个程序,如果它喜欢的话.