質問の簡略版
私は巨大なマトリックスのようなデータセットを持っています.今のところ、実際にはIEEE-754 doubleとしてディスク上に保存されているマトリックスn
ごとのふりをすることができます. ファイルはギガバイトのオーダーですが、特定の (純粋な) 関数では、ファイルに含まれる要素のオーダーのみが必要です。どの要素が必要になるかは複雑で、単純なスライスのようなものではありません。n
n^2
n
ディスクからのファイルの読み取りと計算を分離するためのオプションは何ですか? 何よりも、ディスク上のデータをメモリ内にあるかのように扱いたいと思います (もちろん、ディスク上のデータが変更されないことを参照透過性のすべての神々に誓う準備ができています)。私はmmapとfriendsを見てきましたが、いくつかの大雑把なテストでは、これらが積極的に十分な空きメモリを確保していないように見えることが示されています。
メモリに保持するファイルの量を細かく制御する必要がある場合、計算を IO に結合する必要がありますか?
ディスク上のデータのより正直な説明
ディスク上のデータは、実際には説明されているほど単純ではありません。真実に近いものは次のとおりです。ファイルは 32 ビット整数で始まりますn
。次に、次のことが正確に発生しますn
: 32 ビット整数m_i
> 0 (1 ≤ i ≤ n) の後に、正確にm_i
IEEE-754 の doubleが続きx_(i,1),…,x_(i, m_i)
ます。(つまり、これはギザギザの 2 次元配列です)。
実際には、 と が必要な理由の決定i
は、j
にx_(i, j)
大きく依存しm_i
ます。mmap の問題に近づくと、これらの多くの s を読み取る必要があるため、m_i
基本的にファイル全体がメモリに読み込まれるようです。IO
問題は、すべてがそこにとどまっているように見えることです。このメモリの解放をよりきめ細かく制御するには、計算を引き込む必要があるのではないかと心配しています。
さらに、「データ構造」は、実際には、ファイル名でパラメータ化された多数のこれらのファイルで構成されています。それらを合わせると、約 1 ギガバイトになります。
より手を振る試みですが、質問のバージョンを理解しやすい可能性があります
n^2
要素で構成されるディスク上にいくつかのデータがあるとします。純粋な Haskell 関数n
は要素の順序を必要としますが、それらのどれが複雑な方法で値に依存します。ファイルが巨大なので、ファイル全体をメモリにロードしたくありません。1 つの解決策は、関数をモナドに投入し、IO
必要に応じて要素を読み取ることですが、私はこれを「あきらめる」と呼んでいます。mmapを使用すると、ディスク上のデータをメモリ内にあるかのように扱うことができ、基本的に OS の仮想メモリ システムの助けを借りて遅延 IO を実行できます。これは良いことですが、データのどの要素が必要かを判断するには大量のファイルにアクセスする必要があるため、mmap はメモリ内にあまりにも多くのファイルを保持しているようです。実際には、データを読み取る必要があることを発見しました。mmap を使用する場合、実際にはファイル全体をメモリにロードする必要があります。
どのようなオプションがありますか?