下面是一个C函数来评估多项式:为什么-O1比-O2快10000次?
/* Calculate a0 + a1*x + a2*x^2 + ... + an*x^n */
/* from CSAPP Ex.5.5, modified to integer version */
int poly(int a[], int x, int degree) {
long int i;
int result = a[0];
int xpwr = x;
for (i = 1; i <= degree; ++i) {
result += a[i]*xpwr;
xpwr *= x;
}
return result;
}
和一个主功能:
#define TIMES 100000ll
int main(void) {
long long int i;
unsigned long long int result = 0;
for (i = 0; i < TIMES; ++i) {
/* g_a is an int[10000] global variable with all elements equals to 1 */
/* x = 2, i.e. evaluate 1 + 2 + 2^2 + ... + 2^9999 */
result += poly(g_a, 2, 9999);
}
printf("%lld\n", result);
return 0;
}
当我编译与海湾合作委员会和选项-O1和-02程序分开,我发现, -O1比-O2快很多。
平台详细信息:
- i5-4600
- Arch Linux的x86_64的内核3.18
- GCC 4.9.2
- 的gcc -o -O1 /tmp/a.out test.c的
- 的gcc -o -02 /tmp/a.out test.c的
结果:
- 当次= 100000ll,-O1即刻打印出结果,而-02需要0.36s
- 当次= 1000000000ll,-O1打印结果0.28s,-02花费这么长时间,我没有完成测试
似乎-O1比-O2快大约10000倍。
当我测试它在Mac(铛-600.0.56),其结果是更加怪异:-O1时间不超过0.02秒,即使TIMES = 1000000000000000000ll
我已经测试下列的变化:
- 使得G_A随机(元素是从1到10)
- X = 19234(或某个其他数目)
- 使用int代替长长整型
结果是一样的。
我试着看看汇编代码,看起来-O1调用poly函数,而-O2做内联优化。但内联应该使表现更好,不是吗?
是什么使这些巨大的差异?为什么-O1在铿锵声中可以让节目如此之快?是-O1做错了什么? (我不能检查结果,因为它太慢没有优化)
x = 1呢?我试图通过使用scanf来获得x,然后将它传递给poly调用,结果是一样的。我认为这不是主要问题...... – nnkken 2015-03-02 10:49:00