3

lseek500MB のファイルを繰り返し転送し、シークごとに小さなチャンク (300 ~ 500 バイト) を読み取る方がread、最初からファイル全体を調べてそのバイトを無視するよりも遅いように見える状況に遭遇しました。したくない。これは、シークを 5 ~ 10 回しか行わない場合でも当てはまるようです (つまり、最終的にファイルの ~1% しか読み取らない場合)。私はこれに少し驚いています.カーネル空間からユーザー空間にデータを実際にコピーしなければならない読み取りよりも、作業が少ないはずのフォワードシークがなぜ遅いのでしょうか?

おそらくローカル ディスク上で、OS がシークするときにドライブにメッセージを送信して、バスを介してデータを送り返すことなくシークすることもでき、さらに節約できます。しかし、私はネットワークマウントにアクセスしています。そこでは、読み取りがシークよりもはるかに遅いと予想されます(実際にネットワークを介してデータを転送するのではなく、Nバイト先に移動するように指示する1つのパケットを送信します)。

ローカル ディスクまたはネットワーク ファイル システムからの読み取りに関係なく、これはどのように発生するのでしょうか? 私の唯一の推測は、私が探している場所ごとに OS が大量のデータをプリフェッチしていることです。これは通常発生するものですか、それとも私のコードのバグを示している可能性がありますか?

4

2 に答える 2

1

差の大きさは、ファイル全体のサイズに対する、読み取られるシークカウント/データの比率の要因になります。

しかし、私はネットワークマウントにアクセスしています。ここでは、読み取りがシークよりもはるかに遅いと予想されます(実際にネットワークを介してデータを転送するのではなく、Nバイト先に移動するように1つのパケットを送信します)。

ネットワークのもう一方の端に回転磁気ドライブがある場合、その影響は依然として存在し、ラウンドトリップ時間によって大幅に悪化する可能性があります。ネットワークプロトコルも役割を果たす可能性があります。ソリッドステートドライブでさえ、いくらかのペナルティがかかる場合があります。

I / Oスケジューラーは、ヘッドの動きを最小限に抑えるために要求を並べ替えることがあります(おそらく、ヘッドのないストレージデバイスの場合でも単純に)。単一の一括リクエストにより、多くのレイヤーで効率が向上する場合があります。ファイルシステムには、ここで多少干渉する機会があります。

ローカルディスクから読み取るかネットワークファイルシステムから読み取るかに関係なく、これはどのように発生する可能性がありますか?

これらのレイヤーの影響をすぐに却下することはできません。ローカルディスクから同じ動作を示す測定値はありますか?あなたとハードウェアの間にそれほど多くのことをしなくても、結論を出すのははるかに簡単です。生のデバイスから始めて、そこから二等分します。

代わりにメモリマップを使用することを検討しましたか?このユースケースに最適です。

于 2012-11-30T20:13:32.083 に答える
1

ファイルシステムによっては、特定のlseek実装によりオーバーヘッドが発生します。たとえば、NFS を使用する場合、 をlseek呼び出してカーネルをロックすると思いますremote_llseek()

于 2012-11-30T20:18:52.117 に答える