2010-11-23 17 views
-2
#pragma omp parallel for default(none) shared(x) private (y, z, f) ordered 
for (i = 0; i < 512; i++) { 
    #pragma omp ordered 
    for (y = 0; y < 512; y++) { 
     for (z = 0, f = 0; z < 512; z++) { 
      x[f++] = z + i + y; 
     } 
    } 
} 

上記のコードは、非SMP実行よりもデュアルコアで約20%遅く実行されます( )。 「#pragma omp ordered」がなければ、非SMPより約50%高速です。Ordered並列コードはシングルスレッドよりも低速で実行されます。解決策はありますか?

x [f ++]シーケンスは、同様に後で再利用されるため、順序付けられた形式のままでなければならないとみなされます。

シングルスレッドよりも速い順序コードを使用できますか?それを達成する別の方法がありますか?

システムはwin32/mingw-w64です。

+1

このコードは意味を持ちません。以前の値を考慮せずにxを上書きします。最も内側のループだけが実際に書き込みます。 iとzを512に設定して内部ループを実行すると、コードは25万倍高速に実行されます。 –

答えて

2

fの使用を除いて、1つの反復の結果は前のものに依存しないので、実際には順序付けされていません。

,yおよびzからfを派生できますか?あなたができるように見えます。例:

f = z + y * 512 + i * 512 * 512 + initial_f; 

ここでコードは順序付けされておらず、並列化のメリットが得られます。

+0

私はあなたがその解決方法に来ることができません、 'f'は常に内側ループの開始時に' 0'に設定されます。 –

+0

おっと - 十分に詳しく読まなかった。彼のコードは意味をなさない。 –

-1

明らかに、内部ループの共有ベクターxに依存しています。したがって、その変数への各アクセスはOMPによってmutexされなければなりません。 "パラレル"バージョンがシーケンシャルバージョンよりも遅いのも不思議ではありません。

あなたのコードは私にとって全く意味をなさないので、何を変えるべきかアドバイスするのは難しいです。その結果はどうなると思いますか? orderedの場合、xの最終結果は、iの値のバージョンが511に設定されます。そうしないと、個々のエントリごとにスレッドが勝った人がいます。

あなたのfさんと交流しましょう。評価されたとき、それはwと同じ値を持っていますか?これは単にノイズを追加して理解しにくくすることです。

0

メモリシステムが飽和しているため、シングルスレッド/コアコードはマルチスレッド/コアより高速です。何が起こるかは、単一のスレッドによって必要とされるメモリ作業が、メモリシステムが提供できるものに近いか、またはその限界にあることである。同じ作業を必要とする別のスレッド/コアを追加して、両方のスレッド/コアがメモリシステムが提供できるものを共有する必要がある場合は、待機状態になり、実行が遅くなります。

メモリ作業のプロファイリングと最適化の後、マルチスレッドコードが高速です。最適化では、データを非共有メモリ(L1 & L2キャッシュ)に移動し、共有メモリへのアクセスを最小限に抑える必要があります(L3 & RAM)。

最適化ソリューションは、当面のアプリケーション固有のものです。それは自明ではない(サードパーティのSWベンダーの中には、彼らの製品でそれがケーキだと言うことを試みるだろうが)。一度やってしまえば、少なくともどのような構造を避けるべきか、どのような手法が有用であるかを学ぶことになります。

関連する問題