2016-03-25 6 views
1

私がやろうとしていること: 3D空間の一部を小さなキューブに離散化しようとしています。 (x、y、zデカルト座標で記述されているような)物理的な空間を3Dグリッドに変換します。この配列の各要素には、doubleタイプの距離値が関連付けられています。グリッドが任意の点を(x、y、z)を用いて配列インデックスにマッピングされる1次元配列として格納されている:大規模な3Dグリッドの非順次アクセスのためのファイルI/Oの効率的な実行

z + y*dim_xy + x*dim_xdim_xyグリッドとdim_xの2Dスライスの大きさのサイズであります単一軸(基本的に3D配列を作成して3Dインデックス値を使用して暗黙のうちに何が起こるかに似ています)。

問題:非常に細かい解像度でかなり大きな3D空間を離散化したいと思います。結果の配列のサイズは約4-6GBです。 new演算子を使用して配列を作成するだけでは、RAMがないためにプログラムがクラッシュします(実際にはシステム全体が5〜6分間クラッシュすることがあります)。

私の提案する解決策、およびそれに間違いがあります:私はバイナリファイルとして配列を格納しようとしました。問題は、シーケンシャルI/O操作は比較的高速ですが、非シーケンシャル操作はかなり時間がかかります。私の場合、グリッドの距離値は、指定された点から幅優先の方法で計算されます。したがって、アルゴリズムは、連続する(x、y、z)点が順次(幾分)処理されるように進んでも、それらがマップする配列インデックスは反復から大幅に変化します。だからこそ私は小さな、一時的な配列を作成し、それを値で埋めることができず、一度にファイルに書き込むことができないのです。

私の主な問題は、ファイルのすべての内容を効率的に書き込むことです。現在、私はseek関数を使用して、ファイル内の特定の場所(つまり、配列内のインデックス)を各繰り返しでジャンプしますが、小さな150MBファイルを書き込むためには5分かかるだけです。ファイルを読むことは大きな問題ではないことに注意してください。ファイルが書き込まれると、それを読む必要は頻繁には発生せず、私は非シーケンシャルアクセスに関連する遅延を受け入れることができます。私は最初の場所でファイルを作成するための速い方法が必要です。

+2

私はファイルをマップするメモリをしようとします。私はあなたが64ビットマシンで作業していると仮定します。 – marom

+0

はい。 Linuxを実行している64ビットマシン。マップされたファイルにはRAMの使用も含まれていませんか?または、メモリがいっぱいになることなく、どれくらいのファイルをロードできるかをOSが安全に処理するかどうか。 – Ali250

+0

OSは、実際にアクセスするRAMを実際に隠しておく必要があります。したがって、セグメンテーションを自分で実装する必要はなく、OSに依存しています。それはうまく動作しませんが、実装するのは簡単ですし、試してみる価値があると思います。 – marom

答えて

0

maromから指摘されているように、メモリマップファイルを使用するべきです。しかし、連続したアクセスを取得する方法は、データをBSPまたはBVH(VPツリーまたはkdツリーのように)として保存することです。もう1つの方法は、ポイントをインデックス付けするためのスペース充填曲線(3d peanoカーブのような)を使用することです。

関連する問題