43

私が疑問に思っていた最近の非常に大量の RAM では、4GB を超えるメモリの単一のチャンクを割り当てることは可能ですか? それとも、小さなチャンクをたくさん割り当てて、それらの間の切り替えを処理する必要がありますか?

どうして???私はいくつかの openstreetmap xml データの処理に取り組んでおり、これらのファイルは巨大です。それらをすべて 1 つのチャンクにロードすることはできないため、現在それらをストリーミングしていますが、malloc または new の上限に興味がありました。

4

10 に答える 10

27

簡単な答え: 可能性は低い

これが機能するためには、絶対に64 ビット プロセッサを使用する必要があります。第 2 に、4G を超える RAM を単一のプロセスに割り当てるには、オペレーティング システムのサポートに依存します。

理論的には可能ですが、メモリ アロケータのドキュメントを読む必要があります。また、メモリの断片化の問題が発生しやすくなります。

Windows のメモリ管理に関する有益な情報があります。

于 2008-10-08T01:22:16.007 に答える
24

物理メモリと仮想メモリのレイアウトに関する入門書

64ビットCPUとO/Sビルド、およびほぼ確実に、ワーキングセットのスラッシングを回避するのに十分なメモリが必要になります。少し背景:

32ビットマシン(概して)には、2 ^ 32(4,294,967,296)の一意の値の1つを格納できるレジスタがあります。これは、32ビットポインタが2 ^ 32の一意のメモリ位置のいずれかをアドレス指定できることを意味します。これは、魔法の4GBの制限が由来する場所です。

SPARCV8やXeonなどの一部の32ビットシステムには、より多くの物理メモリを許可するためのトリックを引き出すMMUがあります。これにより、複数のプロセスが合計で4GBを超えるメモリを使用できるようになりますが、各プロセスは独自の32ビット仮想アドレス空間に制限されます。仮想アドレス空間を調べる単一のプロセスの場合、32ビットポインターでマップできるのは2^32の異なる物理的な場所のみです。

詳細については説明しませんが、このプレゼンテーション(警告:パワーポイント)では、これがどのように機能するかについて説明します。一部のオペレーティングシステムには、MMUを操作し、ユーザーレベルの制御下でさまざまな物理的な場所を仮想アドレス空間にスワップする機能(ここで説明するものなど-上記のFPのおかげで)があります。

オペレーティングシステムとメモリマップドI/Oは仮想アドレス空間の一部を占めるため、その4GBのすべてがプロセスで利用できるとは限りません。例として、Windowsはデフォルトでこのうち2GBを使用しますが、起動時に/3Gスイッチが呼び出された場合は1GBのみを使用するように設定できます。これは、この種の32ビットアーキテクチャ上の単一のプロセスが、メモリ内に4GB未満の連続したデータ構造しか構築できないことを意味します。

つまり、オーバーレイを手動で交換するには、WindowsのPAE機能またはLinuxの同等の機能を明示的に使用する必要があります。これは必ずしも難しいことではありませんが、動作するまでには少し時間がかかります。

または、大量のメモリを搭載した64ビットボックスを入手することもできます。これらの問題は多かれ少なかれ解消されます。64ビットポインタを備えた64ビットアーキテクチャは、少なくとも理論上は、2 ^ 64(18,446,744,073,709,551,616)もの一意のアドレスを持つ連続したデータ構造を構築できます。これにより、より大きな連続したデータ構造を構築および管理できます。

于 2008-10-09T18:28:01.350 に答える
22

メモリマップトファイルの利点は、4Gbよりはるかに大きいファイル(NTFSではほぼ無限大!)を開いて、複数の<4Gbメモリウィンドウをそのファイルに含めることができることです。
ファイルを開いてメモリに読み込むよりもはるかに効率的です。ほとんどのオペレーティングシステムでは、組み込みのページングサポートを使用します。

于 2008-10-08T01:54:15.100 に答える
14

これは、64ビットOS(およびそれだけのメモリを搭載したマシン)では問題になりません。

mallocが対応できない場合、OSはメモリを直接割り当てることができるAPIを確実に提供します。Windowsでは、VirtualAllocAPIを使用できます。

于 2008-10-08T01:34:05.513 に答える
12

使用している C コンパイラとプラットフォーム (もちろん) によって異なりますが、連続して利用可能なメモリの最大のチャンクを割り当てることができない根本的な理由はありません。そしてもちろん、多くの RAM よりもアドレス指定するために 64 ビット システムを使用する必要があるかもしれません...

歴史と詳細についてはMallocを参照してください

alloc.hで HeapMax を呼び出して、利用可能な最大のブロック サイズを取得します。

于 2008-10-08T01:20:08.600 に答える
9

メモリマップトファイルの使用を検討しましたか?非常に大きなファイルをロードしているので、これが最善の方法のように思われます。

于 2008-10-08T01:32:46.720 に答える
6

これは、OSが4GBを超えるメモリのアドレス指定を可能にする仮想アドレス空間を提供するかどうか、およびコンパイラがnew/mallocを使用したメモリの割り当てをサポートするかどうかによって異なります。

32ビットWindowsの場合、ポインターサイズが32ビットであるため、4GBを超える単一チャンクを取得することはできません。したがって、仮想アドレス空間は4GBに制限されます。(物理アドレス拡張を使用して4GBを超えるメモリを取得できますが、そのメモリを4GBの仮想アドレス空間に自分でマップする必要があると思います)

64ビットWindowsの場合、VC ++コンパイラは64ビットポインタをサポートし、仮想アドレス空間の理論上の制限は8TBです。

Linux / gccにも同じことが当てはまると思います。32ビットでは許可されませんが、64ビットでは許可されます。

于 2008-10-08T01:34:10.663 に答える
2

他のみんなが言ったように、64ビットマシンを手に入れるのが道です。ただし、32 ビット マシンの Intel マシンでも、OS と CPU がPAEをサポートしていれば、4 GB を超えるメモリ領域をアドレス指定できます。残念ながら、32 ビットの WinXP ではこれができません (32 ビットの Vista ではできますか?)。Linux ではデフォルトでこれを行うことができますが、ポインタがまだ 32 ビットであるため、mmap() を使用しても 4GB 領域に制限されます。

ただし、すべきことは、オペレーティング システムにメモリ管理を任せることです。その量の RAM を処理できる環境に入り、XML ファイルをデータ構造に読み込み、スペースを割り当てます。次に、XML ファイル自体を操作するのではなく、メモリ内のデータ構造を操作します。

ただし、64 ビット システムでも、OS と MMU が処理するため、少なくともほとんどの場合、プログラムのどの部分が実際に RAM やキャッシュに置かれるか、またはディスクにページングされるかを十分に制御することはできません。これ自体。

于 2009-02-25T21:44:18.367 に答える