基本的に特定のフォルダーを再帰的にトラバースし、特定のファイルごとにハッシュを計算する、作成した C++ Win32 プログラムを改善する方法を見つけようとしています (MD5 としましょうが、CPU の高価な計算のいずれかである可能性があります)。 . これは I/O バウンドのアプリケーションであるため、ほとんどの場合、プロセスは I/O が終了するのを待っているため、可能な限り多くの CPU を使用していません。スレッド プールを使用してこれを行っても、おそらく (私が間違っているのでしょうか?) 問題は解決されず、すべてのスレッドが I/O の完了を待ってブロックされ、さらにコンテキスト切り替えのオーバーヘッドが発生します。
そのため、重複した読み取りを使用してこれを行うことを検討し始めています。処理する新しいファイルを収集するたびに、ブロックされていない読み取り操作をキューに入れ、1 つのスレッドで完了コールバックを処理し、受信したすべてのチャンクをブロックハッシュします。キュー自体から...理論的には、これによりプロセスがI / O待機でハングするのを回避でき、CPU使用率が増加するため、全体的な速度が向上するはずです。
次の質問があります。
- これにより、アプリケーションの全体的なパフォーマンスが向上すると思いますが、そうですか? そうでない場合、なぜですか?
- I/O 完了イベントは、読み取り操作と同じ順序になるように保護されていますか? つまり、ファイルのオフセット A、B、および C から N バイトを読み取ると、A、B、および C の完了イベントをその順序で取得できますか、それとも予測できない順序で到着する可能性がありますか?
- このメカニズム全体を実装するためのライブラリまたはいくつかのコード サンプルを探しています。IOCP を使用する必要がありますか? 複数のファイル I/O の例が見つからないようです。見つかったものはすべて、1 つのファイルでの読み取りの重複、またはソケットを使用した IOCP の例にすぎません。正しい方向を教えてもらえますか?
- この場合、スレッドプールは役に立たないでしょうか? シングル スレッド アプローチで十分です (たとえば、nginx/libevent アプローチに従う)。
代替ソリューションで何かに答えないでください。私はできる限り最善の方法で OVERLAPPED 操作キューを実装したいだけです。他のものには興味がありません (もちろん、私のシナリオでより効率的であることが証明されていない限り)。
編集:
ソフトウェアの現在の実装は何ですか(もちろん、アプリはこれとまったく同じではありません。アイデアを提供するためだけです):
DWORD crc32( PBYTE data, DWORD size )
{
// compute the crc32 of the data and return it
}
void on_file_callback( const char *pszFileName )
{
PBYTE file_map = ...; // Open the file and memory map it.
if( crc32( file_map, file_size ) == 0xDEADBEEF )
{
printf( "OMG!!!\n" );
}
// Cleanup
}
int main( int argc, char **argv )
{
const char *pszFolder = "c:\\";
// recurse pszFolder and call 'on_file_callback' on every file found
recurse_directory( pszFolder, on_file_callback );
}
ありがとう。