TM

OpenMP
プログラミング・ワークショップ
平成13年3月22日
日本SGI株式会社
製品技術本部
スケーラブルシステムテクノロジーセンター
芦澤 芳夫

TM

OpenMPの概要
OpenMPの概要

共有メモリ型並列化API
共有メモリ型並列化APIの必要性
APIの必要性TM• 標準化による利点– 利用者• 異機種間の移行が容易– ソフトウェアベンダ
• 移植性、保守性、品質向上• APIの標準化が遅れた理由
APIの標準化が遅れた理由– 各ベンダが独自のAPI各ベンダが独自のAPIを提案
APIを提案• 同様の機能を各社各様の指示行で実現– X3H5/PCFの失敗
X3H5/PCFの失敗• 各社の意向の相違、各社の意向の相違、仕様自身の機能不足– MPIという移植性の高い
MPIという移植性の高いAPIという移植性の高いAPIの存在
APIの存在2001/03/22

3

OpenMPの利点
OpenMPの利点

TM

• 移植性
– 共有メモリ型プログラミングの標準API
共有メモリ型プログラミングの標準API• 幅広い並列構造の記述– コンパイラ指示行によるループレベルの並列化– 関数呼び出しを含む高いレベルの並列化– スレッド生成によるMPI
スレッド生成によるMPIと同様の並列構造の記述
MPIと同様の並列構造の記述• 共有メモリ型プログラミングの活用– 段階的な並列化が可能– 既存資産への適用が容易

2001/03/22

4

OpenMPの特徴
OpenMPの特徴

TM• 移植性の高いAPI
移植性の高いAPI– Fortran77(1.1), C/C++(1.0)
C/C++(1.0)に関する仕様に関する仕様– Fortran90対応、機能追加
Fortran90対応、機能追加 （2.0）
2.0）

• 機能
– コンパイラ指示行による並列化構造の記述– 細粒度（ループレベル）– 粗粒度（関数呼び出しを含む）– スレッド、プロセスの制御

2001/03/22

5

OpenMPの仕様
OpenMPの仕様

TM• OpenMPの仕様のリリース
OpenMPの仕様のリリース– Fortran– C/C++– Fortran– Fortran

version 1.0
version 1.0
version 1.1
version 2.0

1997年
1997年10月
10月
1998年
1998年10月
10月
1999年
1999年11月
11月
2000年
2000年11月
11月• 仕様、公開情報– http://www.OpenMP
http://www.OpenMP.org/
OpenMP.org/– 仕様書、解釈– チュートリアル、プログラミング例– ワークショップ

2001/03/22

6

ARBメンバー
ARBメンバー

TM• Architecture Review Board メンバー
– 米国エネルギー省 ASCIプログラム
ASCIプログラム– Compaq– 富士通 2000年
2000年10月
10月 米国外のベンダとして初
– HP
– IBM
– Intel– KAI
2000年
Intelの子会社
2000年4月
Intelの子会社
– SGI
– Sun

2001/03/22

7

OpenMPの構成要素
OpenMPの構成要素

TM• 並列化指示行（!$pragma）
並列化指示行（!$omp!$omp,
omp, ##pragma
pragma）• 並列化構造の記述• ワークシェアリング
• データのスコープ• 同期• 実行時ライブラリ• 実行制御ライブラリ（スレッド数、ダイナミックスレッドなど）• 基本的な関数（スレッド数、スレッド番号の取得など）• 環境変数• 最大スレッド数• ダイナミックスレッドなど

2001/03/22

8

プログラムの並列化

TM• プログラムの経過時間の短縮
cpu時間

1 processor

通信のオーバーヘッド

4 processors
経過時間

finish• オーバーヘッド:
オーバーヘッド:– 通信– 同期– アルゴリズムの変更に伴う処理の増加– コードのなかの並列化できない部分– 全体のcpu 時間は増加

8 proc
s
4 p
roc
s
2
pr
oc
s

start

p

c
ro

e

o
s
s

