これは非常に一般的な問題のようですが、まだ明確な答えが見つかりません。
Linux を実行し、16 GB の RAM と 16 コア (64 ビット) CPU を備えたサーバーにアクセスできます (/proc/cpuinfo は「Intel(R) Xeon(R) CPU E5520 @ 2.27GHz」を提供します)。ただし、カーネルは 32 ビットです (uname -m は i686 を提供します)。もちろん、私はルート アクセス権を持っていないので、それを変更することはできません。
私が書いた C++ プログラムを実行していますが、これはメモリを大量に消費する計算を行うため、大きなヒープが必要です。ただし、2GB を超える割り当てを試みると、ulimit は「無制限」を返しますが、badalloc が返されます。簡単にするために、私のプログラムがこれであるとしましょう:
#include <iostream>
#include <vector>
int main() {
int i = 0;
std::vector<std::vector<int> > vv;
for (;;) {
++i;
vv.resize(vv.size() + 1);
std::vector<int>* v = &(vv.at(vv.size() - 1));
v->resize(1024 * 1024 * 128);
std::cout << i * 512 << " MB.\n";
}
return 0;
}
g++ (フラグなし) でコンパイルした後、出力は次のようになります。
512 MB.
1024 MB.
1536 MB.
2048 MB.
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted
私が理解している限り、これは 32 ビット システムの制限です。明らかに、32 ビット ポインターは 2^32 個の異なるアドレスを保持できるためです (同じサーバーで同じプログラムをコンパイルした場合、そのサーバーが64 ビット カーネルでは、プログラムは 2GB 以上を割り当てることができますか?)
これは、割り当てられたメモリが連続しているかどうかの問題ではありません。サンプル プログラムで薄くスライスすると、同じ問題が発生します。実際のプログラムでは、メモリの大きなブロックはなく、小さなブロックがたくさんあります。
だから私の質問は:私にできることはありますか?OS を変更することはできませんが、もちろん、ソース コードを変更したり、別のコンパイラ オプションを使用したりすることはできますが、一度に 2GB 以上のメモリが必要であり、アルゴリズムをさらに最適化する明らかな方法はありません。プログラムが使用します。
答えが明確な「いいえ」である場合でも、それを知っておくとよいでしょう。
ありがとう、ルーカス