2017-10-17 11 views
0

間のアクションがだから、私は大体このコードを持っている:OpenMP;ネストされたループ

for (int i = 0; i != 10000; ++i) { 
    doAction(i); 
    for (int j = 0; j != 10000; ++j) { 
     ... 
    } 
} 

をそして私は、OpenMPを使用して、それをparallellizeたいです。私が理解しているように、単純なcollapseはこの場合は行いません。別のものを使用しようとした私の試みは果実を抱えていませんでした。これを簡単に並列化する簡単な方法はありますか?doActioni*j回を呼び出す必要がありますか?

+1

どのように置き換えて!= = <? – tim18

+0

@ tim18どうしたらいいですか?私はいつも、彼らがこの文脈で同等であると仮定しました。また、これは質問のネストされたループ部分にどのように関連しているのか分かりません。 – Akiiino

+1

** [A]:** *(cit)を表す 'doAction(i);'関数の呼び出しを考えますか? )** "**ネストループ間のアクション**" *? ** [B]:** 'doAction(i)'コードが** 'i * j' **回と呼ばれるというアイデアはどうでしたか? ** [C]:** '... 'の内部の実際の処理は何ですか? MCVEコードは再現可能な例を表す必要があります。どのようにしてこのようなコードを検証するかは、 "ちょうど" - "' [並行] '**または真** - [[並列]] **コード実行を確認/実際にMCVEコードの一部が欠落していますか? – user3666197

答えて

1

並列化する簡単な方法は、外側ループ用にのみOpenMPを使用することです。

スレッドの同期化のために、すべての方法を並列化するのは良いことではありません。&タスクスケジューリングのオーバーヘッド。大規模なCPUバウンドタスクを分割して並列実行する場合、理想的には、利用可能なすべてのCPUコアを使用しながら、できるだけ大きなものにするのが理想的です。

P.S. OpenMP 4を使用している場合、内部ループの場合、parallelの代わりに#pragma omp simdを使用することができます。外側のループはまだparallelです。このようにして、両方の種類の並列処理を同時に使用します。外側のループはコアを介して並列化され、内側のループはSIMDレーン間で並列化されます。理論的には、それがしばしば最も速い方法で計算されます。

+0

これは良い答えです。それは詳細には入っていませんが、推奨は正しいです。必要に応じて細粒度(内部ループ)で並列化して(十分な別個の作業項目と負荷バランスを提供するため)、できるだけ粗粒度で並列化する(オーバーヘッドを小さくする)。なぜこれがダウン投票されたのか、それは私を困惑させる。 – Zulan