r

1

経過時間の短縮

経過時間

2001/03/22

9

アムダールの法則

TM• 並列化されない部分の比率
並列化されない部分の比率(1(1(1-F)によって並列実行によるスピー
F)によって並列実行によるスピー
ドアップ(
ドアップ(S)の上限が決まる
S)の上限が決まる•S•P•F

スピードアップ
プロセッサ数並列化部分の比率

1

並列化されな
い部分の比率

スピードアップ(S) ＝F
並列化された部分
だけがP倍速くなる＋ (1 - F)
P• プログラミングモデル（MPI/
プログラミングモデル（MPI/OpenMPMPI/OpenMPなど）に依存しない
OpenMPなど）に依存しない• 考慮していないこと– 通信同期のオーバーヘッド– 並列化の粒度（細粒度、粗粒度）
2001/03/22

10

アムダールの法則

TM

スケーラビリティを期待するのであれば並列実行領域の比率をできるだけ上げる

10

スピードアップ(S)8
並列化部分の比率が５０％程度ではスケーラビリテ
ィは期待できない

6

P=8
P=4

4

P=2
2
0
0.0

0.2

0.4

0.6

0.8

1.0

並列化部分の比率(F)2001/03/22

11

OpenMPの実行モデル（
OpenMPの実行モデル（SGIの実行モデル（SGI）
SGI）

TM

• 並列実行のfork
並列実行のforkfork-joinモデル
joinモデルマスター(me=0)
ジョイン
同期の
時間が
必要

スレーブ
(me=1,P-1)

最初に並列実行領域に入る時にスレーブが生成される!$omp parallel!$omp end parallel

この間スレーブはス
ピンルーチンでCPUを消費し、並列化時のCPU時間としてカウントされる!$omp parallel
ジョイン
同期の
時間が
必要

ダイナミック
スレッドは実装に依存

ダイナミックスレッドの機能により、スレーブの数は実行時にシステムの状況に応じて変化する!$omp end parallel
2001/03/22

12関数レベルの並列構造の記述
Orphaned指示行
Orphaned指示行

TM• 粗粒度の並列処理構造を実現– 並列実行領域から呼び出される関数内で使用されるOpenMP指示行の総称
OpenMP指示行の総称– 異なったコンパイルユニット間での同期処理が可能– X3H5/PCFでは考慮されていなかった構造
X3H5/PCFでは考慮されていなかった構造
Orphaned
指示行

sum=0.
!$omp parallel
call sub(sum)!$omp end parallel
print *,sum

subroutine sub(sum)!$omp critical
並列処理の記述
sum=sum+1.
!$omp end critical
returnend

2001/03/22

13

ダイナミックスレッド

TM

• 機能
– 並列化プログラムを実際の運用環境で効率的に実行するための機能– CPU数以上のプロセスの同時実行を回避
CPU数以上のプロセスの同時実行を回避• システムのスループットの向上• システム利用効率の向上• OpenMPの実行時ライブラリ
OpenMPの実行時ライブラリ– 各並列実行領域の開始時点で、スレッド数を調整し、その並列実行領域が終了するまでは同じ値が保証される– SGIの実装
SGIの実装• デフォルトでダイナミックスレッドが有効

2001/03/22

14

TM

OpenMPプログラミング
OpenMPプログラミング

自動並列化とOpenMPTM• コンパイラがコードをうまく並列化してくれれば．．．
ユーザはOpenMP
ユーザはOpenMPを知らなくてもOpenMPを知らなくてもOKを知らなくてもOK

しかし、．．．

• 実用コードではコンパイラだけではうまく並列化されない場合がある
自動並列化とOpenMP
OpenMP指示行との併用も可能
自動並列化とOpenMP
指示行との併用も可能
例えば、

do

i = 1, nA(IB(i)) = ... ...
enddo
全てのイタレーションで IB(i) の値が異なっていれば並列化可能
コンパイラは確認できない
ユーザが確認できれば並列化
指示行を指定2001/03/22

16

ループを並列化する指示行（１）TM

指示行に続くループを各スレッドに分散して並列処理– Fortran• 大文字、小文字の区別なし• １行に収まらない場合は、!$omp&
１行に収まらない場合は、を指定して次行に続ける（固定形式）
２、．．．) SHARED(変数s１、!$OMP PARALLEL DO PRIVATE(変数p１、
変数 １、変数１、変数p２、．．．
変数 ２、．．．
変数 １、変数１、変数s２、．．．
変数 ２、．．．)
DO I=i1,i2,i3
並列実行領域
block
ENDDO

同じ意味
!$OMP PARALLEL DO!$OMP& PRIVATE(変数p１、
変数 １、変数１、変数p２、．．．
変数 ２、．．．)
２、．．． SHARED(変数s１、
変数 １、変数１、変数s２、．．．
変数 ２、．．．)
DO I=i1,i2,i3
block
並列実行領域
ENDDO
2001/03/22

17

ループを並列化する指示行（２）TM

指示行に続くループを各スレッドに分散して並列処理– C/C++• 大文字と小文字の区別があり• １行に収まらない場合は、＼（バックスラッシュ）で改行をエスケープ#pragma omp parallel for private(変数p１、．．．
変数 １、．．．) shared(変数s１、．．．
変数 １、．．．)]
for (i=0;i<n;i++) {並列実行領域...
}
同じ意味#pragma omp parallel for ＼private(変数p１、．．．
変数 １、．．．) shared(変数s１、．．．
変数 １、．．．)]
for (i=0;i<n;i++) {並列実行領域...
}
2001/03/22

