0

大きな 'int' 配列 (サイズ 10^9 ) を割り当てる必要があるコードを書いていました。そうしている間、私はいくつかの問題に直面し、Google で何かを読んだ後、私は自分自身の結論に従うようになりました. 誰かがこれを見て、私が何か欠けているかどうかを指摘し、これを行うためのより良い方法を提案できますか.

(マシン構成: VM マシン Ubuntu 10.4、gcc 4.4.3、32 ビット、2 GB RAM (私のホスト マシンは 6 ギガバイト)

1. 配列をサイズ 1*10^9 の「unsigned long int」として宣言しました。コードをコンパイルすると、「配列サイズが長すぎます」というエラーが発生しました。だから私はこれを検索し、物理メモリが2 GBだったので、スタックにそれほど多くのメモリを割り当てることができないことに最終的に気付きました。私はすでに配列をグローバル変数として割り当てようとしましたが、スタックではなくグローバル領域にそれらを割り当てますが、同じエラーです

  1. そのため、「malloc」を使用して同じ量のメモリを割り当てようとしましたが、今回も「malloc」で「Cannot alllocate memory」というエラーが発生しました

したがって、これをすべて行った後、私の理解/問題は次のとおりです。

3-物理メモリが2Gbしかないため、スタックまたはヒープにそれほど多くのメモリを割り当てることができません(これが実際の問題であるか、他の要因もこのメモリ割り当てを支配しています??)

4- 2Gig マシンでサイズ 10^9 のメモリを割り当てることができる回避策はありますか (これほど大きな配列またはメモリ領域を割り当てることは、良いアルゴリズム設計でも効率的でもないことはわかっていますが、限界を知りたいだけです。)

5-これだけのメモリを割り当てるためのより良い解決策(つまり、1つの大きなチャンクではなく2つの小さな配列/ヒープメモリを使用する必要があるということです) (注:ポイント4と5は2つの異なるアプローチであり、両方のアプローチの提案をいただければ幸いです)

どうもありがとう PS 私が初心者なら許してください..

4

1 に答える 1

3

32 ビット プロセスをコンパイルしていて、巨大なデータ ブロックに十分な物理アドレス空間がありません。32 ビットのポインターは、2^32 の異なる値、つまり 4GB を保持できます。メモリを参照する方法がないため、それ以上割り当てることはできません。プロセスにマップされるメモリの各バイトには、一意のアドレスが必要です。

したがって、データを 4 GB のアドレス空間に収めることはできません。アレイが 4GB 未満の場合でも、単一の連続したメモリ ブロックを割り当てる際に問題が発生する可能性があります。

64 ビット プロセスを使用することもできますが、アレイがスワップされたときにディスクのスラッシングを回避するために、十分な物理メモリがあることを確認する必要があります。または、そのような巨大なメモリ ブロックを必要としない別のアルゴリズムを見つけることもできます。

于 2012-04-20T17:31:46.210 に答える