ワーカースレッドは、一瞬の後に自分の仕事を停止します
-
20-09-2019 - |
質問
私は、私は、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;
}
これはうまく動作するようです:最初に、私のすべてのワーカースレッドは、ループの反復を実行し、すべてが高速で行く、と私は(クアッドコアマシン上で)100%のCPU負荷を持っています。唯一のメインスレッドが動作したままになるまでしかし、...など、一瞬の後、ワーカースレッドの1が停止し、_vcomp::PersistentThreadFunc
からvcomp90.dll
と呼ばれる関数内に留まります(ファイルがvctools\openmprt\src\ttpool.cpp
である)、その後、別ます。
誰もが、これはなぜ起こるかのアイデアを持っていますか?これは、繰り返しの約半数が実行された後に起こることを開始します。
解決
これは、スケジューリング方式、および各サイクルでの演算サイズに依存する場合があります。 スケジューリングは静的である場合 - それが実行される前に、各スレッドは作業が割り当てられています。各スレッドは、インデックスの1/4を取得します。自分の仕事は、他のスレッド(または多分彼らはちょうどより少ない他のものがロードされている)のそれよりも簡単であるため、いくつかのスレッドが他の人の前に終了している可能性があります。
動的スケジューリングで動作するようにしてみて、それが良い作品かどうかを確認します。
他のヒント
あなたのコードのリトルコメント:あなたのComputeTrajectoryの実行時間をミリ秒で測定され、あなたは数回の反復以上を持っている場合は、あなたが本当に(あなたが各反復に割り当てるので、あなたは、MPが最適化されたメモリアロケータを持っていることを確認し、必要があります今も)ほとんどのアロケータは、グローバルロックを持つグローバルプールを持っています。
あなたはまた、完全に蚊帳の外に割り当てを取得に見ることができるが、それはここに可能であるかどうかを知るための十分な情報がありません。