応用数理工学特論
線形計算とハイパフォーマンスコンピューティング
第 2 回
計算理工学専攻 張研究室山本有作
前回の概要
1 . マイクロプロセッサのメモリ階層
– レジスタ,キャッシュ,主メモリ
2 . 単体プロセッサ向けの高性能化手法
– データ参照の局所性の向上
• レジスタ有効利用のためのループ展開
• キャッシュ有効利用のためのブロック化
– 行列乗算の例
今回の概要
1 . 並列計算機の種類と特徴
2 . 共有メモリ型並列計算機
– プログラミングモデル
– 高性能化の技法
3 . 分散メモリ型並列計算機
– プログラミングモデル
– 高性能化の技法
1 . 並列計算機の種類と特徴
• 共有メモリ型並列計算機
• 分散メモリ型並列計算機
• SMP クラスタ
• 情報連携基盤センターの並列計算機
スーパーコンピュータの性能動向
年年
性能性能
201020102000200019901990198019801970197019601960
1MFLOPS1MFLOPS
1GFLOPS1GFLOPS
1TFLOPS1TFLOPS
1PFLOPS1PFLOPS
IBM360/95IBM360/95
CDC6600CDC6600
CRAY-1CRAY-1 S-810S-810
X-MPX-MPnCUBE2nCUBE2
CM-5CM-5
S3800S3800
VPP500VPP500
SR2201SR2201
T3E-900T3E-900SR8000SR8000
ASCI-4ASCI-4ASCI-5ASCI-5
地球シミュレータ地球シミュレータ
スカラー機スカラー機ベクトル機ベクトル機ベクトル並列機ベクトル並列機並列機並列機
スカラー/ベクトル機 → 並列機スカラー/ベクトル機 → 並列機
(10 times faster / 20 years)(10 times faster / 20 years)44
並列計算機の登場
• 並列計算機の普及の背景– プロセッサの動作周波数向上の飽和– 専用スーパーコンピュータの設計コストの増加
• 並列計算機の特長– プロセッサ数を増やすことでピーク性能を無制限に向上可能– 分散メモリ型並列機では,プロセッサ数に比例した大きなメ
モリ空間が利用可能– 汎用のプロセッサを使うことで設計コストを大幅に削減可能
• 並列計算機の問題点– 多数のプロセッサを効率良く働かせるには,良い並列化アル
ゴリズムが必要
並列処理による高速化
• 複数のプロセッサで処理を分担することにより,プログラムの実行時間を短縮
• プログラムの中で並列化対象部分の占める割合が大きいほど,高速化の効果が大きい
1プロセッサ
並列計算機
さまざまな並列計算機
共有メモリ型並列計算機( SMP )
分散メモリ型並列計算機
SMP クラスタ
Itanium サーバ Power Mac G5
日立 SR2201 PC クラスタ
地球シミュレータ
日立 SR11000
Power Mac G5 クラスタ
チップレベルでの並列処理
• 最近では,ゲーム機の専用プロセッサが非常に高性能化– Xbox360 用プロセッサ: 汎用 PC の6倍の性能– PlayStation3 用プロセッサ( Cell ): 汎用 PC の 20 倍の性
能
PlayStation3Cell 写真プロセッサ Cell 図プロセッサブロック
( 9 個の CPU を内蔵)
これらを数値計算に活用できれば,非常に低コストで超高速の計算が可能
共有メモリ型並列計算機
• 構成– 複数のプロセッサ( PU )がバスを 通してメモリを共有– PU はそれぞれキャッシュを持つ。
• 特徴– メモリ空間が単一のためプログラミングが容易– PU の数が多すぎると,アクセス競合により性能が低下 → 4~8台程度の並列が多い。
• プログラミング言語– OpenMP ( FORTRAN/C/C++ + 指示文)を使用
PU0 PU1 PU2 PU3
メモリ
キャッシュ
バス
分散メモリ型並列計算機
PU0 PU1 PU2 PU3キャッシュ
ネットワーク
メモリ
• 構成– 各々がメモリを持つ複数の PU を ネットワークで接続– PU はそれぞれキャッシュを持つ。
• 特徴– 数千~数万 PU規模の並列が可能– PU 間へのデータ分散を意識したプログラミングが必要
• プログラミング言語– FORTRAN/C/C++ + MPI を使用
SMP クラスタ
• 構成– 複数の共有メモリ型並列計算機 ( SMP )をネットワークで接続
• 特徴– 各ノードの性能を高くできるため,比較的少ないノード数
で高性能を達成できる。– プログラミングは,ノード内部の計算では共有メモリ型並
列機として,ノードをまたがる計算では分散メモリ型並列機として行う。
• プログラミング– MPI と OpenMP とを組み合わせて使用
PU0 PU1 PU2 PU3
メモリ
ネットワーク
PU0 PU1 PU2 PU3
メモリ
PU0 PU1 PU2 PU3
メモリ
情報連携基盤センターの並列計算機
• 富士通 PrimePower HPC2500 ( SMP クラスタ)– 8GFLOPS/プロセッサ– 64 プロセッサ/ノード– 全 24ノード– 全体で 12TB の主記憶
• 講義での利用– ID: w49021a ~ w49040a
– Password: mpi2006
PU0 PU1 PU2 PU3
メモリ
ネットワーク
PU0 PU1 PU2 PU3
メモリ
PU0 PU1 PU2 PU3
メモリ
並列アルゴリズムの例 (1)
• 数値積分による π の計算– π =∫0 1 4/(1+x2) dx の積分区間
を n等分し,中点則により計算。
• 計算の並列化– n 個の長方形を4個のプロ
セッサに割り当て,担当する長方形の面積の計算と部分和の計算を各プロセッサが行う。
– 各プロセッサからの寄与を合計する処理はプロセッサ0が行う。
10 x
4/(1+x2)
プロセッ
サ
0
プロセッ
サ
1
プロセッ
サ
3
プロセッ
サ
2
並列アルゴリズムの例 (2)
• 2次元領域の温度変化の計算– 各格子点での温度変化を,隣接する4個の格子点との温度差から計算。
• 計算の並列化– 格子を4個の領域に分割し,各領域に属する格子点での温度変化をその領域の担当プロセッサが計算。
プロセッサプロセッサ 0 プロセッサプロセッサ 1
プロセッサプロセッサ 2 プロセッサプロセッサ 3
分散メモリ型並列計算機での並列化
• 分散メモリ– 各プロセッサは固有のメモ
リ空間を持ち,自分の担当する部分データを格納する。
– 共有メモリ方式に比べハードが作りやすく,超並列機に向く。
• プロセッサ間通信– 他プロセッサの持つデータ
を参照するには,通信が必要。
プロセッサプロセッサ 0 プロセッサプロセッサ 1
プロセッサプロセッサ 2 プロセッサプロセッサ 3
通信通信
分散メモリ型並列計算機での並列化(続き)
• プログラム例 プロセッサプロセッサ 0 プロセッサプロセッサ 1
プロセッサプロセッサ 2 プロセッサプロセッサ 3
通信通信
PROGRAM HEATREAL*8 A(4,4)◆ 初期設定DO ITER=1, 100 DO I=1, 4 DO J=1, 4 ◆ 必要なら隣接プロセッサ より A の値を受け取る ◆ A(I,J) の値を更新 END DO END DO END DO◆ 結果の出力STOPEND
並列化効率の向上
• 並列実行時間=演算時間+通信時間+待ち時間
• 並列化効率= 1プロセッサでの実行時間1プロセッサでの実行時間pp プロセッサでの実行時間 プロセッサでの実行時間 × p× p
時間時間
プロセッサ0プロセッサ0
プロセッサ1プロセッサ1
プロセッサ2プロセッサ2
プロセッサ3プロセッサ3
: 演算時間: 演算時間 : 通信時間: 通信時間 : 待ち時間: 待ち時間
2.1 共有メモリ型並列計算機のプログラミング
• OpenMP とは
• OpenMP プログラムの構成要素
• 簡単な OpenMP プログラムの例
• 共有変数とプライベート変数
• ループへのスレッド割り当ての指定
• セクション型の並列化
• 参考文献
OpenMP とは
• 共有メモリ型並列計算機上での並列プログラミングのためのプログラミングモデル– ベース言語( FORTRAN/C/C++ )をディレクティブ(指示文)により並列プログラミングができるように拡張
• 米国のコンパイラメーカーを中心に仕様を決定– 1997/10 FORTRAN Ver. 1.0 API
– 1997/10 C/C++ Ver. 1.0 API
OpenMP の実行モデル
• Fork-join モデル– 並列化を指定しない部分は逐次的に実行– 指示文で指定された部分のみを複数のスレッドで実行
– 各スレッドは同じメモリ空間をアクセス
スレッド 1 スレッド 2 スレッド 3スレッド 0
並列起動( fork )
並列終了( join )
並列実行部分
逐次実行部分
逐次実行部分
OpenMP プログラムの構成要素
• 元のプログラム– 通常の FORTRAN または C/C++ で書かれたプログラム
• 指示文– 並列化すべき場所,並列化方法を指定– FORTRAN では !$OMP で始まる文
• ライブラリ関数– 並列実行部分でスレッド番号を取得するときなどに用いる。
• 環境変数– 並列実行部分で使うスレッド数などを指定するのに用いる。– 杉原研 Opteron マシンでは,環境変数 NCPUS でスレッド
数を指定
簡単な OpenMP プログラムの例 (1)
• 環境変数 NCPUS を 2 に設定• 下記のプログラムをコンパイル・実行
• 実行結果
program hellointeger omp_get_thread_numwrite(6,*) ‘program start.’!$omp parallelwrite(6,*) ‘My thread number =’, omp_get_thread_num()!$omp end parallelwrite(6,*) ‘program end.’Stopend
スレッド番号を取得するライブラリ関数
指示文: 並列実行部分の開始
指示文:並列実行部分の終了
My thread number = 0My thread number = 1
簡単な OpenMP プログラムの例 (2)
• 環境変数 NCPUS を 2 に設定• 下記のプログラムをコンパイル・実行
• 実行結果– 1 i 50 ≦ ≦ がスレッド 0 , 51 i 100 ≦ ≦ がスレッド 1 で計算され
る。
program axpyinteger idouble precision a, x(100), y(100), z(100)( a , x(100) , y(100) の値を設定)!$omp parallel dodo i = 1, 100 z(i) = a*x(i) + y(i)end do( z(100) の値を表示)stopend
指示文: 直後の do ループの並列化指示
ベクトルの加算 z = ax + y
共有変数とプライベート変数
• 共有変数– OpenMP のプログラミングモデルでは,基本的にすべての変数は共有変数(どのスレッドからも書き込み/読み出し可能)
– プログラム例 (2) の a , x , y , z は共有変数の例
• プライベート変数– ループインデックス変数 i については,スレッド 0 と 1
で共有すると,正しい制御ができない。そこで,各スレッドがそれぞれ別の変数を持つ必要がある。
– このような変数をプライベート変数と呼ぶ。
変数の共有指定
• デフォルト値– 何も指示をしない変数については,基本的に共有変数とな
る。– しかし,並列化されたループのインデックス変数のように,明らかにプライベート変数でなければならない変数については,特に指示をしなくてもプライベート変数となる(ただし,多重ループの場合は並列化対象ループのインデックス変数のみ)。
• 共有変数の指定(通常は不要)– 並列化指示文の後に, shared 節を追加する。
• プライベート変数の指定– 並列化指示文の後に, private 節を追加する。
• 例 (2) のプログラムで,指示を省略せずに書く場合– !$omp parallel do shared(a, x, y, z) private(i)
変数の共有指定の例
• 2重ループの並列化(行列ベクトル積)
– a, x, y は自動的に共有変数となる。– i は自動的にプライベート変数となる。– j はプライベート変数とすべきだが,自動的にはそうならな
い(並列化対象ループのインデックス変数ではない)ので指定が必要。
program gemvinteger i, jdouble precision a(100,100), x(100), y(100) ( a(100,100) , x(100) の値を設定)!$omp parallel do private(j)do i = 1, 100 y(i) = 0.0d0 do j = 1, 100 y(i) = a(i,j) * x(j) end doend do( y(100) の値を表示)stopend
j をプライベート変数に指定
リダクション変数
• 総和の計算(ベクトルの内積)
• 並列化の際,変数 c は共有変数とすべきか?– そうすると,総和が正しく計算できない(排他制御の問題)。
• プライベート変数とすべきか?– そうすると,並列実行部分終了後に, c の値が消えてしまう。
program dotinteger idouble precision x(100), y(100), c( x(100) , y(100) の値を設定)c = 0.0d0do i = 1, 100 c = c + x(i)*y(i)end do( c の値を表示)stopend
リダクション変数(続き)
• リダクション変数とは– 並列実行部分ではプライベート変数で,並列終了時に各ス
レッドの値が合計されるような変数
– これにより,総和型のループも正しく並列化できる。– 総和の他に,積や最大値を求めるリダクション変数指定も可
能
program dotinteger idouble precision x(100), y(100), c( x(100) , y(100) の値を設定)c = 0.0d0!$omp parallel do reduction(+:c)do i = 1, 100 c = c + x(i)*y(i)end do( c の値を表示)stopend
c をリダクション変数に指定(総和型)
ここで c の値が合計される。
ループへのスレッド割り当ての指定
• 指定なしの場合の割り当て方法– インデックス変数の値の範囲をスレッド数分に分割し,各
部分をスレッドに割り当てる。
• 負荷の不均等が生じる場合– 上三角行列とベクトルの積の計算などでは,この やりかたで割り当てると負荷の不均等が発生– 一定の長さ L のブロックを周期的にスレッドに割り 当てるブロックサイクリック割り当てを採用すると, 負荷分散を改善できる場合がある。 × =
× =
ループへのスレッド割り当ての指定(続き)
• ブロックサイクリック割り当ての例
– 上記の例は,コンパイル時に割り当てを決める静的割り当て– 動的割り当てや,環境変数による割り当て方法指定も可能
program gemvinteger i, jdouble precision a(100,100), x(100), y(100) ( a(100,100) , x(100) の値を設定)!$omp parallel do private(j) schedule(static,10)do i = 1, 100 y(i) = 0.0d0 do j = i, 100 y(i) = a(i,j) * x(j) end doend do( y(100) の値を表示)stopend
ブロック幅 10 のブロックサイクリック割り当てインデックス変数 j は陽にプライベート指定
上三角行列とベクトルの積
セクション型の並列化
• 今まで学んだのは,主に do ループの並列化• 各スレッドに別々の仕事を並列に行わせたい場合は,セクショ
ン並列化を指定する。
program main(逐次処理の部分)!$omp parallel sections!$omp section(ここにスレッド 0 の処理内容を記述)!$omp section(ここにスレッド 1 の処理内容を記述)!$OMP end parallel sections(逐次処理の部分)stopend
セクション並列化の開始
セクション並列化の終了
参考文献
• 南里豪志,天野浩文: “ OpenMP入門 (1), (2), (3)” ,九州大学情報基盤センター広報,全国共同利用版 , Vol.2, No.1 (2002), pp.1-40.– http://www.cc.kyushu-u.ac.jp/RD/watanabe/RESERCH/MANUSCRIPT
/KOHO/OpenMP/intro.html
• 佐藤三久: “ OpenMP” , JSPP’99 チュートリアル , 1999.– http://phase.hpcc.jp/Omni/openmp-tutorial.pdf
• PGI Workstation User’s Guide– http://www.uic.edu/depts/accc/hardware/argo/pgi/pgiws_ug/pgiug__t.htm
Top Related