2

私は現在、コアデータから処理できるプログラムを書いています。そのため、1MBから50GBまでのサイズのファイルを処理しています(将来的にはさらに大きくなる可能性があります)。

メモリ マップ ファイルに関するいくつかのチュートリアルを読み、現在はデータ IO を管理するためにメモリ マップ ファイルを使用しています。つまり、ハード ドライブとの間でデータを読み書きしています。

ここで、データも処理し、データと同じサイズの一時配列が必要です。私の質問は、そのためにメモリマップファイルも使用する必要があるか、またはメモリマップファイルを明示的に定義せずにOSで管理する必要があるかどうかです。問題は次のとおりです。

私は複数のプラットフォームで作業していますが、常に 64 ビット システムを使用しています。理論的には、私のニーズには 64 ビットの仮想アドレス空間で十分です。ただし、Windows では、最大仮想アドレス空間はオペレーティング システムによって制限されているようです。つまり、ユーザーは、ページングが許可されているかどうか、およびどの最大仮想メモリ サイズが許可されているかを設定できます。また、Windows 64の最大仮想メモリは2 ^ 64ではなく、2 ^ 40程度のどこかであるとどこかで読みましたが、それでも私にとっては十分ですが、かなり奇妙な制限のようです。さらに、Windows には、配列の種類に関係なく、最大サイズが 2^31 要素の配列など、いくつかの奇妙な制限があります。これらすべてが Linux でどのように処理されるかはわかりませんが、同様に処理されると思います。おそらく最大許容仮想メモリ=OS-RAM+Swapパーティションサイズ? そのため、システムを使用してRAMサイズを超えるデータを処理したい場合、苦労することがたくさんあります. C ++で64ビット仮想アドレス空間全体を何らかの形で使用できるかどうかさえわかりません。私の短いテストでは、2 ^ 31 要素よりも mot を初期化できないというコンパイラ エラーが発生しましたが、 std::vector などを使用してそれを超えるのは簡単だと思います。

ただし、一方で、メモリマップファイルを使用することにより、すべてのメモリ書き込み操作で常に hdd に書き込まれるデータになります。特に私の物理 RAM より小さいデータの場合、これはかなり大きなボトルネックになるはずです。それとも、RAM を超えているため、必要になるまで書き込みを回避しますか??? メモリ マップド ファイルの利点は、共有メモリを使用したプロセス間通信または一時的な通信で発生します。たとえば、アプリケーションを起動し、何かを書き込み、アプリケーションを終了してから再起動し、必要なデータのみを RAM に効率的に読み取ることができます。データ全体を処理する必要があり、1 つのプロセスで 1 つの実行インスタンスでのみ処理する必要があるため、私の場合は両方の利点が得られません。

注: 私の問題に対する代替ソリューションとしてのストリーミング アプローチは、データへのランダム アクセスに大きく依存しているため、実際には実現可能ではありません。

私が理想的に望んでいるのは、サイズと動作制限セットの制限に関係なくすべてのモデルを処理できる方法ですが、RAM で可能なすべてのものを処理し、物理的な制限を超えた場合にのみ、メモリ マップされたファイルまたはその他のメカニズムを使用する方法です (他にある場合) RAM を超えるデータをページアウトするため、理想的にはオペレーティング システムによって管理されます。

結論として、この一時的な既存データを処理する最善の方法は何ですか? メモリ マップされたファイルやプラットフォームに依存せずに実行できる場合は、コード スニペットまたはこのようなものを提供して、これらの OS の制限を回避するためにどのように機能するかを説明してもらえますか?

4

2 に答える 2