6

免責事項:私はこの質問の冗長さをお詫びします(私はそれは面白い問題だと思いますが)もっと簡潔に言えばアクセス> 2,3,4GB 64bit(または32bit)Windows上の32bitファイルファイル

私は明らかに/LARGEADDRESSAWAREからVirtualAllocEx AWEに至るまで、64ビット版のWindows 7上の32ビットプロセスでマルチGBのファイルへのアクセスの問題を解決するには無数の方法のような研究の時間を行っています。私は、Windows(CreateFileMapping、MapViewOfFileなど)でマルチビューメモリマップシステムを作成するのはやや快適ですが、この問題に対するより洗練された解決策が存在するという感情から逃れることはできません。また、私はBoostのプロセス間およびiostreamのテンプレートをよく知っていますが、軽量であるように見えますが、Windows API呼び出しのみを利用してシステムを作成するのに似たような努力が必要です(私は、 Windows API呼び出しを使用して半実装されたマップされたアーキテクチャ)。

大きなデータセットを処理しようとしています。このプログラムはあらかじめコンパイルされた32ビットライブラリに依存しているため、システムが64ビットで64ビットOSであっても、プログラム自体も32ビットプロセスで動作しています。私は、これの周りにラッパーライブラリを追加する方法があることを知っていますが、それがより大きいコードベースの一部であることを見ても、それは確かに少しの作業です。私は/LARGEADDRESSAWARE(私のカーネルスペースを減らすことを犠牲にして)を許すようにバイナリヘッダーを設定しました。それは、プロセスごとに約2-3GBのアドレス可能なメモリを与えたり、与えたり(ヒープフラグメンテーションなどに依存して) 。

問題は次のとおりです。データセットは4 + GBであり、ファイル全体に基本的にランダムアクセスが必要なDSPアルゴリズムが実行されています。ファイルから生成されたオブジェクトへのポインタはC#で処理されますが、ファイル自体はC++(これはP/Invoked)でメモリにロードされます(この部分的メモリマップシステムで)。したがって、私はアクセスする必要があるファイルの部分にアクセスするためにウィンドウを調整するだけでは不都合ではないと思います。基本的には、ファイル全体を1つのポインタに抽象化したいので、メソッドから呼び出すことができますファイル内のほぼどこにでもデータにアクセスできます。

ほとんどのメモリマップされたアーキテクチャは、特異プロセスを複数のプロセスに分割することに依存しています。たとえば、3GBのプロセスで6GBのファイルにアクセスします。私はこれらの異なるウィンドウ/プロセス間でデータを引き出し、再結合するためにかなりの量のロジックを追加する必要があります。 VirtualAllocExは明らかに仮想アドレス空間を増やす方法を提供しますが、これが最善の方法であるかどうかはまだ完全にはわかりません。

しかし、このプログラムを64ビットシステム上の単なる64ビットプロセスと同じように「簡単に」機能させたいとします。私はスラッシングを気にしないと仮定し、システム上の大きなファイルを操作できるようにしたいとします.500 MBしか一度に物理RAMにロードされない場合でも同じです。手動でいくらかばかげた手動メモリシステムを書かなくても、この機能を得る方法はありますか?それとも、私はそうやってSOとインターネットを使って見つけたより良い方法がありますか?

これは二次質問に役立ちます。このプロセスで使用される物理RAMの量を制限する方法はありますか?たとえば、プロセスを物理RAMに一度に500 MBしかロードしないように制限したいのであれば(マルチGBファイルをディスク上に保ったままで)

長い質問には申し訳ありませんが、SOとネットで見つかった多くの質問(部分的な回答のみ)が表示されているようです。私は、これが決定的な答え(または少なくともいくつかの長所/短所)を洗い流すことができる領域になることを望んでおり、プロセスで貴重なものをすべて学ぶことができます!

+1

tl;しかし、外部ライブラリを使用したい場合:Qtは(32ビットプラットフォームで)メモリマップされていないが、 "ビッグファイル"クロスプラットフォームを処理できます。しかし、それは同等の性能に達する可能性のある内部IOキャッシュを使用しますか? – leemes

+0

コメントをいただきありがとうございます(たとえtl; drが> _ ;;;)と言っても大したことはありません)!私は内部IOキャッシュを使用する方法を検討しましたが、これはかなりの複雑さを導入するように思えます。これは避けようとしているものです。また、Qtなどのライブラリを追加することを避けたいと思います(Boostはすでに統合されています)。 –

+0

RAMを制限すると、Windowsジョブオブジェクトを使用して物理RAMを制限するワーキングセットを制限できます。残念ながら、これはスワップを最大化するだけだと思う​​ので、あなたが望むものではありません。私はまた、メモリマップされたファイルについて知っていると仮定し、彼らはあなたのニーズに合っていません。 –

答えて

2

ベースアドレスと長さを付けるアクセサクラスを作成できます。エラー状態が発生した場合(範囲外など)、データを返したり例外をスローします(または、エラー状態を通知したい場合)。

ファイルから読み取る必要があるときはいつでも、アクセサオブジェクトはSetFilePointerEx()を使用してからReadFile()を呼び出すことができます。次に、ファイルを読むときに作成したオブジェクトのコンストラクタにアクセサクラスを渡すことができます。次に、オブジェクトはアクセサクラスを使用してファイルからデータを読み取ります。次に、オブジェクトのコンストラクタにデータを返し、オブジェクトのコンストラクタはオブジェクトデータを解析します。

後でラインを64ビットにコンパイルできる場合は、アクセサークラスを変更してメモリから読み込むことができます。プロセスで使用されるRAMの量を制限するよう

は...それはほとんど A)を使用すると、メモリリーク(特に卑猥なもの)と Bを持っていないことを確認することの問題)そうしない破壊したオブジェクトですすぐに必要です。後でそれを必要としても、データは変わらないでしょう...オブジェクトを破壊してください。その後、必要なときに再作成し、ファイルからデータを再読み込みできるようにします。

+1

うーん...これは面白いアイデアのように聞こえる、inetknght!入力いただきありがとうございます!これはファイル全体を読み込むための素晴らしい方法のように聞こえますが、ファイル全体で手動でビューを移動するにはかなりの量のロジックを追加する必要がありますが、拡張可能なアクセサを使用するとこれが今まで64ビットに向けて移動された場合、アクセサクラスだけを変更する必要があることに注意してください。これは、他の方法でファイルを簡単に管理する方法が他にない場合、最終的な実装になる可能性があります。 –

関連する問題