この問題は、本質的に、大きな(> 20GB)データファイルで、ある程度の関数void lineProcess(string, string&, int[])
を計算することを含んでいます。計算は非常に重く、配列パラメータの長さとランダム性にもかなり依存します。いくつかのテストランで平均した時間。最初のパラメータはファイルの1行、2番目は文字列のアドレスで結果を出力することができます。出力の合計サイズは3MBです。入力と出力のk番目のラインが対応する必要はありません。ファイルioとは別に、並列化には完璧に聞こえるので、ここではコードを示します。C++ OpenMPとファイルioによる並列化。パフォーマンスの問題
void foo(const int param[]) {
// process some stuff ...
// create input stream fin, output stream fout from <iostream>
string result;
for (string line; getline(fin, line);) {
#pragma omp parallel task firstPrivate(result)
lineProcess(line, result, param);
fout << result << endl;
}
#pragma omp task wait
fin.close();
fout.close();
}
私はラップトップ上でそれを数回走ってきました(i7のクアッドコア、ハイパースレッディングと8つのプロセスをサポートする必要があります)と大幅にスピードアップを見ているように見えません。シリアルラインプロセス(すなわち、上記のマイナスプラガマディレクティブ)の平均値は、〜2800秒/行で、パラレル〜2000秒/ラインです。私は〜600秒/ラインの数字を目指していました。私は、問題の一部は、タスクとtaskwaitを使用してopenMPの実装かもしれないと思うが、私はファイルの行数がわからないので、簡単な方法で#pragma omp for
を見ることができなかった。
理想的には、私は、1つのバッファがほぼ空/フルになってから、スレッドが読み書きによってディスクを補充/空にするまでスワップするまで、 OpenMPでこれが可能であるかどうか、または読み書きの間でスワップするだけの1つのスレッドでこの単純なバージョンを実行できるかどうかはわかりません。 これが期待どおりに速くない理由やパフォーマンスを向上させる方法についてのアドバイスをいただければ幸いです。明らかに、多くのデータを読み書きするという基本的な限界がありますが、ライン処理にはかなりの時間がかかります。
私はこの質問を非常によく似た方法で見つけましたopenmp - while loop for text file reading and using a pipeline最初の答えは自分のコードとよく似ていますが、2番目のバッファはバッファを使用しているようですが、完全にそれを適応させる方法や価値があるかどうかはわかりません。