Mais conteúdo relacionado Semelhante a More modern gpu (20) Mais de Preferred Networks (20) More modern gpu4. しかし我々はCUDAを書くのか
l 否!
– 素⼈人はCUDAを書いてはならない [Okuta 2015]
l cupy (chainer)
– 殆どのnumpyで書く数値計算はそのままGPU化できる
– ディープラーニングだけにつかうのは勿体無い
l modern gpu/thrust (今回のメイン)
– 離離散的なアルゴリズムをSTLで書ける
– CUDAを⼀一切切書かずにかなり汎⽤用的にアルゴリズムをかける
– コンパイルが遅いのとエラー時に意味不不明
4
5. cupy (chainer.cuda.cupy)
l chainerの開発のために作られたnumpy互換ライブラリ
l Numpyと同じように書きながら、gpuの性能をフルに活かせる!
l 今までCUDAを書くのがなんだったのかという衝撃の簡単さ
l 中の仕組み
– 実⾏行行時にcudaコードを動的に⽣生成し、コンパイルし、キャッシュ
– 関数ごとの⾮非常に細切切れのcudaライブラリが⼤大量量にできている
u Chainerの規模だと数万個
– Nvidiaの⼈人⽈曰く、直接kernelをloadする仕組みを利利⽤用したのを⾒見見たのは⼆二例例⽬目だと
l きっとChainer Meetupで詳しい話がされますので今⽇日は省省略略
5
6. ModernGPUの説明のまえに・・
並列列処理理の考え⽅方
l 並列列処理理の種類
– MIMD(Multiple Instruction, Multiple Data)
u 複数の命令令で、複数のデータを同時に処理理する
u 例例:PESY-‐‑‒SC(睡蓮)、datacenter as a computer
– SIMD(Single Instruction, Multiple Data)
u ⼀一つの命令令で、複数のデータを同時に処理理する
u 例例:SSE
l GPUはMIMD + SIMD(彼らはSIMTと呼んでいる)
– 各ストリームプロセッサ(SM)は独⽴立立に動作し異異なるデータを扱う MIMD
– 各SMはwarp単位(今は16〜~32)で同じ命令令でデータをまとめて処理理をするSIMD
u 全てのデータアクセスはgather/scatter
– 各SMは⼗十分な量量のスレッドを持ち、データが揃ったスレッドから
実⾏行行することでレイテンシを隠す 6
8. 代表的な並列列処理理 (Prefix-‐‑‒)Scan
l 配列列X[0…n)が与えられた時,Scanは次を求める
– X[i] := X[0] + X[1] + ... + X[i-‐‑‒1] exclusive scan
– X[i] := X[0] + X[1] + … + X[i] inclusive scan
l Scanは次のように並列列に計算できる
– 各X[i]について,X[i] += X[i-‐‑‒1]
– 各X[i]について, X[i] += X[i-‐‑‒2]
– 各X[i]について,X[i] += X[i-‐‑‒4]
– ...
l 例例:X[7]の時,
– X[7] += X[6]
– X[7] += X[5] (=X[4]+X[5])
l これはO(log n)時間で実⾏行行できる
8
10. 例例:マージソート (1/2)
l ⼆二つのソート済み配列列X, Yが与えられた時,これらをあわせてソートせよ
l X = {1, 3, 3, 5, 7, 9, 10, 10, 11, 13, 15}
l Y = {0, 2, 3, 3, 7, 8, 8, 9, 10, 11, 14}
l Z={0, 1, 2, 3, 3, 3, 3, 5, 7, 7 8, 8, 9, 9, 10, 10, 10, 11, 11, 13, 14, 15}
l それぞれの配列列⻑⾧長をn=|X|, m=|Y|とした時,計算量量はO(n+m)
10
11. 例例:マージソート (2/2)
逐次的なマージソート
X, Y, Z
ix = 0, iy = 0, iz = 0
while (iz < n+m) {
if (comp(X[ix], Y[iy]) Z[iz++] = X[ix++]
else Z[iz++] = Y[iy++]
}
// 境界条件はcompがうまいことやってくれてることにします
これをどのように分割するのか?
11
12. マージソートの解釈
0 1 3 5 6 6 7 9 10
1
2
2
4
7
8
9
9
10
12
行にA、列にBを並べた行列を考える。
マージソートにおけるZ[iz++] = X[ix++]は右に進む、Z[iz++] = Y[iy++]は下に
進むに対応する
このパスをマージパスと呼ぶ
X[4]=6 < Y[4]=7
14. マージパスによる問題の分割
l X = 0 1 3 5 6 6 7 9 10
l Y = 1 2 2 4 7 8 9 9 10
l それぞれの問題は、⻑⾧長さ4の結果を出⼒力力するマージソートに分割される
l 0 1 と 1 2 のマージソート
l 3 5 と 2 4 のマージソート
l 6 6 7 と 7 のマージソート
l 9 と 8 9 9 のマージソート
l 10 と 10 のマージソート(最後だけ⻑⾧長さは違う)
17. 次のような問題も同様にして解ける
l Bulk Insert, Bulk Delete
– まとめて挿⼊入、まとめて削除
l Segmented Vector Reduction
– ⻑⾧長さの異異なる配列列の集合に対し,各配列列毎にReductionをする
l DBにおけるJoin
– Outer, Inner, Left-‐‑‒, Right-‐‑‒ Join
– やっていることはマージソートとほぼ同じ
l 特に興味深いのがMapReduceができる点
l これらは,Modern GPU,Thrust, Cubなどのライブラリで提供されている
17
19. GPUで転置ファイルを作ってみよう
l 転置ファイル
– 各単語毎にその出現位置を記録
1. ⽂文字列列中の単語数を数える
1. 単語境界の数を数える(!isAlpha(right) && isAlpha(left))
2. 各単語の出現位置と、そのハッシュ値を計算する
1. これはSegmented Reductionで解ける
2. (ハッシュ値、位置、⻑⾧長さ)をReduceする
3. KR法でハッシュ値を計算するのでReduceの順によらない
3. ハッシュ値で単語をソートし集める
4. ハッシュ値でSegmented Reduction
1. 各単語毎の出現位置をまとめる
19
21. 実験
l 英⽂文700MB
l マシン:Titan X
l 総単語数 106,888,008
l 異異なり単語数 1,252,268
l GPU実⾏行行時間:1.67秒
– そのうち、CPU-‐‑‒>GPU コピー時間:0.2秒
– 但し、キーの0.1%未満は衝突している
l ⽐比較:CPU実⾏行行時間 14.80秒
l 約10倍弱は速くなった
21
23. コンパイル時間
l nvcc + thrust の組み合わせはコンパイル時間がやばい
– 全てtemplateでコンパイル時に展開されるだけでなく、nvcc側の最適化も
– 1分ぐらいかかる
l お勧めは関数毎に別ソースファイルでコンパイル
– 10秒ぐらいなので,許容範囲・・
23
24. まとめ
l GPUによる並列列処理理を紹介した
– 離離散的で⾮非均質な問題も効率率率的に解けるアルゴリズムが登場してきた
– cupy, thrust, cub(未紹介)などを使えばCUDAを書かなくても並列列処理理できる
l 今後は⾮非同期,並列列処理理が重要になる
– 中央集権型,逐次型は性能⾯面,電⼒力力消費⾯面で競争⼒力力が落落ちていく
– Goのchannel, go routineのような⾔言語によるネイティブサポートが必要
– データの依存関係を⾃自然に表した,データフローモデル
l 昔のデータセンターが今は1チップで実現
– Datacenter as a computerの著者が予⾔言していたデータセンターが1チップに収
まる時代が到来しつつある (数⼗十TFlops in 1 chip)
– 通信はレイテンシ,スループット,電⼒力力量量が問題.狭い場所で処理理すれば全部解決
24