5

これは非常に一般的な問題のようですが、まだ明確な答えが見つかりません。

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 以上のメモリが必要であり、アルゴリズムをさらに最適化する明らかな方法はありません。プログラムが使用します。

答えが明確な「いいえ」である場合でも、それを知っておくとよいでしょう。

ありがとう、ルーカス

4

2 に答える 2

5

一度にすべてのメモリが必要な場合、いいえ、64 ビット カーネルに変更せずにそれを行う方法は実際にはありません (はい、1 つのプロセスでより多くのメモリを割り当てることができます)。

とはいえ、メモリを一度にすべて必要とせず、代わりに高速アクセスだけが必要な場合は、いつでもメモリ ストレージの一部を別のプロセスにオフロードできます。

これは、たとえば、データを他のプロセスに保存することで機能し、必要に応じてプロセスが共有メモリをそのプロセスから独自のメモリ空間に一時的にマップするようにすることができます。メモリ内に保存されますが、メモリ範囲を切り替えるときにオーバーヘッドが発生します。オーバーヘッドが許容できるかどうかは、メモリ アクセス パターンによって異なります。

これは非常に単純なアプローチではありませんが、カーネルを変更して 64 ビットのアドレス空間を提供しないと、少し窮地に立たされているように思えます。

編集: カーネルを再構成することで制限を 2GB より少し上に上げることができるかもしれませんが、それは代わりにハード制限に達することを意味するだけです。また、ルート アクセスが必要になります。

于 2013-02-08T10:56:37.517 に答える
0

答えは明確な「いいえ」です。OS を変更できない場合は、上限を引き上げることはできません。制限はプロセス全体に適用され、明らかに単一の割り当てがプロセスごとの制限を超えることはできません。

カーネルのコンパイルに使用するオプションによっては、制限が 2GB を超える場合もありますが、4GB 未満になることは間違いありません。しかし、カーネルを再コンパイルすることも「OSを変更する」ことと見なされると思います。

この議論を見る

はい、64 ビット OS では、その制限はなくなります。

于 2013-02-08T10:58:25.187 に答える