为什么g ++编译器使用这么多内存?

时间:2013-11-07 14:41:59

标签: c++

我在我的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;
}

我的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) 

我的服务器内存为64GB。 当我运行g++ test.cpp时,需要大约1分钟来编译这个c ++文件。 g ++进度的峰值使用量为5GB内存....

为什么?

顺便说一句,当我运行这个程序时,它需要大约1分钟才能完成。 我想可能是我的记忆有问题。 是因为记忆力太大了吗?

2 个答案:

答案 0 :(得分:7)

关于编译器内存使用的第一个问题是gcc / g ++中的错误。这个问题之前提出过,但我现在似乎无法找到它。我发现this暗示了同样的问题,但我清楚地记得更直接地提到这个错误。

无论如何,简而言之,问题如下。首先,假设您的数组已初始化:

int a[100*100*100*100*10] = {10, 20};

这意味着现在整个数组应该实际写在可执行文件中(所以也应该首先驻留在g ++的内存中)。这很慢,因为a非常大(4GB)。现在,如果数组没有初始化,就像你的情况一样,它应该转到.bss部分,整个数组在运行时就被分配/初始化了。这意味着它不需要写入文件。

这也意味着g ++可以跳过将整个数组放在内存中。这就是bug的来源.g ++ 将该数组保存在内存中,之后才决定不写入它。如您在another answer的报告中所看到的那样,以后会修复此错误。


执行过程中的第二个问题很自然。你正在做十亿次的事情。做十亿次的事情需要时间!

一个好的经验法则是“1000万次轻量级计算循环需要一秒钟”。因此,您可以想象100次操作将需要100次(大约一分钟)。

答案 1 :(得分:1)

我没有问题 - 它工作正常。

我会猜到它是因为它试图弄清楚是否展开循环,但是因为你没有使用任何优化标志...

附注:你不应该以root身份编译。

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.8.1-10ubuntu8' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --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.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu8)