我在我的ubuntu服务器上写了一个最简单的c ++程序:
TEST.CPP:
#include<iostream>
using namespace std;
int a[100*100*100*100*10];
int main() {
unsigned int count = 0;
for (int i = 0; i < 100*100*100*100*10; i++) {
if (i % 10000000 == 0) cout << i << endl;
a[i] = i;
count += i;
}
cout << count << endl;
}
Run Code Online (Sandbox Code Playgroud)
我的g ++编译器是:
root@ubuntu:~# g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
Run Code Online (Sandbox Code Playgroud)
我的服务器的内存是64GB.当我运行时g++ test.cpp,它需要大约1分钟来编译这个c ++文件.而g ++进展的高峰用量是5GB内存....
为什么?
顺便说一下,当我运行这个程序时,它需要大约1分钟才能完成.我想可能是我的记忆有问题.是因为内存太大了?
关于编译器的内存使用的第一个问题是gcc/g ++中的错误.这个问题之前提出过,但我现在似乎无法找到它.我发现这个暗示同样的问题,但我清楚地记得更直接提到这个错误.
无论如何,简而言之,问题如下.首先,假设您的数组已初始化:
int a[100*100*100*100*10] = {10, 20};
Run Code Online (Sandbox Code Playgroud)
这意味着现在整个数组应该实际写在可执行文件中(所以也应该首先驻留在g ++的内存中).这很慢,因为a它非常大(4GB).现在,如果数组没有初始化,就像你的情况一样,它应该转到.bsssection并且整个数组在你运行时被分配/初始化.这意味着它不需要写入文件.
这也意味着g ++可以跳过将整个数组放在内存中.这就是bug的来源.g ++ 确实将该数组保存在内存中,之后才决定不写入它.稍后修复此错误,您可以在另一个答案的报告中看到.
执行过程中的第二个问题很自然.你正在做十亿次的事情.做十亿次的事情需要时间!
一个好的经验法则是"1000万次轻量级计算循环需要一秒钟".因此,您可以想象100次操作将需要100次(大约一分钟).