簡単な応答として、単一のファイルを処理して別のファイルに書き込む場合、openMP を使用すると、IO 部分にあまり注意を払うことなく、プログラムのシーケンシャル バージョンをマルチスレッド バージョンに簡単に変換できます。それ自体は並列化できます。
これは、通常、メイン スレッドが IO を処理するためです。データのチャンクが大きすぎて一度に読み取ることができず、計算アルゴリズムが小さなチャンクを処理できないためにこれを達成できない場合は、openMP API を使用して各スレッドの IO を同期できます。これは、新しいデータの読み取りまたは書き込みができるように、アプリケーション全体が停止または他のスレッドの計算が終了するまで待機するという意味ではなく、読み取りおよび書き込み部分のみをアトミックに実行する必要があることを意味します。
たとえば、順次申請の流れが次のようになっているとします。
1) Read
2) compute
3) Write
本当に並列化でき、データの各チャンクを各スレッド内から読み取る必要がある場合、各スレッドは次の設計に従うことができます。
1) Synchronized read of chunk from input (only one thread at the time could execute this section)
2) Compute chunk of data (done in parallel)
3) Synchronized write of computed chunk to output (only one thread at the time could execute this section)
チャンクを読み取ったのと同じ順序で書き込む必要がある場合は、最初にバッファリングするか、正しい位置に fseek などの別の戦略を採用する必要がありますが、それは出力ファイルのサイズが最初からわかっているかどうかによって異なります。 ..
デフォルトは計算アルゴリズムに最適ではない可能性があるため、openMP スケジューリング戦略には特に注意してください。また、読み取った入力ファイルのオフセットなど、スレッド間で結果を共有する必要がある場合は、openMP API が提供するリダクション操作を使用できます。これは、コードの一部をすべてのスレッド間でアトミックに実行するよりもはるかに効率的です。 、グローバル変数を更新するためだけに、openMP は書き込みが安全な時期を認識しています。
編集:
「読み取り、処理、書き込み」操作に関しては、すべてのワーカー間で読み取りと書き込みをアトミックに保つ限り、問題が発生する理由は考えられません。読み取られたデータが内部バッファーに格納されていて、すべてのワーカーがアトミックにアクセスしている場合でも、そのデータはまったく同じ順序で取得されます。そのチャンクを出力ファイルに保存するときにのみ特別な注意を払う必要があります。これは、各ワーカーが属性付きチャンクの処理を終了する順序がわからないためです。まだ処理中です。各ワーカーが各チャンクの位置を追跡する必要があるだけで、最後に出力ファイルに保存されてから一連の完成したチャンクが得られるまで、保存する必要があるチャンクへのポインターのリストを保持できます。
内部バッファ自体が心配な場合 (そして、あなたが話しているライブラリがわからないので、間違っている可能性があることに注意してください)、データの一部のチャンクに対してリクエストを行う場合、その内部バッファのみを変更する必要があります。あなたがそのデータを要求した後、データがあなたに返される前; そして、その要求をアトミックに行ったので (つまり、他のすべてのワーカーは順番に並んでいる必要があります)、次のワーカーが自分のデータを要求したときに、その内部バッファーは、最後のワーカーがそのデータを受け取ったときと同じ状態になっている必要があります。かたまり。ライブラリが特に、チャンク自体のコピーではなく、内部バッファーの位置へのポインターを返すと述べている場合でも、アトミック読み取り操作全体のロックを解放する前に、ワーカーのメモリにコピーを作成できます。
私が提案したパターンが正しく守られていれば、アルゴリズムの同じ逐次バージョンでは見つからない問題が見つかるとは思いません。