我在C中创建了一个程序,它将程序作为输出。
目标是在单片程序中测试性能的各个方面。
第一次测试配置了10 000次迭代,结果程序编译并运行。 在Ubuntu 12.04 x86_64中,在带有16 GB RAM(16 GB SWAP)的i7 3770中进行了第二次100 000次迭代测试(直到现在为止3030分钟)。
我知道解析复杂度从O(n ** 2)到O(n ** 3),但这需要太长时间。 在最糟糕的情况下,编译时间要多1000倍。
消耗35.2%的内存并且仍在增加。
我的问题是:
GCC是否对每个模块或模块大小的变量数量有限制?
这是一个错误吗?
原始程序生成器是:
#include <stdio.h>
#define MAX_INTERACTION 100000
int main(int argc, char **argv)
{
FILE * fp;
fp = fopen("source.c","w");
fprintf(fp,"#include <stdio.h> \n \n \n");
fprintf(fp,"int main(int argc, char **argv) \n");
fprintf(fp,"{ \n");
// local variables and exchange variables
for (int i=0; i< MAX_INTERACTION ; ++i)
{
// passed variable, return label , local variable
fprintf(fp," int pv%d , rl%d, loc%d ; \n",i,i,i);
}
fprintf(fp," int pvd =0 ;\n \n \n");
//code blocks
for (int i=0; i< MAX_INTERACTION ; ++i)
{
fprintf(fp," block%d : \n",i);
fprintf(fp," loc%d = pv%d +1 ; \n",i,i);
fprintf(fp," goto rl%d; \n",i);
}
//call blocks
for (int i=1; i< MAX_INTERACTION +1; ++i)
{
fprintf(fp," pvd = pv%d ;\n",(i-1));
fprintf(fp," goto block%d; \n",(i-1));
fprintf(fp," rl%d: \n",(i-1));
}
fprintf (fp,"printf( \"Concluido \\n \"); \n");
fprintf(fp,"}\n");
fclose(fp);
}
答案 0 :(得分:1)
我在配备8 GB主内存(2.3 GHz Intel Core i7)的MacBook Pro上做了一些计时。
修改生成器以获取指示程序大小的参数,然后重复运行:
$ for size in 10 100 1000 2000 3000 4000 5000 10000 20000 30000
> do
> ./generator $size
> echo $size
> time make -s source 2>/dev/null
> sleep 1
> done
10
real 0m0.526s
user 0m0.030s
sys 0m0.029s
100
real 0m0.084s
user 0m0.031s
sys 0m0.018s
1000
real 0m0.333s
user 0m0.235s
sys 0m0.044s
2000
real 0m0.392s
user 0m0.318s
sys 0m0.046s
3000
real 0m0.786s
user 0m0.661s
sys 0m0.070s
4000
real 0m0.657s
user 0m0.599s
sys 0m0.053s
5000
real 0m0.978s
user 0m0.893s
sys 0m0.069s
10000
real 0m3.063s
user 0m2.770s
sys 0m0.149s
20000
real 0m8.109s
user 0m7.315s
sys 0m0.274s
30000
real 0m21.410s
user 0m19.553s
sys 0m0.483s
$
显然,在小尺寸的情况下,只需简单地运行编译器(特别是第一次运行!),读取和写入文件等,就会产生开销。重复10,000次到90,000的倍数,我得到了表格中的结果下面。经济放缓是可观的,特别是在20,000到30,000之间。对于任何给定的尺寸,我在时间上也有相当大的变化。并且使代码可配置,然后在遇到问题时以递增方式运行是明智的。
Compared to 10K
Size Time Size Ratio Time Ratio Log Time Ratio
10K 3.7 1.00 1.00 0.000
20K 8.1 2.00 2.19 0.784
30K 25.1 3.00 6.78 1.915
40K 45.2 4.00 12.22 2.503
50K 76.7 5.00 20.73 3.032
60K 110.5 6.00 29.96 3.397
70K 176.0 7.00 47.57 3.862
80K 212.0 8.00 57.30 4.048
90K 292.3 9.00 79.00 4.369
100K 363.3 10.00 98.19 4.587
当然,你的里程会有所不同。
作为参考,我正在使用的GCC是:
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00)
编译命令行是:
/usr/bin/gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition source.c -o source
自制的GCC 4.7.1在10K时为34.6秒,在20K时为150.9秒。