2012-05-13 35 views
0

私のプログラムは以下のようにそれをインターリーブ、ファイルを読み込み、Linuxアプリケーションのために読み取ります高速化は

enter image description here

読み込まれるファイルが大きいです。それは4つの部分に分割され、多くのブロックに分割されます。私のプログラムはまずパート1のブロック1を読み込み、パート2のブロック1にジャンプします。次に、パート1のブロック2に戻ります。

テストでパフォーマンスが低下します。私はその理由は、カーネルのページキャッシュ機能がこのような状況では効率的に機能しないと考えているからです。しかし、ファイルが大きすぎてmmap()になり、ファイルがNFSに置かれています。

どのようにこのような状況で読書をスピードアップできますか?コメントや提案は大歓迎です。

+0

あなたが行ったようにファイルを飛び越えることは、パフォーマンスを圧迫することです。とにかくアルゴリズムをリニアに読み直すことができますか?また、あなたが現在行っているようにNFS上のコンテンツを引き出すのではなく、ファイルを保持するボックスと同じ場所にコードを置くことができますか? – chrisaycock

+0

あなたはファイルをmmapできないと言っていますが、すべてのデータをメモリに読み込むことはできますか? –

+0

@chrisaycock残念ながら、私は標準に従って上記のようにファイルを読み込んで送信する必要があります。多くのテストの結果、NFSはボトルネックではないことがわかりました。 – LiJunjie

答えて

1

posix_fadvise()を使用して、システムヒントを使用することができます。先読みを無効にするにはPOSIX_FADV_RANDOMを使用し、POSIX_FADV_WILLNEEDを使用して、必要になる前に次のブロックをページキャッシュに読み込もうとします(これが予測できる場合)。 また、あなたは、システムが根底にあるキャッシュページを解放持つようにブロックを読み終わったら、これは、ブロックの各ペアについて

+0

私はそれを採用しなかったけれども、あなたの提案をありがとう。 'posix_fadvise()'を使うのは複雑で、私は最初に線形に読むことができるようにファイルインターリーブを生成しました。 – LiJunjie

0

必要ではないかもしれないが、プロセス内の両方が最初に読んで、POSIX_FADV_DONTNEEDを使用しよう、と可能性2番目のスタックをスタックにプッシュします。ファイルの終わりに来たら、スタックの一番下から値をシフトし始め、一つずつそれを処理します。

0

読み込みを線形チャンクに分割することができます。例えば、あなたのコードは次のように見える場合:これに

int index = 0; 
for (int block=0; block<n_blocks; ++block) { 
    for (int part=0; part<n_parts; ++part) { 
    seek(file,part*n_blocks+block); 
    data[part] = readChar(file); 
    } 
    send(data); 
} 

変更は:

for (int chunk=0; chunk<n_chunks; ++chunk) { 
    for (int part=0; part<n_parts; ++part) { 
    seek(file,part*n_blocks+chunk*n_blocks_per_chunk); 
    for (int block=0; block<n_blocks_per_chunk; ++block) { 
     data[block*n_parts+part] = readChar(file); 
    } 
    } 
    send(data); 
} 

は、その後、あなたのキャッシュのn_blocks_per_chunkを最適化します。