gpuコンピューティングの現状と未来*seismic cpml* fim gtc dns gaussian specfm3d geos-5...
TRANSCRIPT
GPUコンピューティングの現状と未来
成瀬 彰, HPC Developer Technology, NVIDIA
© NVIDIA Corporation 2013
Summary
我々のゴールと方向性
ゴール実現に向けて進めている技術開発
Unified Memory, OpenACC
Libraries, GPU Direct
Keplerの機能紹介
Warp shuffle, Memory system
Hyper-Q, Dynamic Parallelism
© NVIDIA Corporation 2013
Our Goals
プログラミング簡易化 ポータビリティ
多数アプリをカバー 電力効率
© NVIDIA Corporation 2013
様々な分野で使われるGPUコンピューティング
© NVIDIA Corporation 2013
CUDA パラレル・コンピューティング・プラットフォーム
© NVIDIA Corporation 2013
CUDA パラレル・コンピューティング・プラットフォーム
© NVIDIA Corporation 2013
CUDA パラレル・コンピューティング・プラットフォーム
© NVIDIA Corporation 2013
GPUプログラミング言語
© NVIDIA Corporation 2013
GPUプログラム実行環境
© NVIDIA Corporation 2013
GPU ロードマップ D
P G
FLO
PS p
er
Watt
Kepler
Tesla
Fermi
Maxwell Unified Memory
Dynamic Parallelism
FP64
CUDA
32
16
8
4
2
1
0.5
2008 2010 2012 2014 2016
Now
© NVIDIA Corporation 2013
Tesla K40
メモリ容量 より多くのアプリ
CPUクロック 電力状況により
適切なクロックを選択
6GB
流体 解析
地震波 解析
レンダ リング
12GB
GPU Boost
© NVIDIA Corporation 2013
Unified Memory
現在 将来
© NVIDIA Corporation 2013
Unified Memory
void sortfile(FILE *fp, int N) {
char *data = (char*)malloc(N);
char *sorted = (char*)malloc(N);
fread(data, 1, N, fp);
cpu_sort(sorted, data, N);
use_data(sorted);
free(data); free(sorted)
}
CPU code
void sortfile(FILE *fp, int N) {
char *data = (char*)malloc(N);
char *sorted = (char*)malloc(N);
fread(data, 1, N, fp);
char *d_data, *d_sorted;
cudaMalloc(&d_data, N);
cudaMalloc(&d_sorted, N);
cudaMemcpy(d_data, data, N, …);
gpu_sort<<<…>>>(d_sorted, d_data, N);
cudaMemcpy(sorted, d_sorted, N, …);
cudaFree(d_data); cudaFree(d_sorted);
use_data(sorted);
free(data); free(sorted)
}
GPU code
© NVIDIA Corporation 2013
Unified Memory
void sortfile(FILE *fp, int N) {
char *data = (char*)malloc(N);
char *sorted = (char*)malloc(N);
fread(data, 1, N, fp);
cpu_sort(sorted, data, N);
use_data(sorted);
free(data); free(sorted)
}
void sortfile(FILE *fp, int N) {
char *data = (char*)malloc(N);
char *sorted = (char*)malloc(N);
fread(data, 1, N, fp);
gpu_sort<<<…>>>(sorted, data, N);
use_data(sorted);
free(data); free(sorted)
}
CPU code GPU code (UVM)
© NVIDIA Corporation 2013
OpenACC: ディレクティブ
Program myscience
... serial code ...
!$acc kernels
do k = 1,n1
do i = 1,n2
... parallel code ...
enddo
enddo
!$acc end kernels
...
End Program myscience
CPU GPU
オリジナルFotrran/C コード
OpenACC
Compiler
Hint
シンプル: ディレクティブ挿入
パワフル: 少ない労力、
コンパイラが並列化
オープン: 多数のベンダのアクセラレータをサポート
NVIDIA, AMD, (soon) Intel
© NVIDIA Corporation 2013
OpenACC の特徴
オープンスタンダード ヘテロジニアス アーキテクチャ
X86 and ARM
AMD, Intel, NVIDIA
多分野への応用 親しみやすいプログラミングモデル
© NVIDIA Corporation 2013
(アーキテクチャ向け最適化はコンパイラが実施)
プログラマは並列化に注力
OpenACCによるアプリ高速化事例事例 (ORNL and Tokyo Tech)
(dual-CPU nods vs. CPU+GPU)
S3D Combustion
NICAM Weather/Climate
• Tuned top 3 kernels for GPUs (90% of runtime) • End result: 2.2X faster with K20X vs. dual AMD node
• Kepler is 6X faster than Fermi • Improved performance of CPU-only version by 50%
• Tuned top kernels using CUDA, then OpenACC • CUDA result: 3.1x faster on GPU vs. CPU node • OpenACC result (preliminary ) = 69-77% of CUDA
• More portable, more maintainable • Full OpenACC port in progress
Results from Cray/ORNL and Tokyo Tech
© NVIDIA Corporation 2013
OpenACC対応状況
Geology Weather/Climate/
Ocean
Plasma &
Combustion
Fluid Dynamics /
Cosmology
Quantum
Chemistry
AWP-ODC CAM-SE Cloverleaf CHIMERA CASTEP
EMGS ELAN COSMO Physics GENE PMH bv DELPASS GAMESS CCSD(T)
*Seismic CPML* FIM GTC DNS GAUSSIAN
SPECFM3D GEOS-5 LULESH MiniGHOST MiniMD
Harmonie S3D RAMSES ONETEP
HBM UPACS Quantum Espresso
ICON X-ECHO
NICAM
NEMO GYRE
NIM
PALM-GPU
ROMS
WRF
© NVIDIA Corporation 2013
CUBLAS: 逆行列計算
LAPACK準拠API
cublas<t>getrfBatched() … LU分解
cublas<t>getriBatched() … 逆行列計算
多数の小サイズ行列用
0
2
4
6
8
10
12
CPU-1core(2.8GHz,MKL)
GPU(K20,naïve)
GPU(K20,cublas)
Speed-u
p
(*) 行列サイズ:64, 行列数:1000
© NVIDIA Corporation 2013
NVIDIA GPUDirect™
データ移動を最適化する技術ファミリー
GPUDirect™ Shared GPU and System memory
ノード内のメモリコピー負荷を削減
GPUDirect™ Peer-to-Peer
ノード内の別GPUのメモリを直接アクセス
ノード内のGPU-to-GPUメモリ転送を加速
GPUDirect™ RDMA
ノード間でGPU-to-GPU RDMA通信
© NVIDIA Corporation 2013
GPUDirect™ Shared GPU and System Memory
Without GPUDirect™
GPU writes to pinned main memory 1
CPU copies main memory 1 to main memory 2
Network driver reads main memory 2
With GPUDirect™
GPU writes to pinned main memory
Network driver reads from main memory
CPU
GPU Chip
set
GPU Memory
Network
Main
Mem 1 2
CPU
GPU Chip
set
GPU Memory
Network
Main
Mem 1
© NVIDIA Corporation 2013
GPUDirect™ (Peer-to-Peer)
ホストメモリを仲介せずにデータ移動 (ノード内)
Fermi以上
© NVIDIA Corporation 2013
Network
GPUDirect™ RDMA
Server 1
GPU1 GPU2 CPU
GDDR5 Memory
GDDR5 Memory
Network Card
System Memory
PCI-e
Server 2
GPU1 GPU2 CPU
GDDR5 Memory
GDDR5 Memory
Network Card
System Memory
PCI-e
Kepler以上
ホストメモリを仲介せずにデータ移動 (ノード間)
© NVIDIA Corporation 2013
GPU-aware MPI
MPI関数だけでGPU-to-GPU通信を可能に
MPI_Send(), MPI_Recv()にデバイスメモリを指定を可能に
通信処理の最適化からプログラマを解放
パイプライン転送 (DeviceHost, HostHost, HostDevice)
送信:
cudaMemcpy( s_buf, s_device, size, … );
MPI_Send( s_buf, size, … );
受信:
MPI_Recv( r_buf, size, … );
cudaMemcpy( r_device, r_buf, size, … );
送信:
MPI_Send( s_device, size, …);
受信:
MPI_Recv( r_device, size, …);
Without GPU-aware MPI With GPU-aware MPI
© NVIDIA Corporation 2013
GPU-aware MPI Libraries
• GPUメモリからの送信・受信
• 多くの集合通信に対応
• 利用可能な最も良い転送方式を選択
Versions:
• MVAPICH2 1.9
• OpenMPI 1.7.2
• IBM Platform MPI V9.1.2 (Free Community Edition)
Reference
• NVIDIA GPUDirect Technology Overview
MVAPICH
Open MPI
IBM Platform
Computing
Computing IBM Platform MPI
© NVIDIA Corporation 2013
Kepler D
P G
FLO
PS p
er
Watt
Kepler
Tesla
Fermi
Maxwell Unified Memory
Dynamic Parallelism
FP64
CUDA
32
16
8
4
2
1
0.5
2008 2010 2012 2014 2016
© NVIDIA Corporation 2013
性能と電力: Fermi Kepler
Fermi
(M2090)
Kepler
(K20X)
ピーク演算性能(DP) 0.665 TFLOPS 1.31 TFLOPS
ピーク演算性能(SP) 1.33 TFLOPS 3.95 TFLOPS
最大メモリバンド幅 177 GB/s 250 GB/s
TDP 225 Watt 235 Watt
27
x2
x3
x1.4
x1
© NVIDIA Corporation 2013
FermiからKeplerへ
28
Fermi
Kepler
最大3倍の電力あたり性能
© NVIDIA Corporation 2013
SM(Fermi) SMX(Kepler)
Fermi
(M2090)
Kepler
(K20X)
CUDAコア 32 192
コア周波数 1.3GHz 0.73GHz
最大スレッド数 1536 2048
最大スレッドブロック数 8 16
32ビットレジスタ数 32 K 64 K
L2容量 0.75 MB 1.5 MB
29
x6
x0.6
x2
x2
x2
x1.3
© NVIDIA Corporation 2013
Keplerで強化された機能
Warp Shuffle
Memory System
Atomics Operations
Read-only Cache
Hyper-Q
Concurrency
Overlapping
Dynamic Parallelism
30
© NVIDIA Corporation 2013
Warp Shuffle
他スレッドのレジスタの読み出しを可能に
対象: 同一ワープ内のスレッド (32スレッド)
共有メモリ不要のスレッド間データ交換
__syncthreads()も不要に
Kepler世代(CC 3.0以上)から利用可能
31
© NVIDIA Corporation 2013
4種類の関数
idx, up, down, xor
a b c d e f g h
a b a b c d e f
Shift right/up to
nth neighbour
c d e f g h g h
Shift left/down
to nth neighbour
c d a b g h e f
Butterfly (XOR)
exchange
__shfl() __shfl_up() __shfl_down() __shfl_xor()
h d f e a c c b
Indexed
any-to-any
© NVIDIA Corporation 2013
Shuffleの効果(scan)
スレッドブロック内scan(prefix sum)
33
for (ofst = 1; ofst < BLOCK_SIZE; ofst *= 2) { if (idx >= ofst) smem[idx] += smem[idx - ofst]; __syncthreads(); }
SMEM (Shared Memory)
for (ofst = 1; ofst < WARP_SIZE; ofst *= 2) { if (idx >= ofst) val += __shfl_up(val,ofst,WARP_SIZE); } if (idx % WARP_SIZE == WARP_SIZE - 1) smem[idx/WARP_SIZE] = val; __syncthreads(); if (idx < NUM_WARP) { sum = smem[idx]; for (ofst = 1; ofst < NUM_WARP; ofst *= 2) { if (idx >= ofst) sum += __shfl_up(sum,ofst,NUM_WARP); } smem[idx] = sum; } __syncthreads(); if (idx/WARP_SIZE > 0) val += smem[idx/WARP_SIZE - 1];
SHFL (Shuffle)
0 入力 1 2 3
0 出力 1 3 7
4
11
© NVIDIA Corporation 2013
Parallel scan
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 10 12 14 16 18 20 22
0 1 2 3 4 6 8 10 12 15 18 21 24 28 32 36
0 1 2 4 6 9 12 16 20 25 30 36 42 49 56 64
0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120
© NVIDIA Corporation 2013
6 28 66 120
0 1 3 6 4 9 15 22 8 17 27 38 12 25 39 54
Warp scan Warp scan Warp scan Warp scan
Warp scan
Parallel scan
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
6 22 38 54
0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120
© NVIDIA Corporation 2013
Shuffleの効果事例(scan)
0
1
2
3
4
5
6
7
SMEM SHFL
Tim
e (
ms)
Scan (fp32)
36
Tesla K20
グリッド形状 (26, 1, 1)
ブロック形状 (1024, 1, 1)
1000回実行
4,096B 128B smem per block
3倍の性能UP
x3.0
© NVIDIA Corporation 2013
Shuffleの効果(reduction)
スレッドブロック内reduction
reductionコード例 (ワープ内)
SMEM (Shared Memory)
SHFL (Shuffle)
37
for (mask = WARP_SIZE/2 ; mask > 0 ; mask >>= 1) { var = __shfl_xor( var, mask, WARP_SIZE ); }
idx = threadIdx.x; for (mask = WARP_SIZE/2 ; mask > 0 ; mask >>= 1) { if (idx < mask) smem[idx] += smem[idx ^ mask]; __syncthreads(); }
© NVIDIA Corporation 2013
Shuffleの効果事例(reduction)
0
1
2
3
4
5
SMEM SHFL
Tim
e (
ms)
Reduction within TB (fp32)
38
Tesla K20
ブロック形状 (1024, 1, 1)
グリッド形状 (26, 1, 1)
1000回実行
4,096B 128B smem per block
2.4倍の性能UP
x2.4
© NVIDIA Corporation 2013
Atomic Operations
サポートタイプ・データ型の拡張
グローバルメモリ上のAtomic操作を高速化
複数カーネルに分離していた処理を単一カーネルで
効果確認
16M要素reduction
データ型はfloat
39
smem[idx] = input[g_idx]; for (mask = BLOCK_SIZE/2; mask > 0; mask /= 2) { if (idx < mask) { smem[idx] += smem[idx ^ mask]; } __syncthreads(); } if (idx == 0) { atomicAdd( output, smem[idx] ); }
© NVIDIA Corporation 2013
Atomic Operations効果事例
0
1
2
3
4
5
6
Fermi(C2075) Kepler(K20) Kepler(K20)with SHFL
Tim
e (
ms)
Reduction (Sum, SP, 16M elements)
40
ブロック形状 (1024, 1, 1)
ECC off
FermiからKepler
で2.1倍の性能UP
Shuffle命令併用で3.7倍の性能UP
x2.1
x3.7
© NVIDIA Corporation 2013
Read-Only(RO) Cache
TEX
Texture API
CUDA Arrays
一般的なRead-Onlyキャッシュとして使用可能
Kepler以降
コンパイラに指示
41
DRAM
L2 cache
SM
SMEM TEX L1 Read
only
Threads
© NVIDIA Corporation 2013
__global__ kernel( int* output, int* input ) { ... output[idx] = ... + input[idx + delta] + ...; ... }
__global__ kernel( int* output, int* input ) { ... output[idx] = ... + input[idx + delta] + ...; ... }
2つの使い方
組み込み関数: __ldg()
型修飾子: const __restrict__
42
__global__ kernel( int* output, int* input ) { ... output[idx] = ... + __ldg( &input[idx + delta] ) + ...; ... }
__global__ kernel( int* output, const int* __restrict__ input ) { ... output[idx] = ... + input[idx + delta] + ...; ... }
© NVIDIA Corporation 2013
RO Cacheの効果
Himeno BMT
19ポイント・ステンシル
テストコード
共有メモリを使用せずにCUDA化
43
jacobi_kernel( ..., float* p, ... );
jacobi_kernel( ..., const float* __strict__ p, ... );
© NVIDIA Corporation 2013
RO Cacheの効果事例(Himeno BMT)
0
10
20
30
40
50
60
70
80
90
100
Without RO cache(Fermi: C2075)
Without RO cache(Kepler: K20)
With RO cache(Kepler: K20)
GFLO
PS GFLOPS (Himeno BMT)
44
Himeno BMT問題サイズ: L
ブロック形状 (128, 2, 1)
ECC off
25%性能UP 25%
© NVIDIA Corporation 2013
Hyper-Q
Work Distributor
32 active grids
Stream Queue Mgmt
C
B
A
R
Q
P
Z
Y
X
Grid Management Unit Pending & Suspended Grids
1000s of pending grids
SMX SMX SMX SMX SM SM SM SM
Work Distributor 16 active grids
Stream Queue Mgmt
C
B
A
Z
Y
X
R
Q
P
Fermi Kepler
より多くのカーネルを
同時実行可能に
45
CUDA
Generated
Work
© NVIDIA Corporation 2013
Without Hyper-Q (Fermi)
最多16同時実行
制限: 同時実行できるのはストリーム端のカーネル
46
Kernel P, Q, R
Kernel A, B, C
Kernel X, Y, Z
Stream 1
Stream 2
Stream 3 Single Hardware Work Queue
A—B—C P—Q—R X—Y—Z
© NVIDIA Corporation 2013
With Hyper-Q (Kepler)
最多32同時実行
(偽の)ストリーム依存性から開放
47
Kernel P, Q, R
Kernel A, B, C
Kernel X, Y, Z
Stream 1
Stream 2
Stream 3
A—B—C
P—Q—R
X—Y—Z
Multiple Hardware Work Queue
© NVIDIA Corporation 2013
小カーネル同時実行テストコード
48
cudaStream_t stream[nStreams]; for (i = 0 ; i < nStreams ; ++i) { // ストリーム生成
cudaCreateStream( &stream[i] ); } dim3 gdim( 1, 1, 1 ); dim3 bdim( 1024, 1, 1 ); for (i = 0 ; i < nStreams ; ++i) { // カーネル1を投入
kernel_1<<<gdim, bdim, 0, stream[i]>>>( ... ); // カーネル2を投入
kernel_2<<<gdim, bdim, 0, stream[i]>>>( ... ); // カーネル3を投入
kernel_3<<<gdim, bdim, 0, stream[i]>>>( ... ); }
© NVIDIA Corporation 2013
小カーネル同時実行テスト(Fermi)
49
部分的に同時実行
シングルハードウェアキューの制約
Tesla C2075
© NVIDIA Corporation 2013
小カーネル同時実行テスト(Kepler)
50
全カーネル(ストリーム)を同時実行
これまでより簡単に同時実行が可能に
Tesla K20
© NVIDIA Corporation 2013
cudaMemcpy( a_dev, a_host, all, cudaMemcpyHostToDevice ); kernel_1<<<gdim, bdim>>>( c_dev, a_dev, all ); cudaMemcpy( b_dev, b_host, all, cudaMemcpyHostToDevice ); kernel_2<<<gdim, bdim>>>( c_dev, b_dev, all ); cudaMemcpy( c_host, c_dev, all, cudaMemcpyDeviceToHost );
データ転送とカーネル実行のオーバーラップ
3つの処理をオーバーラップ可能
データ転送 (Host to Device)
カーネル実行
データ転送 (Device to Host)
51
cudaMemcpy( a_dev, a_host, all, cudaMemcpyHostToDevice ); kernel_1<<<gdim, bdim>>>( c_dev, a_dev, all ); cudaMemcpy( b_dev, b_host, all, cudaMemcpyHostToDevice ); kernel_2<<<gdim, bdim>>>( c_dev, b_dev, all ); cudaMemcpy( c_host, c_dev, all, cudaMemcpyDeviceToHost );
© NVIDIA Corporation 2013
パイプライン化
パイプラインコードもHyper-Qで効率化
データ転送とカーネル実行のオーバーラップ
52
cudaStream_t stream[nStreams]; for (s = 0 ; s < nStreams ; ++s) { cudaCreateStream( &stream[s] ); } s = 0; for (p = 0 ; p < nPipeline; ++p) { cudaMemcpyAsync( a_dev[p], a_host[p], part, cudaMemcpyHostToDevice, stream[s] ); kernel_1<<<gdim, bdim, 0, stream[s]>>>( c_dev[p], a_dev[p], part ); cudaMemcpyAsync( b_dev[p], b_host[p], part, cudaMemcpyHostToDevice, stream[s] ); kernel_2<<<gdim, bdim, 0, stream[s]>>>( c_dev[p], b_dev[p], part ); cudaMemcpyAsync( c_host[p], c_dev[p], part, cudaMemcpyDeviceToHost, stream[s] );
s = (s+1) % nStreams; }
© NVIDIA Corporation 2013
オーバーラップ実行テスト(Fermi)
53
パイプライン化前
データ転送とカーネル実行のオーバーラップ無し
Tesla C2075
© NVIDIA Corporation 2013
オーバーラップ実行テスト(Fermi)
パイプライン後
データ転送とカーネル実行、相応の時間でオーバーラップ
カーネル実行の間に隙間
54
Tesla C2075
© NVIDIA Corporation 2013
オーバーラップ実行テスト(Kepler)
完全にオーバーラップ
カーネル実行の間に空き無し
Hyper-Qの効果
55
Tesla K20
© NVIDIA Corporation 2013
Dynamic Parallelismとは?
GPUからカーネルを起動する仕組み
Dynamically 実行時のデータ値に基づくカーネル起動
Simultaneously 複数スレッドから同時に起動
Independently スレッド毎に独自グリッドで起動
CPU GPU CPU GPU
Fermi Kepler
© NVIDIA Corporation 2013
CPU GPU CPU GPU
Dynamic Parallelismの動作イメージ
GPUが自律的にに動作 CPUがきめ細かく制御
© NVIDIA Corporation 2013
Dynamic Parallelism コードサンプル
__global__ void rec_func( ... ) { ... if ( blockIdx.x == 0 ) { cudaStreamCreate( &st0 ); cudaStreamCreate( &st1 ); rec_func<<< ..., st0 >>>( ... ); rec_func<<< ..., st1 >>>( ... ); cudaDeviceSynchronize(); cudaStreamDestroy( st0 ); cudaStreamDestroy( st1 ); } __syncthreads(); ... }
void rec_func( ... ) { ... rec_func( ... ); rec_func( ... ); ...
}
© NVIDIA Corporation 2013
まとめ
我々のゴール
電力効率, プログラミング簡易化, 多数アプリ
その達成のために開発している技術
Unified Memory, OpenACC
Libraries, GPU Direct, GPU-aware MPI
Keplerの機能
Warp shuffle, Memory system
Hyper-Q, Dynamic Parallelism