有时用一个使用大块静态内存的小程序来模拟一些东西很方便.我注意到在改用Fedora 15之后程序需要很长时间才能编译.我们说30秒对0.1秒.更奇怪的是ld(链接器)正在最大化CPU并慢慢开始吃掉所有可用的内存.经过一番摆弄后,我设法找到了这个新问题与我的交换文件大小之间的关联.以下是用于本讨论的示例程序:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define M 1000000
#define GIANT_SIZE (200*M)
size_t g_arr[GIANT_SIZE];
int main( int argc, char **argv){
int i;
for(i = 0; i<10; i++){
printf("This should be zero: %d\n",g_arr[i]);
}
exit(1);
}
Run Code Online (Sandbox Code Playgroud)
该程序有一个巨大的数组,其声明大小约为200*8MB = 1.6GB的静态内存.编译此程序需要花费大量时间:
[me@bleh]$ time gcc HugeTest.c
real 0m12.954s
user 0m6.995s
sys 0m3.890s
[me@bleh]$
Run Code Online (Sandbox Code Playgroud)
13s对于~13行C程序!?那是不对的.键号是静态存储空间的大小.一旦它大于总交换空间,它就会再次开始快速编译.例如,我有5.3GB的交换空间,因此将GIANT_SIZE更改为(1000*M)会给出以下时间:
[me@bleh]$ time gcc HugeTest.c
real 0m0.087s
user 0m0.026s
sys 0m0.027s
Run Code Online (Sandbox Code Playgroud)
啊,那更像是它!为了进一步说服自己(和你自己,如果你在家里尝试这个)交换空间确实是神奇的数字,我尝试将可用的交换空间更改为真正庞大的19GB,并尝试再次编译(1000*M)版本:
[me@bleh]$ ls -ali /extraswap
5986 -rw-r--r-- 1 root root 14680064000 Jul 26 15:01 /extraswap
[me@bleh]$ …Run Code Online (Sandbox Code Playgroud) 给出以下C++代码:
struct vertex_type {
float x, y, z;
//vertex_type() {}
//vertex_type(float x, float y, float z) : x(x), y(y), z(z) {}
};
typedef struct {
vertex_type vertex[10000];
} obj_type;
obj_type cube = {
{
{-1, -1, -1},
{1, -1, -1},
{-1, 1, -1},
{1, 1, -1},
{-1, -1, 1},
{1, -1, 1},
{-1, 1, 1},
{1, 1, 1}
}
};
int main() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我将(当前已注释掉的)构造函数添加到vertex_type结构中时,编译时间突然增加10-15秒.难倒,我看了gcc(使用-S)生成的程序集,发现代码大小比以前大几百倍.
...
movl $0x3f800000, cube+84(%rip)
movl $0x3f800000, cube+88(%rip)
movl $0x3f800000, …Run Code Online (Sandbox Code Playgroud) 如果有人能告诉我为什么编译这个程序,我真的很感激:
double data[123456789];
int main() {}
Run Code Online (Sandbox Code Playgroud)
比这个编译要长10倍:
int main() {
double* data=new double[123456789];
}
Run Code Online (Sandbox Code Playgroud)
两者都编译时:
$ g++ -O0
Run Code Online (Sandbox Code Playgroud)
并且可执行文件的大小几乎相同.
我在Ubuntu 10.04上使用gcc 4.4.3.
谢谢.