18

private変数とshared変数

TM

並列実行領域内の変数の属性を定義::
並列実行領域内の変数の属性を定義• private– スレッド毎にプライベート– 新たに記憶領域が確保される– 並列実行領域内だけでアクセス可能– 初期値は未定義• shared– 共有変数– すべてのスレッドから同じアドレスで参照可能

2001/03/22

19

Doループ並列化の記述
Doループ並列化の記述

TM

インデックス
変数はデフォ
ルトでprivate
省略可能!$omp parallel do private(i, tmp) shared(max, A, B, C, n)
do i = 1, n
tmp = i + max
デフォルト
C(i) = A(i) * B(i) + tmp
はsharedで
enddo
省略可能
print *, ‘C(n) = ‘, C(n)... ...

2001/03/22

20

縮約（リダクション）演算の記述

TM

演算の種類(+,-,*,MAX,MINなど）
によりローカル変数に初期値が与えられる

sum=0.
!$omp parallel do private(i) shared(A,n)!$omp&
reduction(+:sum)do i = 1, n
sum = sum + A(i)
並列実行ループ
enddo
各スレッドがローカ
print *, ‘sum = ‘, sum
ルsumを計算し、最... ...
後に加え合わせる

2001/03/22

21

クリティカルセクションの記述
sum=0.
!$omp parallel private(i,localsum)!$omp&
shared(A,n,sum)
各スレッドのlocalsum=0.
localsumを初期化!$omp dodo i = 1, n
並列実行ループ
localsum = localsum + A(i)enddo!$omp criticalsum = sum + localsum
各スレッドが!$omp end critical
排他的に実
end parallel
行することでsumを計算print *, ‘sum = ‘, sum... ...

TM

各スレッド
が自分の担
当分につい
てlocalsum
を計算
並列実行
領域

（注）!$omp parallel doは直後のループだけを並列処理する簡略な記述
2001/03/22

22

TM

SGI Originでのコンパイルと実行
Originでのコンパイルと実行

SGI Originでのコンパイル方法
Originでのコンパイル方法

TM• コンパイラはOpenMP
コンパイラはOpenMP 1.1に準拠
1.1に準拠• コンパイル方法– 自動並列化(
自動並列化(自動＋指示行を有効にする）% f90 –apo prog.f% cc –apo prog.c– 指示行だけを有効にする% f90 –mp prog.f% cc –mp prog.c• 分割コンパイル% f90 –c –mp prog1.f% f90 –c –apo prog2.f% f90 –mp prog1.o prog2.o

並列化制御のライブラリをリンクするため-mpが必要
コンパイル時の-mpと混同しないこと

2001/03/22

24

OpenMPプログラムの実行•

環境変数に実行プロセッサ数を指定% setenv OMP_NUM_THREADS 4% a.out•

実行プロセッサ数のデフォルト

TM

８プロセッサ

2001/03/22

25

プログラム実行時の注意点

TM

必要以上にCPU
CPU数を使用しない• 必要以上にCPU数を使用しない– オーバヘッドによるCPU
オーバヘッドによるCPU時間の増加
CPU時間の増加• 使用するプロセッサ数– 必ずしも指定した値で実行されるとは限らない– デフォルトでダイナミックスレッドは有効（
デフォルトでダイナミックスレッドは有効（SGI
SGIの実装）
SGIの実装）• ダイナミックスレッドを無効にする% setenv OMP_DYNAMIC FALSE• threadprivateの内容を保持する場合の内容を保持する場合• 並列実行領域間で使用するCPU
並列実行領域間で使用するCPU数を固定する場合
CPU数を固定する場合

2001/03/22

26

SGI Originシステムの特徴
Originシステムの特徴

TM• ccNUMAアーキテクチャの採用
ccNUMAアーキテクチャの採用– Cache Coherent Non
Non-Uniform Memory Access• 特徴– メモリは物理的にシステム全体に分散– システム全体で論理的な共有メモリを実現– ハードウェアでキャッシュのコヒーレンシーを保証– ローカルメモリへのアクセスは、リモートメモリへのアクセス
よりも高速– それぞれのノード内のローカルなメモリアクセスには相互干渉がない

2001/03/22

27

SGI Origin3800 アーキテクチャTM• システム全体として共有メモリシステム• 4CPUでローカルメモリを共有
CPUでローカルメモリを共有
×32ボード=128 CPU

C-brick

C-brick

メモリ

メモリ

3.2GB/s

NUMAlink3
多段ルータ接続
ネットワークハブ
1.6GB/s

1.6GB/s

L2
8MB

CPU

CPU

L2
8MB

L2
8MB

CPU

CPU

L2
8MB

リンク１本=1.6GB/s×2=3.2GB/s

3.2GB/s

ハブ
1.6GB/s

1.6GB/s

L2
8MB

CPU

CPU

L2
8MB

L2
8MB

CPU

CPU

L2
8MB

2001/03/22

28

データ配置方法

TM– データ（ページ単位）は初期化されて初めてメモリに配置される（ファーストタッチ）– もし、初期化が逐次実行領域であれば該当するデー
タはすべて特定ボードのメモリに配置される– 並列実行領域では全プロセッサが特定ボードのメモ
リをアクセスすることになり、プログラムのスケーラビ
リティが低下する

実際の演算部分
と同じ配置になるよう初期化部分も並列化する

CPU

CPU

CPU

CPU
ハブ

メモリ

ハブ

メモリ

CPU

CPU

CPU

CPU

real*8 A(n), B(n), C(n), D(n)!$omp parallel do private(i)do i=1, nA(i) = 0.
B(i) = i/2
C(i) = i/3
D(i) = i/7
enddo!$omp parallel do private(i)do i=1, nA(i) = B(i) + C(i) + D(i)enddo
2001/03/22

29

TM

SGI Originでの性能解析
Originでの性能解析

SpeedShopによる解析

TM• プログラムのボトルネックの解析• 関数、サブルーチン単位での解析– 行レベルでも解析可能• 特別なコンパイルオプションは不要• 再コンパイルなしで解析が可能
man speedshop% ssrun -fpcsampx 実行モジュール名% prof -h データファイル名１ [データファイル名2]…
実行モジュール名+.fpcsampx.[mp]PID
2001/03/22

31

SpeedShop:: 解析例
SpeedShopTM

SpeedShop解析結果
Summary of statistical PC sampling data (fpcsampx)-2844: Total samples
2.844: Accumulated time (secs.)
1.0: Time per sample (msecs.)
4: Sample bin width (bytes)------------------------------------------------------------------------line list, in descending order by time------------------------------------------------------------------------secs% cum.% samples function (dso: file, line)
2.600 91.4% 91.4%
2600
0.079 2.8% 94.2%
79
0.053 1.9% 96.1%
53
0.042 1.5% 97.5%
42．．．（略）．．．

ソースコードmainの中の2番目の並列実行領域の意味__mpdo_MAIN__2 (a.out: main.f, 14)__mpdo_MAIN__2 (a.out: main.f, 15)__mp_wait_for completion (libmp.so:……
__mpdo_MAIN__1 (a.out: main.f, 8)

main.fの14
行目に対
応

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.

program main
parameter(n=1000)
real a(n,n),b(n,n),c(n,n)
do j=1,ndo i=1,na(i,j)=1.
b(i,j)=1.
c(i,j)=0.
enddo
enddo
do k=1,ndo j=1,ndo i=1,nc(j,k)=c(j,k)+a(k,i)*b(i,j)
enddo
enddo
enddo
print *,c(1,1)
end

2001/03/22

32

perfex コマンドTM

• プログラム実行時の命令レベルの統計情報を収集– 全体のMflops値、キャッシュ利用情報など• 実行終了時に標準エラー出力に出力• 再コンパイルなしで解析が可能
man perfex% perfex –a –x –y 実行モジュール名

2001/03/22

33

perfex -a -x -y: 出力例

TM

Costs for pid
4331257 (a.out)
TypicalMinimum
Maximum
Event Counter NameCounter Value
Time (sec)Time (sec)Time (sec)=======================================================================================================
0 Cycles........................................... 127370944
0.318427
0.318427
0.318427
16 Executed prefetch instructions...................
11718624
0.000000
0.000000
0.000000
21 Graduated floating point instructions...........
116991216
0.292478
0.146239
15.208858
18 Graduated loads..................................
69565280
0.173913
0.173913
0.173913
2 Decoded loads....................................
59090752
0.147727
0.147727
0.147727
4 Miss handling table occupancy....................
40460768
0.1011520.1011520.101152
25 Primary data cache misses........................
2473200
0.052555
0.013417
0.052555
6 Resolved conditional branches....................
18776368
0.046941
0.046941
0.046941
26 Secondary data cache misses.....................
60752
0.0151710.009573
0.015171
3 Decoded stores...................................
28409120.007102
0.007102
0.007102
19 Graduated stores.................................
2837952
0.007095
0.007095
0.007095
22 Quadwords written back from primary data cache...
5909440.005880
0.004639
0.005880
24 Mispredicted branches............................
1291360.002350
0.001937
0.002844.. .. .. .. .. (略) .. .. .. .. ..
Statistics=========================================================================================
Graduated instructions/cycle................................................
1.757898
Graduated floating point instructions/cycle.................................
0.918508
Graduated loads & stores/cycle..............................................
0.568444
Graduated loads & stores/floating point instruction.........................
0.618878
Mispredicted branches/Resolved conditional branches.........................
0.006878
Graduated loads /Decoded loads ( and prefetches )...........................
0.982430
Graduated stores/Decoded stores.............................................
0.998958
Data mispredict/Data scache hits............................................
0.041684
Instruction mispredict/Instruction scache hits..............................
0.000000
L1 Cache Line Reuse.........................................................
28.275122
L2 Cache Line Reuse.........................................................
39.709771
L1 Data Cache Hit Rate......................................................
0.965841
L2 Data Cache Hit Rate......................................................
0.975436
Time accessing memory/Total time............................................
0.784272
Time not making progress (probably waiting on memory) / Total time..........
1.000000
L1--L2 bandwidth used (MB/s, average per process)...........................
278.234584
Memory bandwidth used (MB/s, average per process)...........................
25.829338
MFLOPS (average per process)................................................
367.403153
Cache misses in flight per cycle (average)..................................
0.317661
Prefetch cache miss rate....................................................
0.048238

2001/03/22

34

TM

領域分割法への適用

ループレベルの並列化の限界

TM• すべてのループの並列化は困難– 逐次実行領域の存在• 並列化の粒度– 一般的にループレベルの並列化の粒度は小さい• ループ終了時の同期（noループ終了時の同期（no waitで非同期
waitで非同期）
で非同期）• 並列実行領域内部の同期（クリティカルセクション）• キャッシュとメモリの整合性• 領域分割法による記述• 同期ポイントの減少による並列化のオーバーヘッドの減少• メッセージパッシングプログラミング• データのローカリティの向上• スケーラビリティの向上

2001/03/22

36

プログラミングモデルの比較

TM

• MPI
– メッセージ通信ライブラリ– 必要な機能が標準関数として用意される– 関数の勉強が大変（MPI
関数の勉強が大変（MPIMPI-1.2, 125種類）
125種類）– 移植性が高い• OpenMP– 指示行、環境変数の体系– プログラムの記述やプロトタイプ作成が容易– 段階的な並列化が可能– MPIのコレクティブルーチン相当の機能がない
MPIのコレクティブルーチン相当の機能がない

2001/03/22

37

MPIと
MPIとOpenMPでの記述例
OpenMPでの記述例
MPI% cat mpi.f

デフォルト値の設定
program main
-mp,-apoがない時
include 'mpif.h'はコメントの扱い
call MPI_Init(ierr)call MPI_Comm_Rank&(MPI_COMM_WORLD,me,ierr)call MPI_Comm_Size&(MPI_COMM_WORLD,np,ierr)print *,'me = ',me,' np = ',np
call MPI_Finalize(ierr)stop
end% f90 mpi.f -lmpi% mpirun -np 4 ./a.out
me = 0 np = 4
me = 1 np = 4
me = 3 np = 4
me = 2 np = 4%

TM

OpenMP

並列実行領域% cat openmp.fの中で呼ぶ
program main!$omp parallel private(me,np)
me=0
並列実行領域!$
me=omp_get_thread_num()
の中で呼ぶ
np=1
!$
np=omp_get_num_threads()
print *,'me = ',me,' np = ',np!$omp end parallelstop
end% f90 -mp openmp.f% setenv OMP_NUM_THREADS 4% ./a.out
me = 1 np = 4
me = 2 np = 4
me = 3 np = 4
me = 0 np = 4%

2001/03/22

38

スレッド間でデータを交換する

TM• 並列実行領域内で呼ばれた関数がローカルに確保したメモリはプライベート– シェアード変数を介して交換する方法• #Nがローカル変数の内容をシェアード変数にコピー• 同期• #Mがそのシェアード変数を参照し、ローカル変数にコピー» ダブルコピー– スレッド間で直接データを交換する方法• グローバルポインタを使用して直接参照することが可能» コピー不要• SGI拡張
SGI拡張MP_SHMEM
拡張MP_SHMEM通信ライブラリ
MP_SHMEM通信ライブラリ» シングルコピー

2001/03/22

39

グローバルポインタによる参照例#include <stdio.h>

int main(void)#include <stdlib.h>{#include <omp.h>#pragma omp parallel#define

MAX_THREADS#define

N

グローバル
ポインタ

16

TM

{
hello();

10

ｄouble *r[MAX_THREADS];}
exit (EXIT_SUCCESS);int hello(void)
}

{
int

i,me,np,you;double*p;me=omp_get_thread_num();
np=omp_get_num_threads();
you=(me+1)%np;
p=malloc(sizeof(double)*N);
r[me]=p;for ( i=0 ; i<N ; i++)p[i]=me;#pragma omp barrier
p=r[you];

初期化の
完了を待つ

% cc -mp test.c% ./a.out
me = 1 you = 2 p[0]= 2.000000
me = 2 you = 3 p[0]= 3.000000
me = 0 you = 1 p[0]= 1.000000
me = 3 you = 0 p[0]= 0.000000%

ローカルなポ
インタをグローバルポイン
タにコピー

printf("me = %d you = %d p[0]= %f¥n ",me,you,p[0]);return (EXIT_SUCCESS);}

2001/03/22

40

MP_SHMEM通信ライブラリの例
MP_SHMEM通信ライブラリの例

TM% cat mp_shmem.f% f90 -mp mp_shmem.f
スレッド数の制御
program main
% setenv OMP_NUM_THREADS 4にOpenMPの実行
時ライブラリを使
integersource,target,me,pe% setenv OMP_DYNAMIC FALSE
用するので、リン
common/com/target% ./a.out
リモート参照ク時に-mpのフラ!$omp threadprivate(/com/)
put:
0
1
0
3
する変数を
グが必要
put:
1
2
1
0
threadprivate!$omp parallel
put:
2
3
2
1
で宣言する
!$omp& private(source,np,target,me,pe)
put:
3
0
3
2
me=omp_get_thread_num()%
threadprivateで宣言された変数
source=meの内容を別の並列実行領域でnp=omp_get_num_threads()
参照する場合、ダイナミックスレ
ッドの機能を無効にして、その
pe = mod(source+1,np)間にスレッド数が変化しないこ
call MP_SHMEM_PUT32とを保証する& (target, source, 1, pe)
MP_SHMEMは
この例のように並列実行領域!$omp barrier
一方向通信ラが1つしかない場合は意味があ
print '(a5,4i4)','put: ',イブラリなのでりません
データ転送の& me,pe,source,target
完了を待つ!$omp end parallelend%

2001/03/22

41

メッセージパッシングとの比較

TM• プログラミング上の利点– 領域分割のアルゴリズムは、
領域分割のアルゴリズムは、MPI
MPIなどと同様であるが、プ
MPIなどと同様であるが、プログラミングは容易• グローバル参照可能なデータを全スレッドで共有• メッセージ交換を不要にすることも可能» ゴーストセルの取り扱いがあるので実際には難しい• 性能面での利点– データ転送性能• レイテンシ• バンド幅– メッセージ交換時間の削減

2001/03/22

42

領域分割法おけるゴーストセルTM• ゴーストセルの導入– 差分法では隣接する格子点の値の重み付き平均を計算する

周期的境界条件

領域0

領域1
計算対象

領域2

領域3

ゴーストセル– 計算対象よりも一回り大きなグリッドをとり、隣接する領域と境界条件を交換しながら計算を行う

2001/03/22

43

MPIと
MPIとOpenMPのスケーラビリティ
OpenMPのスケーラビリティ

TM• NAS Parallel Benchmark （NPB）
NPB） 2.2 APPLU– MPIに基づくソースコードが提供されるベンチマーク
MPIに基づくソースコードが提供されるベンチマーク– 問題の規模（グリッド数）に応じた３ケース（Class
問題の規模（グリッド数）に応じた３ケース（Class O,A,B）
O,A,B）– 流体擬似アプリケーション• 共有メモリ型プログラミングへの変更– MPI版と同じアルゴリズムで並列化
MPI版と同じアルゴリズムで並列化– 並列化の粒度はMPI
並列化の粒度はMPI版と同じ
MPI版と同じ– ソースは25%
ソースは25%程度減少
25%程度減少• 通信性能の差がプログラムの性能差

2001/03/22

44

スケーラビリティの比較

TM• NAS Parallel Benchmark 2.2 APPLU
Origin2000 300MHz
96
Class B
OpenMP

88
80
72
64
スピードアップ

Class BMPIMPI/OpenMPもほぼ同等か、わずかに
OpenMPの方が良い

56

Class A
OpenMP

48
40

Class AMPIClass O,A,Bと問題の規模が
大きくなる

32
24

Class O
OpenMP

16
8

Class O
MPI

0
0

8

16

24

32
PE数
PE数

40

48

56

64

2001/03/22

45

TM

OpenMPのスケーラビリティの限界
OpenMPのスケーラビリティの限界

OpenMPの仕様と実装
OpenMPの仕様と実装

TM• OpenMPはスケーラビリティを考慮した仕様
OpenMPはスケーラビリティを考慮した仕様– Orphaned指示行
Orphaned指示行– ダイナミックスレッド– 並列実行領域の入れ子• OpenMPの実装は各ベンダ任せ
OpenMPの実装は各ベンダ任せ– 機能を実装するか否か– デフォルト値の設定– ハード・ソフトに依存した最適化• 性能評価2001/03/22

47

スカラの縮約（リダクション）演算TM• スカラの縮約演算の時間を評価する– MPI_Allreduceの縮約（
MPI_Allreduceの縮約（MPI_SUMの縮約（MPI_SUM）
MPI_SUM）演算– OpenMPのクリティカルセクションで縮約演算を記述
OpenMPのクリティカルセクションで縮約演算を記述
MPI

OpenMPreal(KIND=8):: sum,gsumreal(KIND=8):: gsum...
sum=1.d0
call MPI_Allreduce(sum,gsum,&
1,MPI_DOUBLE_PRECISION,&MPI_SUM,MPI_COMM_WORLD,ierr)

gsum=0.d0!$omp parallel!$omp critical
gsum=gsum+1.d0!$omp end critical!$omp end parallel

2001/03/22

48

スカラの縮約演算の処理時間

TM

10000

∝N 2

Origin2000 300MHz

時間/マイクロ秒

1000

OpenMPの方がMPIより高速

OpenMPは
MPIに比較して遅い

バイナリツリーアルゴリズム採用∝ log N
100

MPI
SHMEM
OpenMP

SGIのMPIライブラリと同等な高速通信ライブラリ
OpenMP用MP_SHMEMとは異なることに注意

10

1
1

10

100

1000

PE数
2001/03/22

49

OpenMP

TM• プログラミング– 簡潔な記述で並列処理構造の記述が可能• ループレベル• 関数やコードブロックレベル• 同じ実行モジュールに対して環境変数による制御• 使用するスレッド数に制約がない– MPIのような領域分割法にも適応可能
MPIのような領域分割法にも適応可能– スケーラビリティの限界• システム運用– ダイナミックスレッドによりシステムの利用効率が向上

2001/03/22

50

SGI Origin マニュアルページ

TM• プログラミング– OpenMP関連
OpenMP関連% man pe_environ% man omp_threads– MP_SHMEMライブラリ
MP_SHMEMライブラリ% man mp
– メッセージパッシングライブラリ MPI/SHMEM% man mpi
% man shmem• プロファイルツール% man speedshop% man perfex
2001/03/22

51

2000年
2000年11月
11月 OpenMP Fortran 2.0

TM• OpenMP 1.1
1.1に対する機能追加
に対する機能追加– Fotran90
Fotran90 配列構文に対するworkshare
配列構文に対するworkshare/end
workshare/end workshare– data文に現れる変数に
data文に現れる変数にsave
文に現れる変数にsaveの属性が必要（
saveの属性が必要（Fortran95の属性が必要（Fortran95）
Fortran95）– Fortran90 モジュール内のprivate
モジュール内のprivate変数の記述
private変数の記述– 経過時間計測関数 omp_get _wtime/_wtime/omp_get_wtick– threadprivateが共通ブロック以外の変数にも適用可能
threadprivateが共通ブロック以外の変数にも適用可能– copyinが共通ブロック以外の変数にも適用可能
copyinが共通ブロック以外の変数にも適用可能– copyprivateの追加
copyprivateの追加– reductionに配列の指定も可能
reductionに配列の指定も可能– 使用するCPU
使用するCPU数の指定
CPU数の指定 num_threads節
num_threads節– など
2001/03/22

52