非静力学海洋モデルkinaco のGPUによる高速化 · 非静力学海洋モデルkinaco...
Transcript of 非静力学海洋モデルkinaco のGPUによる高速化 · 非静力学海洋モデルkinaco...
非静力学海洋モデルkinacoのGPUによる高速化
山岸孝輝1, 松村義正2
1 高度情報科学技術研究機構2 東京大学大気海洋研究所
平成28年度 高速化ワークショップ~「京」を中核とするHPCI、メニーコアを見据えて~
平成29年3月24日 秋葉原UDXカンファレンス
Ver. 1.1
発表の概要GPUの基本
ハードの特徴実行モデル・プログラミングモデル性能を引き出すための基本
海洋モデルのGPUによる高速化事例まとめ
2
(※本発表ではNVIDIA GPUを前提)
GPUの基本
3
GPUの構造
単純な構造でリソースの大半は演算 多数のコア
NVIDIA Kepler GPUのブロックダイアグラム
4
ハード性能(演算)低クロックのコアを多数
バルクで高い演算性能、高並列計算コア内パイプライン化あり
複雑な機構は無しインオーダで処理無し:プリフェッチ、分岐予測etc.
高い演算性能、高並列計算単純な命令スケジューリング
5
ハード性能(メモリ・キャッシュ)
高いメモリバンド幅、高レイテンシGDDR5の性質
キャッシュ:CPUより弱い(階層による)演算にリソースを多く割り当てた結果
高いメモリバンド幅、高レイテンシ弱いキャッシュ
6
CPU/GPU 実行モデル
各々のハードウェアの特徴によるもの
64 65 66 67 68 94 95
0 1 2 3 4 331
330…
…
スレッド0
64 65 66 67 68 94 95…
7
CPU GPU
1スレッドが連続データを処理CPUコア数=スレッド数
基本は1スレッドが1データを処理GPUコア数<<スレッド数
逐次処理 並列処理
カーネルのCUDA化
__global__ void func(){
int i = threadidx.x;JST[i] = UTC[i] + 9;
GPU
void func(){
for(i=0;i<N;i++){ JST[i] = UTC[i] + 9;
}
CPU
1スレッドが連続データを処理 1スレッドが1データを処理
関数利用時にスレッドの総数・形状を指定
組み込み命令でスレッド管理
書くだけなら結構簡単だが、スレッドとデータの対応付けは完全に書き手に任されている
8
逐次処理 並列処理
ハードウェア・実行モデル・プログラミングモデルの理解のもとでスレッドとデータの対応をつける必要あり
CUDA: NVIDIA GPU用の原語拡張
CPU 依存性のある命令
do i = 1, Ntmp = data( i )out(i) = tmp + 2.0
end do
プリフェッチ、キャッシュ、ソフトウェアパイプライン など 様々な手段で対応
実行
待ち
データ読み込み待ちが発生
1スレッドが逐次で処理
9
時間
GPU スレッドの切り替え
0 1 2 3 0
0
1
2
3
ストールしたスレッド→待機していた他のス
レッドに入れ替え他のスレッドにもレジスタを割り当てて、準備をさせておく→外部メモリなどへの
待避無しにすぐに切り替え可能
※本当は32スレッドごとに入れ替わる(ここでは省略)
コアが常に稼働する状態10
時間
:実行 :待ち(ストール) :待機(active)
スレッドの切り替え(続き)効率的にレイテンシを隠蔽するには
スレッドが多い方がよいスレッド間の同期はなるべくとりたくない
スレッドを「自由に」
レイテンシを隠蔽出来れば、GPUの利点「高い演算性能」と「広いメモリバンド幅」を活用出来る
11
スレッドの階層とメモリの階層
各階層でどこまでデータを共有できるかを把握する※レジスタとL1/シェアードメモリは複数のスレッド(最大で2048)でリソースを分け合うことに注意12
レジスタ65Kスレッド
L1/シェアードメモリ
48KBブロック
(例: 256スレッド)
L21MB
メモリ5GB
グリッド(全スレッド) ……
NVIDIA K20c
コアレスアクセス
64 65 66 67 68 94 95
0 1 2 3 4 331
330
インデックスが連続したスレッド群
アドレスが連続したメモリ領域
…
…+
64 65 66 67 68 94 95
0 1 2 115 ex. ストライド2のアクセス
→メモリ帯域が半分無駄に!!…
…
両方とも連続するようなアルゴリズムが望ましいまたはシェアードメモリの活用
13
スレッドレベルの並列性
thread 0
x = x + cx = x + bx = x + a
thread 1
y = y + cy = y + by = y + a
thread 2
z = z + cz = z + bz = z + a
thread 3
w = w + cw = w + bw = w + a
4つの独立な命令
独立なスレッドを複数用意スレッドを切り替えてレイテンシを隠蔽
14Volkov (2010)より
命令レベルの並列性thread 0
w = w + bz = z + by = y + bx = x + bw = w + az = z + ay = y + ax = x + a
Volkov (2010)より15
4つの独立な命令
独立な命令をスレッドの中で並列処理
スレッドレベルの並列性vs 命令レベルの並列性
基本はデータ並列性多数のスレッドを用意する
複数データ/1スレッド を試してみるどこかに最適解がある
どちらが良いかは処理の内容次第余計なデータロードの削減も期待できる
16
ここまでのまとめGPUのハード性能
Good: 高い演算性能、高バンド幅Bad: 高レイテンシ、弱いキャッシュ
GPUの実行モデルとプログラミングモデルスレッドの切り替えによるレイテンシの隠蔽階層化されたスレッドとメモリ、両者の対応
その他性能を引き出すために重要なことコアレスアクセス命令レベルの並列性
17
海洋モデルのGPUによる高速化事例
18
非静力学海洋モデル kinacoウェッデル海における南極低層水形成の再現シミュレーション - 3次元Navier-Stokes方程式、移流拡散方程式
- 静水圧近似なし、3次元の流れを陽に計算- 等方構造格子- ポワソン/ヘルムホルツ方程式をマルチグリッ
ド法を用いた前処理付きCG法で求解- 詳細はMatsumura and Hasumi (2008)
GPU向けの最適化:- Yamagishi and Matsumura (2016)- SC15, SC16 Poster session
~1kmのスケールの運動を詳細に表現
19
CPU向けの最適化実績有り
3種類のカーネル最適化事例を紹介
Case1: コアレスアクセス
Case2: 命令レベルの並列性
Case3: スレッドレベルの並列性
20
Case1:疎行列-ベクトル積
DO k=1, n3DO j=1, n2
DO i=1, n1out(i,j,k) = a(-3,i,j,k) * x(i, j, k-1) &
+ a(-2,i,j,k) * x(i, j-1,k ) &+ a(-1,i,j,k) * x(i-1,j, k ) &+ a( 0,i,j,k) * x(i, j, k ) &+ a( 1,i,j,k) * x(i+1,j, k ) &+ a( 2,i,j,k) * x(i, j+1,k ) &+ a( 3,i,j,k) * x(i, j, k+1)
END DOEND DO
END DO
-3 -2 -1 0 1 2 3
a(-3,i,j,k)~a( 3,i,j,k)
7点ステンシル計算に相当
係数行列
係数の空間的配置
-3
3
1-1-2
2
0
キャッシュライン上に7点をまとめる
21
CPU実装
GPUでコアレスアクセス
a(i,j,k,-3)
a(i+1,j,k,-3)
a(i+2,j,k,-3)
thread(id)thread(id+1)
thread(id+2)
a(-3:3,i,j,k) a(i,j,k,-3:3)
GPUの各スレッドがストライドアクセス(7間隔)
a(-3,i,j,k) a(-3,i+1,j,k) a(-3,i+2,j,k)
thread(id) thread(id+1) thread(id+2)
次元の入れ替えでコアレスアクセス22
Case 2: 命令レベルの並列性
i = threadidx%x + blockdim%x * (blockidx%x-1)j = threadidx%y + blockdim%y * (blockidx%y-1) k = threadidx%z + blockdim%z * (blockidx%z-1)
out(i,j,k) = a(i,j,k,-3) * x(i, j, k-1) &+ a(i,j,k,-2) * x(i, j-1,k ) &+ a(i,j,k,-1) * x(i-1,j, k ) &+ a(i,j,k, 0) * x(i, j, k ) &+ a(i,j,k, 1) * x(i+1,j, k ) &+ a(i,j,k, 2) * x(i, j+1,k ) &+ a(i,j,k, 3) * x(i, j, k+1)
できる限り多くのスレッドを設定 (i, j, k)
• 3次元スレッド(i, j, k) • 1スレッド for 1データ
スレッドを切り替えることでレイテンシを隠蔽23
命令レベルの並列性を確保独立な命令をスレッド内で繰り返し
i = threadidx%x + blockdim%x * (blockidx%x-1)j = threadidx%y + blockdim%y * (blockidx%y-1)
DO k=1, n3out(i,j,k) = a(i,j,k,-3) * x(i, j, k-1) &
+ a(i,j,k,-2) * x(i, j-1,k ) &+ a(i,j,k,-1) * x(i-1,j, k ) &+ a(i,j,k, 0) * x(i, j, k ) &+ a(i,j,k, 1) * x(i+1,j, k ) &+ a(i,j,k, 2) * x(i, j+1,k ) &+ a(i,j,k, 3) * x(i, j, k+1)
END DO
命令を重ねてレイテンシ隠蔽
• 2次元スレッド(i, j)• 1スレッド for 1カラム
(i, j)
本カーネルでは2次元スレッドの設定の方が高速 24
Case 3: スレッドレベルの並列性
物理過程の1カーネル 処理の概要
※実際のカーネルはより複雑、要点だけ抽出
DO i,j,k looptx(i,j,k) = Fx( A(i,j,k) )ty(i,j,k) = Fy( B(i,j,k) )tz(i,j,k) = Fz( C(i,j,k) )
END DO
DO i,j,k loopout(i,j,k) = Fout( tx(i,j,k), tx(i-1,j,k),
ty(i,j,k), ty(i,j-1,k),tz(i,j,k), tz(i,j,k-1) )
END DO
k-1
i-1j-1
(i,j,k)
25
CPU tunedDO k loopDO i,j looptz0(i,j) = tz1(i,j)tx (i,j,k) = Fx( A(i,j,k) )ty (i,j,k) = Fy( B(i,j,k) )tz1(i,j) = Fz( C(i,j,k) )
END DO
DO i,j loopout(i,j,k) = Fout( tx(i,j,k), tx(i-1,j,k),
ty(i,j,k), ty(i,j-1,k),tz1(i,j) , tz0(i,j) )
END DOEND DO
2次元データでブロック化キャッシュに
k軸のデータは使い回しする
26
GPU tunedi=threadidx%x; j=threadidx%y
DO k loopr_tz0 = r_tz1r_tx = Fx( A(i ,j ,k) )r_ty = Fy( B(i ,j ,k) )r_tz1 = Fz( C(i ,j ,k) )r_tx_im1 = Fx( A(i-1,j ,k) )r_ty_jm1 = Fy( B(i ,j-1,k) )
out(i,j,k) = Fout( r_tx , r_tx_im1,r_ty , r_ty_jm1,r_tz1, r_tz0 )
END DO
2次元でスレッドを生成
隣接格子上の計算を付加レジスタで確保
k-1
i-1j-1
(i,j,k)
各スレッドが独立同期が不要 27
1スレッドK軸ループ
Case3「次に」何をやるべきか複数データ/1スレッド
レジスタ増えるがロードストア・演算が減少シェアードメモリの利用
tx, ty, tzを各スレッドで計算させた後スレッド間で共有スレッド間で同期をとる必要あり
以上はプロセッサのリソースとのバランスが重要
レジスタ、シェアードメモリ増加→割り当てスレッド数減少→レイテンシ隠蔽が非効率化
28
海洋モデル高速化 上記以外の施策
カーネルの分割・融合シェアードメモリによるスレッド間での共有CPU-GPU間転送の最小化混合精度演算(連立方程式ソルバ前処理を単精度化)粒子追跡コードにてメモリアクセスの改善テクスチャメモリの活用参考:Yamagishi and Matsumura (2016), SC(15, 16)Poster Session
29
性能評価事例 実験設定CPU (Fujitsu SPARC64VIIIfx) vs GPU (NVIDIA K20c)
1 CPU vs 1 GPU傾圧不安定を伴う対流混合実験
Visbeck et al. (1996)外部強制: 温度forcing, コリオリ力等方構造格子
size: (256, 256, 32)時間ステップ/総時間
2min/5hours (150 steps)
256256
32
3次元: 200万2次元: 6万
スレッド数
性能比較
CPU GPU Speedup all components 174.2 37.3 4.7 Poisson/Helmholtz solver 36.8 10.5 3.5
others 137.4 26.8 5.1
経過時間[s]: CPU vs GPU
GPUはCPU比較で4.7倍高速 31
CPU GPU
Computational performance (GFLOPS) 7.7 42.3(dp)/3.8(sp)
GFLOPS/PEAK (%) 6.0 3.6(dp)/0.1(sp)Memory throughput (GB/S) 22.2 114.1
演算, メモリ性能: CPU vs GPU dp: double precision, sp: single precision
まとめGPUの基本を説明
ハードの特長、実行モデル・プログラミングモデルGPUで性能を引き出すための基本
非静力学海洋モデルの高速化事例紹介コアレスアクセス、命令レベルの並列性、レジスタ活用によるスレッドレベルの並列性
紹介しきれなかった細かい工夫も多数CPU比較で5倍弱の高速化
32
ReferencesNVIDIA公式資料
CUDA C Best Practices Guide, CUDA C Programming GuideProgramming Massively Parallel Processors, Third Edition, David B. Kirk, Wen-mei W. Hwu, Morgan Kaufmann.CUDA Cプロフェッショナルプログラミング, John Chengら, インプレス.V. Volkov. Better performance at lower occupancy. GPU Technology Conference 2010.Dan Cyca. Essential CUDA Optimization Techniques. 2014. http://on-demand.gputechconf.com/gtc/2014/video/S4702-essential-cuda-optimization-techniques-acceleware-part-4.mp4Matsumura, Y. and Hasumi, H., 2008. A non-hydrostatic ocean model with a scalable multigrid Poisson solver. Ocean Modelling.Yamagishi, T. and Matsumura, Y., 2016. GPU Acceleration of a Non-hydrostatic Ocean Model with a Multigrid Poisson/Helmholtz Solver. Procedia Computer Science 80, 1658-1669.出川智啓, GPGPU実践プログラミング, http://www.toffee.jp/streaming/gpgpu/index.html
33