2

OpenMP を使用して並列化したシリアル アプリケーションがあります。メインループに次を追加するだけです:

#pragma omp parallel for default(shared)
for (int i = 0; i < numberOfEmitters; ++i)
{
    computeTrajectoryParams* params = new computeTrajectoryParams;
            // defining params...
    outputs[i] = (int*) ComputeTrajectory(params);

    delete params;
}

うまく機能しているようです: 最初は、すべてのワーカー スレッドがループの繰り返しを実行し、すべてが高速になり、CPU 負荷が 100% になります (クアッドコア マシン上)。ただし、しばらくすると、ワーカー スレッドの 1 つが停止し、(ファイルは)_vcomp::PersistentThreadFuncから呼び出された関数にとどまり、次に別のスレッドなど... メイン スレッドだけが動作し続けるまで続きます。vcomp90.dllvctools\openmprt\src\ttpool.cpp

なぜこれが起こるのか誰にも分かりますか?これは、反復の約半分が実行された後に発生し始めます。

4

2 に答える 2

6

これは、スケジューリング方式と各サイクルの計算サイズに依存する場合があります。スケジューリングが静的である場合 - 各スレッドは、実行される前に作業が割り当てられます。各スレッドはインデックスの 1/4 を取得します。一部のスレッドの作業が他のスレッドの作業よりも簡単であるため (または、他のスレッドの負荷が少ないため)、一部のスレッドが他のスレッドよりも先に終了する可能性があります。

動的スケジューリングを試してみて、うまくいくかどうかを確認してください。

于 2009-08-27T10:32:07.570 に答える
2

コードについてのコメント:ComputeTrajectoryの実行時間がミリ秒単位で測定され、反復回数が数回を超える場合は、各反復で割り当て、(現在も)MPに最適化されたメモリアロケータがあることを確認する必要があります。ほとんどのアロケータには、グローバルロック付きのグローバルプールがあります。

割り当てを完全にループから外すことも検討できますが、ここでそれが可能かどうかを知るための十分な情報はありません。

于 2009-08-27T22:08:34.453 に答える