end do
並列化率とアムダールの法則
87
アムダールの法則
オーバーヘッドを無視した理想的な条件でも
速度向上率の上限は逐次部の割合 (1-p) で決まってしまいます。
時間
逐次
逐次部
∞ 並列
1-p
p
逐次部
1/(1-p)
倍が速度向上率の上限。並列化率
80% ( p = 0.8 )
ならば、1/0.2 =
5倍が上限予定の並列数にふさわしい並列化率以上 である必要があります。
並列化済
並列化率とアムダールの法則 (cont.)
88
アム ダー ル則に よ る 速度向上率
並列数 (N)
1-p = 1/2 1-p = 1/4
1-p = 0 逐次部の割合 (1-p) が1/(並列数)
以下になるよう並列化を進めましょう。
1-p = 1/8
速度向上率
(p:並列化率,N:並列数)
アムダールの法則
(並列化率100%)
(88%)
(75%) (50%)
2.3 2.9
逐次部の割合
4.3
1.8
情報源
89
OpenMP
の仕様情報 http://openmp.org/wp/openmp-specifications/
OpenMP version 3.0に関しては日本語訳あり
「京」のコンパイラ: デフォルトはv3.0準拠(v3.1準拠版も利用可)
gcc 4.4以降:v3.0準拠(gcc 4.7以降v3.1準拠)
intelコンパイラ 11.0以降: v3.0準拠
(12.1以降: v3.1準拠, 13.1(XE 2013 Update 2)以降: v4.0準拠)
チュートリアル資料もあり(上記のページにリンクあり)
https://computing.llnl.gov/tutorials/openMP/
参考資料
Fortran/C利用者向け
「Using OpenMP」,B. Chapman他,The MIT Press
Fortran利用者向け
「OpenMPによる並列プログラミングと数値計算法」,牛島省,丸善
C/C++利用者向け
「C/C++プログラマーのためのOpenMP並列プログラミング」,菅原清文,カットシステム
「OpenMP入門―マルチコアCPU時代の並列プログラミング」,北山洋幸,秀和システム
本セミナーの資料は以下のページからダウンロード可(随時更新):
http://www.hpci-office.jp/pages/seminar_text
Sections 構文
特殊なデータ属性
おまけ
90
Sections 構文
91
※処理量のバラツキが大きいと並列化の効果が出にくくなります。
処理A 処理B 処理C 処理D 処理の流れ
!$omp sections
!$omp section
…処理A…
!$omp section
…処理B…
!$omp section
…処理C…
!$omp section
…処理D…
!$omp end sections
……
処理A 処理B 処理C
処理D
Sections 構文による並列化
Single Program, Multiple Data streams (SPMD)
処理A,B,C,Dの中のループが並列化不能でも、処理A,B,C,D
の間に依存性がなく独立に実行できるならば、並列に実行できます。
FirstPrivate/LastPrivate
共有変数がある場合の注意( Threadprivate 指示文)
特殊なデータ属性
92
Firstprivate 属性
93
プログラム開始
マスタースレッド0
firstprivate( t )
t = 2.0
!$omp parallel do
firstprivate(t)
do i = 1, 4000
if (i.gt.nmax) t = 0.0 V(i) = X(i) + t * Y(i) end do
●Firstprivate指示節
- Private変数と同様の属性を持ちます が、並列実行領域に入る直前の値で、
各スレッドの値が初期化されます
マスタースレッド0
t
0= 2.0
スレッド1
t
1= 2.0
スレッド2
t
2= 2.0
スレッド3
t
3= 2.0
t= 2.0 V X Y shared(V, X, Y)
Lastprivate 属性
94
プログラム開始
マスタースレッド0
lastprivate( i )
!$omp parallel do
lastprivate(i)
do i = 1, 4000
V(i) = X(i) + Y(i) end do
V(i) = X(i) !!! i = 4001
●Lastprivate指示節
-Private変数と同様の属性をもちます が、並列実行領域後に、ループの逐 次的な終値に相当する反復後の値 が代入されます。
V X Y shared(V, X, Y)
マスタースレッド0
i 0
i=1,1000
スレッド1
i 1
i=1001,2000
スレッド2
i 2
i=2001,3000
スレッド3
i 3
i=3001,4000
マスタースレッド0
i=4001 i=4000の反復(逐次実行した場合の
最終に相当する反復)終了後の値
共有変数がある場合の注意
95
COMMON ブロック/ SAVE 変数
Threadprivate 指示文の説明
Threadprivate 指示文
96
以下のとき、
threadprivate指示文を使います。
複数のルーチンからアクセスする変数(commonブロック変数・SAVE変数・module変数)がある。
かつ、その変数が、スレッドごとに異なる値を持つ必要がある。(=shared属性では×)
shared属性
並列実行領域内 のすべてのス
レッドから アクセス可能な
共有データ スレッド0 threadprivate属性
ルーチンA,B の共通データ
ルーチンA 固有なデータ ルーチンB 固有なデータ
スレッド1 threadprivate属性
ルーチンA,Bの共通データ
ルーチンA 固有なデータ ルーチンB 固有なデータ
※ 単にprivate属性とすると、新たにスタック領域に変数・配列が 確保され、複数のルーチンから共有できなくなってしまいます。
Threadprivate 指示文 (cont.)
97
Threadprivate 指示文( common ブロックの例)
common
ブロック内の変数を、スレッド内で複数のsubroutine
からアクセスできる状態のまま、
private
化できます。(スレッドごとに固有の値を持つことができます。) 対象とする
common
ブロックの宣言の直後に記述します。 対象が複数ある場合は、コンマで区切って記述します。
対象が宣言されている全てのプログラム単位(subroutine等)に記述します。
common
ブロックの要素、equivalence
文に現れる変数はthreadprivate
指示文で指定で きません。 指定された
common
ブロックの変数は、並列実行領域の終了後も存在し続け、次の並 列実行領域でアクセスした時にも、データの内容を保持しています。common /com/ A, B
!$omp threadprivate ( /com/ )
Copyin 指示節と copyprivate 指示節
98
Copyin 指示節
並列領域開始時の
threadprivate
変数の初期化
マスタースレッド以外のスレッドの threadprivate 変数は、自動的に初期化さ れません。 Copyin 指示節により、並列実行領域の開始時にマスタースレッド のデータの内容を各スレッドにコピーします。
Copyprivate 指示節
Single
領域(並列領域内の逐次領域)終了後の各スレッドへのデータ転送
Single 構文の終りに Single 実行スレッドの変数を、他のスレッドの対応する
変数へデータをブロードキャスト ( コピー ) します。
!$omp parallel copyin ( /com/ )
!$omp end single copyprivate ( /com/ )
ThreadPrivate 指示文の使用例
99
program routine_A include 'omp_lib.h' common /com/id
!$omp threadprivate ( /com/ )
!$omp parallel
id = omp_get_thread_num() call routine_B
!$omp end parallel
write(*,*)'2nd parallel region'
!$omp parallel call routine_B
!$omp end parallel end
subroutine routine_B common /com/id
!$omp threadprivate ( /com/ ) write(*,*) ’id=‘, id
end
Threadprivate
変数id
は、routine_A, routine_B
の両方からアクセス可。変数
id
の値はスレッドごとに異なる。2つ目の並列実行領域でも各スレッドごと の値が保存される。
並列実行 領域1
並列実行 領域2
2つのルーチンが参照する common ブロックを threadprivate 化する例を示 します。
メインルーチン: 「
routine_A
」 サブルーチン: 「routine_B
」おわり
100
ご清聴ありがとう ございました。