質問をしてから、自分の回答でフォローアップしたいのですが、他の人がどのような回答をしているかも確認したいと思います。
2 つの別々のスレッドから同時に読み取りたい 2 つの大きなファイルがあります。一方のスレッドは fileA を順次読み取り、もう一方のスレッドは fileB を順次読み取ります。スレッド間でロックや通信は行われず、両方とも可能な限り高速に順次読み取りを行い、読み取ったデータをすぐに破棄します。
Windows でのこのセットアップの経験は非常に貧弱です。2 つのスレッドを合わせたスループットは、2 ~ 3 MiB/秒のオーダーです。ドライブは、ほとんどの時間を 2 つのファイル間で前後にシークしているように見えます。おそらく、各シーク後にほとんど読み取っていません。
スレッドの 1 つを無効にして、一時的に 1 つのスレッドのパフォーマンスを調べると、帯域幅が大幅に向上します (このマシンでは ~45 MiB/秒)。したがって、2 スレッドのパフォーマンスが悪いのは、明らかに OS ディスク スケジューラの影響です。
同時スレッド読み取りのパフォーマンスを改善するためにできることはありますか? おそらく、別の API を使用するか、OS ディスク スケジューラのパラメーターを何らかの方法で微調整することによります。
いくつかの詳細:
ファイルは、2 GiB の RAM を搭載したマシン上でそれぞれ 2 GiB のオーダーです。この質問の目的のために、それらはキャッシュされておらず、完全に最適化されていないと考えています。これが事実であることを確認するために、最適化ツールを使用して再起動しました。
これらのファイルを読み取るために、特別な API は使用していません。この動作は、Win32 の CreateFile、C の fopen、C++ の std::ifstream、Java の FileInputStream など、さまざまなボグ標準 API で再現可能です。
各スレッドはループ内でスピンし、read 関数を呼び出します。各反復で API から要求されるバイト数を、1KiB から 128MiB までの値に変更しました。これを変更しても効果がないため、各ディスク シーク後に OS が物理的に読み取っている量は、この数値によって決定されないことは明らかです。これはまさに期待すべきことです。
1 スレッドと 2 スレッドのパフォーマンスの劇的な違いは、Windows 2000、Windows XP (32 ビットおよび 64 ビット)、Windows Server 2003、およびハードウェア RAID5 の有無にかかわらず再現可能です。