使用全局变量的递归函数中的GCC优化差异

Pet*_*ter 7 c gcc

前几天我遇到了一个使用GCC和'-Ofast'优化标志的奇怪问题.使用'gcc -Ofast -o fib1 fib1.c'编译以下程序.

#include <stdio.h>

int f1(int n) {
    if (n < 2) {
        return n;
    }
    int a, b;
    a = f1(n - 1);
    b = f1(n - 2);
    return a + b;
}

int main(){
    printf("%d", f1(40));
}
Run Code Online (Sandbox Code Playgroud)

在测量执行时间时,结果是:

peter@host ~ $ time ./fib1
102334155
real    0m0.511s
user    0m0.510s
sys     0m0.000s
Run Code Online (Sandbox Code Playgroud)

现在让我们在程序中引入一个全局变量,然后使用'gcc -Ofast -o fib2 fib2.c'再次编译.

#include <stdio.h>

int global;

int f1(int n) {
    if (n < 2) {
        return n;
    }
    int a, b;
    a = f1(n - 1);
    b = f1(n - 2);

    global = 0;

    return a + b;
}

int main(){
    printf("%d", f1(40));
}
Run Code Online (Sandbox Code Playgroud)

现在执行时间是:

peter@host ~ $ time ./fib2
102334155
real    0m0.265s
user    0m0.265s
sys     0m0.000s
Run Code Online (Sandbox Code Playgroud)

新的全局变量没有任何意义.但是,执行时间的差异很大.

除了问题(1)这种行为的原因是什么,如果(2)在不引入无意义的变量的情况下可以实现最后的表现,那也是很好的.有什么建议?

谢谢彼得

Rom*_*sev 0

在我的机器上 ( gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010) 我有这个:
time ./fib1 0,36s user 0,00s system 98% cpu 0,364 total
time ./fib2 0,20s user 0,00s system 98% cpu 0,208 total

man gcc

-Ofast
无视严格的标准合规性。-Ofast 启用所有 -O3 优化。它还可以实现并非对所有符合标准的程序都有效的优化。它打开 -ffast-math 以及 Fortran 特定的 -fno-protect-parens 和 -fstack-arrays。

不太安全的选择,让我们尝试一下-O2
time ./fib1 0,38s user 0,00s system 99% cpu 0,377 total
time ./fib2 0,47s user 0,00s system 99% cpu 0,470 total

我认为,一些激进的优化并未应用于fib1,而是应用于fib2. 当我切换-Ofast-O2- 时,一些优化并未应用于fib2,而是应用于fib1.

咱们试试吧-O0
time ./fib1 0,81s user 0,00s system 99% cpu 0,812 total
time ./fib2 0,81s user 0,00s system 99% cpu 0,814 total

未经优化,它们是相等的。
因此,在递归函数中引入全局变量,一方面可以破坏某些优化,另一方面可以改善其他优化。