私は並列化できるC++プログラムを持っています。私はVisual Studio 2010、32ビットコンパイルを使用しています。プログラムの構造は、各some_computations()
ため並列タスクは、pplやOpenMPよりもboost :: threadのほうがパフォーマンスが良い
#define num_iterations 64 //some number
struct result
{
//some stuff
}
result best_result=initial_bad_result;
for(i=0; i<many_times; i++)
{
result *results[num_iterations];
for(j=0; j<num_iterations; j++)
{
some_computations(results+j);
}
// update best_result;
}
に従っている要するに
私はインナーfor
- ループを並列化(いくつかのグローバル変数を読み取る、ないグローバル変数は変更されない)は無関係です。
私の最初の試みは、ブースト::スレッド、結果は良かった
thread_group group;
for(j=0; j<num_iterations; j++)
{
group.create_thread(boost::bind(&some_computation, this, result+j));
}
group.join_all();
とあったが、私はより多くをしようとすることを決めました。
私は結果がboost::thread
のものより悪かった
#pragma omp parallel for
for(j=0; j<num_iterations; j++)
{
some_computations(results+j);
}
をのOpenMPライブラリを試してみました。
は、それから私は、 皆さんライブラリを試してみましたが、parallel_for()
を使用:
Concurrency::parallel_for(0,num_iterations, [=](int j) {
some_computations(results+j);
})
結果は最悪でした。
この現象は非常に驚くべきことです。 OpenMPとpplは並列化用に設計されているので、boost::thread
より良い結果が期待できます。私が間違っている?
boost::thread
はなぜ私に良い結果をもたらしますか?
"より良い"と評価してください。実行時間とスレッド数を比較する'boost :: thread'では64スレッドを作成しています。 OpenPMはワーカースレッドのチームを使用し、その数はデフォルトで仮想CPUの数になります。 PPLはスレッドプールも使用し、ワークバランシングも実装されているため、OpenMPより高いオーバーヘッドを持ちます。 –
OpenMPとpplを使用して、試行ごとに同じ番号(32または64)を使用しました。おそらく指摘したように、スレッド数をコア数と同じに設定するとより良い結果が得られます。私が試してみます。 – 888
質問に答えるのはほとんど不可能です。 'some_computations'は何をしていますか? OpenMPが実際にオーバーヘッドを下げているが、共有キャッシュラインへの書き込みがたくさんあると、結果的にキャッシュ無効化の狂気が実際に遅くなる可能性があります)。 'some_operation'が機能するために、バリアントごとに並列化されたブロックを実行するにはどれくらいの時間がかかりますか? – Grizzly