Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
gcc优化什么时候最有效?_C_Gcc - Fatal编程技术网

gcc优化什么时候最有效?

gcc优化什么时候最有效?,c,gcc,C,Gcc,当我通过-O3选项使用gcc编译C代码时,与未进行优化编译时相比,它通常会减少大约10~30%的运行时间。今天,我发现使用-O3选项,我的一个程序的运行时间显著缩短,约为1/10。在没有优化的情况下,大约需要7秒才能完成。但是-O3选项在0.7秒内运行!我从未见过如此惊人的时间缩减 所以在这里我想知道什么类型的程序模式更有可能从gcc优化选项中受益,或者在编程中是否有一些方法可以更切实地进行优化 1/10代码如下。这是一个简单的程序,使用轮分解算法计算所有小于宏常量MAXX的素数之和 #incl

当我通过-O3选项使用gcc编译C代码时,与未进行优化编译时相比,它通常会减少大约10~30%的运行时间。今天,我发现使用-O3选项,我的一个程序的运行时间显著缩短,约为1/10。在没有优化的情况下,大约需要7秒才能完成。但是-O3选项在0.7秒内运行!我从未见过如此惊人的时间缩减

所以在这里我想知道什么类型的程序模式更有可能从gcc优化选项中受益,或者在编程中是否有一些方法可以更切实地进行优化

1/10代码如下。这是一个简单的程序,使用轮分解算法计算所有小于宏常量MAXX的素数之和

#include <stdio.h>
#include <math.h>
#include <inttypes.h>
#include <time.h>

#define MAXX 5000000
#define PBLEN 92160
#define PBMAX 510510

int main(){
    clock_t startT, endT;
    startT = clock();
    int pArr[7] = {2, 3, 5, 7, 11, 13, 17};
    int pBase[PBLEN];
    pBase[0] = 1;
    int i, j, k, index = 1;
    for (i = 19; i <= PBMAX; ++i){
        for (j = 0; j < 7; ++j){
            if (i % pArr[j] == 0){
                goto next1;
            }
        }
        pBase[index] = i;
        ++index;
        next1:;
    }
    uint64_t sum = 2 + 3 + 5 + 7 + 11 + 13 + 17;
    for (i = 1; i < PBLEN; ++i){
        for (j = 0; j < 7; ++j){
            if (pArr[j] <= (int)sqrt((double)pBase[i]) + 1){
                if (pBase[i] % pArr[j] == 0){
                    goto next2;
                }
            }
            else{
                sum += pBase[i];
                goto next2;
            }
        }
        for (j = 1; j < PBLEN; ++j){
            if (pBase[j] <= (int)sqrt((double)pBase[i]) + 1){
                if (pBase[i] % pBase[j] == 0){
                    goto next2;
                }
            }
            else{
                sum += pBase[i];
                goto next2;
            }
        }
        next2:;
    }
    int temp, temp2;
    for (i = PBMAX; ; i += PBMAX){
        for (j = 0; j < PBLEN; ++j){
            temp = i + pBase[j];
            if (temp > MAXX){
                endT = clock();
                printf("%"PRIu64"\n\n", sum);
                printf("%.3f\n", (double)(endT - startT) / (double)CLOCKS_PER_SEC);
                return 0;
            }
            for (k = 0; k < 7; ++k){
                if (temp % pArr[k] == 0){
                    goto next3;
                }
            }
            for (k = 1; k < PBLEN; ++k){
                if (pBase[k] <= (int)sqrt((double)temp) + 1){
                    if (temp % pBase[k] == 0){
                        goto next3;
                    }
                }
                else{
                    sum += temp;
                    break;
                }
            }
            next3:;
        }
    }
}
#包括
#包括
#包括
#包括
#定义MAXX 5000000
#定义PBLEN 92160
#定义PBMAX 510510
int main(){
时钟开始,结束;
startT=时钟();
int pArr[7]={2,3,5,7,11,13,17};
int-pBase[PBLEN];
pBase[0]=1;
int i,j,k,指数=1;

对于(i=19;i我将通过查看您的代码来猜测这是如何发生的。到目前为止,我猜花费时间最长的是sqrt()。您在一个不变的值上运行sqrt()时有一个紧密的循环。gcc可能会决定进行一次调用,保存返回,然后重用它。同样的结果,对sqrt()的调用要少得多,因此运行时间大大加快。如果您将对sqrt()的调用移出紧密循环并少运行它们,您可能会手动看到相同的结果。不过,请运行探查器以确定


因此,简单的回答是——有时候gcc可以解决你本可以自己解决的重大问题,但前提是这些问题的范围很小。通常你需要坐下来使用剖析器,看看到底是什么占用了你的时间,以及如何解决这个问题。

要了解情况,请编译到汇编:
gcc-o O3.s-O3 main.c
and
gcc-oo0.s-O0 main.c
。然后检查并比较程序集源(.s文件)。Hyde是正确的,但您必须使用
-s
选项来获取汇编程序输出(她可能刚刚忘记了)。谢谢!您绝对正确!在我取出sqrt()之后作为循环外的一个临时变量,没有优化的运行时间也是0.7秒。现在使用-O3,它将减少到0.45秒。我真的应该尝试更多,不要犯如此明显的错误;智能编译器也给我留下了深刻的印象。