gpu hot tips: マルチgpuでプロ グラムを加速す …4 マルチgpu •...
TRANSCRIPT
![Page 1: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/1.jpg)
成瀬彰, シニアデベロッパーテクノロジーエンジニア, 2017/12/12
GPU HOT TIPS: マルチGPUでプログラムを加速する方法
![Page 2: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/2.jpg)
2
NVIDIA DGX-1V
8 x Tesa V100
NVLINK
2 x Intel Xeon
4 x EDR InfiniBand
3200 Watt
![Page 3: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/3.jpg)
3
NVIDIA DGX-1V8 x Tesla V100
PCIe
NVLINKNVLINKで全結合された4 GPUブロック x 2
6 NVLINK lanes per GPU
25+25 GB/s per lane
隣接GPUメモリへのload/store/atomics
バルクデーテ転送ようの高速コピーエンジン
![Page 4: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/4.jpg)
4
マルチGPU
• シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい
• DLトレーニング、リアルタイム処理
• シングルGPUのメモリには収まらない、もっと大きな問題を扱いたい
• 大規模シミュレーション
• マルチGPUノードがあるので、活用したい
![Page 5: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/5.jpg)
5
サンプルプログラム: ヤコビ反復法
収束条件を満たすまで、以下の計算を繰り返す
シングルGPU
for ( iy = 1; iy < ny-1; iy++ )
for ( ix = 1; ix < nx-1; ix++ )
a_new[ ix + iy*nx ] = 0.25 * ( a[ ix + (iy-1)*nx ] + a[ ix + (iy+1)*nx ]
+ a[ (ix-1) + iy*nx ] + a[ (ix+1) + iy*nx ] );
![Page 6: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/6.jpg)
6
マルチGPUで解く
1D領域分割
• 通信相手が少ない
• 並列数が少ない場合に有効
問題(2D領域)を分割して、各GPUに割り当てる
2D領域分割
• 通信量が少ない
• 並列数が多い場合に有効
![Page 7: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/7.jpg)
7
ヤコビ反復法
収束条件を満たすまで、以下の計算と通信を繰り返す
マルチGPU
for ( iy = 1; iy < ny-1; iy++ )
for ( ix = 1; ix < nx-1; ix++ )
a_new[ ix + iy*nx ] = 0.25 * ( a[ ix + (iy-1)*nx ] + a[ ix + (iy+1)*nx ]
+ a[ (ix-1) + iy*nx ] + a[ (ix+1) + iy*nx ] );
通信: 更新した要素の境界部分を、隣接GPUに送る(受け取る)
計算: 自分が担当する領域に関して、以下の計算を行う
![Page 8: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/8.jpg)
8
マルチGPUを使う方法
シングル・スレッド
• 1つのスレッドが、複数GPUを管理
マルチ・スレッド
• 複数スレッドで、複数GPUを管理(1 GPU per 1スレッド)
マルチ・プロセス
• 複数プロセスで、複数GPUを管理(1 GPU per 1プロセス)
![Page 9: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/9.jpg)
9
シングル・スレッドでマルチGPUを使う
![Page 10: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/10.jpg)
10
GPUカーネル (ヤコビ反復法)
__global__ void kern_jacobi( ... ) {
int ix = ...;
int iy = ...;
if ( out of range ) return;
new_val = 0.25 * ( a[ ix + (iy-1)*nx ] + a[ ix + (iy+1)*nx ]
+ a[ (ix-1) + iy*nx ] + a[ (ix+1) + iy*nx ] );
a_new[ ix + iy*nx ] = new_val
my_error = fabs( new_val – a[ ix + iy*nx ] );
atomicMax( error, my_error );
}
各スレッドの担当箇所を決定領域内か確認
担当要素の計算
収束条件の計算(最大差分)
計算結果をwrite
![Page 11: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/11.jpg)
11
シングルGPUの場合
while ( *error > tol ) {
cudaMemset( error_d, 0, … );
kern_jacobi<<< ... >>>( a_new, a, error_d, nx, ny );
cudaMemcpy( error, error_d, … );
swap( a_new, a );
}
最大誤差の初期化
GPUカーネルの実行
最大誤差をCPUに回収
ポインタの入れ替え
![Page 12: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/12.jpg)
12
マルチGPUの場合while ( error > tol ) {
for ( dev_id = 0; dev_id < num_devs; dev_id++ ) {
cudaSetDevice( dev_id );
cudaMemsetAsync( error_d[dev_id], 0, … );
kern_jacobi<<<blocks, threads, …>>>( a_new[dev_id], a[dev_id], error_d[dev_id],
nx, iy_start[dev_id], iy_end[dev_id] );
cudaMemcpyAsync( error_h[dev_id], error_d[dev_id], … );
prev_id = (dev_id – 1) % num_devs;
cudaMemcpyAsync( a_new[prev_id] + iy_end[prev_id]*nx,
a_new[dev_id] + iy_start[dev_id]*nx, … );
next_id = (dev_id + 1) % num_devs;
cudaMemcpyAsync( a_new[next_id],
a_new[dev_id] + (iy_end[dev_id]-1)*nx, … );
}
error = 0.0;
for ( dev_id = 0; dev_id < num_devs; dev_id++ ) {
cudaSetDevice( dev_id ); cudaDeviceSynchronize();
error = max(error, *(error_h[dev_id]));
swap( a_new[dev_id], a[dev_id] );
}
}
複数GPU、それぞれに指示cudaSetDeviceでGPU指定
GPUカーネル実行非同期API使用、
CPUがGPUの実行完了を待たないようにする
通信 (後述)
最大誤差をCPUに回収
各GPUの処理完了を待つcudaDeviceSynchronize
![Page 13: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/13.jpg)
13
通信: 境界交換
cudaMemcpyAsync(
a_new[prev_id] + iy_end[prev_id]*nx,
a_new[dev_id] + iy_start[dev_id]*nx,
… );
コピー先
コピー元
(*) 前のGPUが、次のサイクルに使うデータを送る
![Page 14: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/14.jpg)
14
通信: 境界交換
cudaMemcpyAsync(
a_new[prev_id] + iy_end[prev_id]*nx,
a_new[dev_id] + iy_start[dev_id]*nx,
… );
cudaMemcpyAsync(
a_new[next_id],
a_new[dev_id] + (iy_end[dev_id]-1)*nx,
… );
(*) 次のGPUが、次のサイクルに使うデータを送る
コピー先
コピー元
![Page 15: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/15.jpg)
15
並列性能の、性能指標と測定方法
Ts … 逐次実行時間 (シングルGPU)
Tp … 並列実行時間 (マルチGPU)
P … プロセス数 (GPU数)
S = Ts/Tp … スピードアップ (理想はP)
E = S/P … 並列化効率 (理想は1.0)
ストロング・スケーリング
• 問題サイズを固定
• プロセス数が増えるほど、プロセスあたり担当領域が小さくなる
ウィーク・スケーリング
• プロセス数に比例して問題サイズを大きくする
• プロセスあたりの問題サイズは一定
![Page 16: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/16.jpg)
16
シングルGPU性能問題サイズと性能
問題サイズは7168を使用
8 GPUのときの各GPUの問題サイズ
![Page 17: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/17.jpg)
17
マルチGPU (シングル・スレッド)DGX-1V, 1000反復
8 GPUのときの並列化効率は
6割弱
![Page 18: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/18.jpg)
18
マルチGPU (シングル・スレッド)NVVP Timeline
GPU0
GPU1
GPU2
GPU3
MemCpy(DtoH)とMemCpy(HtoD)
が使われている
GPU間の通信(コピー)が、ホストメモリ経由になっている
![Page 19: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/19.jpg)
19
PEER-TO-PEER(P2P) メモリコピー
ホスト(CPU)を介さないで、デバイス(GPU)間で、直接データ転送
GPU間がNVLINK接続なら、NVLINK使用 (そうでなければ、PCIe使用)
![Page 20: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/20.jpg)
20
P2Pの設定
for ( dev_id = 0; dev_id < num_devs; dev_id++ ) {
cudaSetDevice( dev_id );
prev_id = (dev_id – 1) % num_devs;
cudaDeviceCanAccessPeer( &canAccessPeer, dev_id, prev_id );
if ( canAccessPeer )
cudaDeviceEnablePeerAccess( prev_id, 0 );
next_id = (dev_id + 1) % num_devs;
cudaDeviceCanAccessPeer( &canAccessPeer, dev_id, next_id );
if ( canAccessPeer )
cudaDeviceEnablePeerAccess( next_id, 0 );
}
自GPUから、別GPU(prev_id)への
P2P可否を確認
自GPUを選択(dev_id)
自GPUから、別GPU(prev_id)への
P2Pを可能に
![Page 21: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/21.jpg)
21
P2PメモリコピーをEnabledNVVP Timeline
MemCpy(PtoP)
が使われている
![Page 22: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/22.jpg)
22
マルチGPU (シングルスレッド)DGX-1V, 1000反復
並列化効率が改善
![Page 23: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/23.jpg)
23
NVLINKは使われているのか?
GPU0 GPU1 GPU5 GPU4
GPU2 GPU3 GPU7 GPU6
GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 GPU6 GPU7
NVLINK接続形態
ヤコビ反復法の通信
NVLINKにルーティング機能は無い
直接接続ではないGPU間のデータコピーに、NVLINKは使用されない
![Page 24: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/24.jpg)
24
NVLINKは使われているのか?
GPU0 GPU1 GPU5 GPU4
GPU2 GPU3 GPU7 GPU6
GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 GPU6 GPU7
NVLINK接続形態
ヤコビ反復法の通信
GPU3とGPU4、GPU0とGPU7、ここにはPCIが使われる
![Page 25: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/25.jpg)
25
GPU AFFINITY
GPU0 GPU1 GPU5 GPU4
GPU2 GPU3 GPU7 GPU6
GPU0 GPU2 GPU3 GPU1 GPU5 GPU7 GPU6 GPU4
export CUDA_VISIBLE_DEVICES=“0,2,3,1,5,7,6,4”
NVLINK接続形態
ヤコビ反復法の通信
CUDA_VISIBLE_DEVICES
• そのプロセスが認識できるGPU、その順番を設定可能
![Page 26: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/26.jpg)
26
マルチGPU (シングル・スレッド)DGX-1V, 1000反復
並列化効率が若干改善
![Page 27: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/27.jpg)
27
マルチGPU (シングル・スレッド + P2Pコピー)NVVP Timeline
GPUの選択・切り替えに時間がかかっている?
![Page 28: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/28.jpg)
28
マルチ・スレッドによるマルチGPU使用
![Page 29: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/29.jpg)
29
マルチ・スレッドによる、マルチGPU活用OpenMP
num_devs = 0;
cudaGetDeviceCount( &num_devs );
#pragma omp parallel num_threads( num_devs )
{
dev_id = omp_get_thread_num();
cudaSetDevice( dev_id );
...
}
マルチスレッド区間
スレッド番号の取得
スレッド数の指定
GPU数の取得
![Page 30: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/30.jpg)
30
シングル・スレッドwhile ( error > tol ) {
for ( dev_id = 0; dev_id < num_devs; dev_id++ ) {
cudaSetDevice( dev_id );
cudaMemsetAsync( error_d[dev_id], 0, … );
kern_jacobi<<<blocks, threads, …>>>( a_new[dev_id], a[dev_id], error_d[dev_id],
nx, iy_start[dev_id], iy_end[dev_id] );
cudaMemcpyAsync( error_h[dev_id], error_d[dev_id], … );
prev_id = (dev_id – 1) % num_devs;
cudaMemcpyAsync( a_new[prev_id] + iy_end[prev_id]*nx,
a_new[dev_id] + iy_start[dev_id]*nx, … );
next_id = (dev_id + 1) % num_devs;
cudaMemcpyAsync( a_new[next_id],
a_new[dev_id] + (iy_end[dev_id]-1)*nx, … );
}
error = 0.0;
for ( dev_id = 0; dev_id < num_devs; dev_id++ ) {
cudaSetDevice( dev_id ); cudaDeviceSynchronize();
error = max(error, *(error_h[dev_id]));
swap( a_new[dev_id], a[dev_id] );
}
}
複数GPU、それぞれに指示cudaSetDeviceでGPU指定
GPUカーネル実行非同期API使用、
ここで待たないようにする
通信
最大誤差をCPUに回収
各GPUの処理完了を待つcudaDeviceSynchronize
![Page 31: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/31.jpg)
31
マルチ・スレッド (OPENMP)while ( error > tol ) {
error = 0.0
#pragma omp parallel num_threads(num_devs) reduction(max:error)
{
dev_id = omp_get_thread_num();
cudaSetDevice( dev_id );
cudaMemsetAsync( error_d[dev_id], 0, … );
kern_jacobi<<<blocks, threads, …>>>( a_new[dev_id], a[dev_id], error_d[dev_id],
nx, iy_start[dev_id], iy_end[dev_id] );
cudaMemcpyAsync( error_h[dev_id], error_d[dev_id], … );
prev_id = (dev_id – 1) % num_devs;
cudaMemcpyPeerAsync( a_new[prev_id] + iy_end[prev_id]*nx,
a_new[dev_id] + iy_start[dev_id]*nx, … );
next_id = (dev_id + 1) % num_devs;
cudaMemcpyPeerAsync( a_new[next_id],
a_new[dev_id] + (iy_end[dev_id]-1)*nx, … );
cudaDeviceSynchronize();
error = max(error, *(error_h[dev_id]));
swap( a_new[dev_id], a[dev_id] );
}
}
GPUカーネル実行非同期API使用、
ここで待たないようにする
通信
最大誤差をCPUに回収
スレッド間の最大誤差の縮約
![Page 32: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/32.jpg)
32
マルチ・スレッド + P2PコピーNVVP Timeline
全GPUのカーネル開始時刻がほぼ
同じ
![Page 33: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/33.jpg)
33
マルチ・スレッド + P2PコピーDGX-1V, 1000反復
並列化効率がかなり改善
![Page 34: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/34.jpg)
34
スレッドは、どのCPU上にいるの?
GPU0 GPU1 GPU5 GPU4
GPU2 GPU3 GPU7 GPU6
T0 T1 T2 T3 T4 T5 T6 T7
CPU
0-19
CPU
20-39
![Page 35: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/35.jpg)
35
GPU/CPU AFFINITYnvidia-smi topo -m
![Page 36: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/36.jpg)
36
GPU/CPU AFFINITY
GPU0 GPU1 GPU5 GPU4
GPU2 GPU3 GPU7 GPU6
T0 T1 T2 T3 T4 T5 T6 T7
CPU
0-19
CPU
20-39
export CUDA_VISIBLE_DEVICES=“0,2,3,1,5,7,6,4”
export OMP_PROC_BIND=TRUE
export OMP_PLACES=“{0},{1},{2},{3},{20},{21},{22},{23}”
![Page 37: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/37.jpg)
37
マルチスレッド + P2PコピーDGX-1V, 1000反復
並列化効率は微妙に改善
![Page 38: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/38.jpg)
38
マルチスレッド + P2PコピーNVVP Timeline
計算と通信は順番に実行する必要が
あるのか?
計算
通信
![Page 39: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/39.jpg)
39
計算と通信のオーバーラップ通信が必要な、境界部分の計算を、先にする
計算(全て) 通信
計算(内部)
計算(境界) 通信
時間
計算と通信を順番に実行
オーバーラップ実行 時間短縮
依存関係
依存関係
![Page 40: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/40.jpg)
40
計算と通信のオーバーラップCUDAストリームで、実行順序を制御
// (内部計算)
kern_jacobi<<<blocks, threads, 0, stream_comp>>>(
a_new[dev_id], a[dev_id], error_d[dev_id], nx, iy_start[dev_id]+1, iy_end[dev_id]-1 );
// (境界計算)
kern_jacobi<<<blocks, threads, 0, stream_prev>>>(
a_new[dev_id], a[dev_id], error_d[dev_id], nx, iy_start[dev_id], iy_start[dev_id]+1 );
kern_jacobi<<<blocks, threads, 0, stream_next>>>(
a_new[dev_id], a[dev_id], error_d[dev_id], nx, iy_end[dev_id]-1, iy_end[dev_id] );
// (通信)
cudaMemcpyPeerAsync( a_new[prev_id] + iy_end[prev_id]*nx,
a_new[dev_id] + iy_start[dev_id]*nx, …, stream_prev );
cudaMemcpyPeerAsync( a_new[next_id],
a_new[dev_id] + (iy_end[dev_id]-1)*nx, …, stream_next );
内部と境界部を、別カーネルで計算
CUDAストリームで依存性を記述
![Page 41: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/41.jpg)
41
計算と通信のオーバーラップPriority CUDAストリーム
cudaDeviceGetStreamPriorityRange( &low_priority, &high_priority );
cudaStreamCreateWithPriority( &stream_comp, ..., low_priority );
cudaStreamCreateWithPriority( &stream_prev, ..., high_priority );
cudaStreamCreateWithPriority( &stream_next, ..., high_priority );
Priorityの高いCUDAストリームに投入されたカーネルは、優先的に実行される
境界領域の計算に、Priorityの高いCUDAストリームを使用
![Page 42: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/42.jpg)
42
マルチ・スレッド + 計算・通信オーバーラップNVVP Timeline
GPUカーネル実行中(計算中)に、通信が行われている
![Page 43: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/43.jpg)
43
マルチ・スレッド + 計算・通信オーバーラップDGX-1V, 1000反復
並列化効率はかなり改善
![Page 44: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/44.jpg)
45
明示的な通信は必要なのか通信(memcpy)はCPUが起動
計算(全て) 通信
計算(内部)
計算(境界) 通信
時間
順番に実行
オーバーラップ実行 時間短縮
![Page 45: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/45.jpg)
46
P2PアクセスGPUカーネルから、隣接GPUメモリに直接アクセス
時間
GPU N
GPU N-1
GPU N+1
境界(下) 境界(上)
境界(下) 境界(上)
境界(下) 境界(上)
![Page 46: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/46.jpg)
47
GPUカーネル
__global__ void kern_jacobi( ... ) {
int ix = ...;
int iy = ...;
if ( out of range ) return;
new_val = 0.25 * ( a[ ix + (iy-1)*nx ] + a[ ix + (iy+1)*nx ]
+ a[ (ix-1) + iy*nx ] + a[ (ix+1) + iy*nx ] );
a_new[ ix + iy*nx ] = new_val
my_error = fabs( new_val – a[ ix + iy*nx ] );
atomicMax( error, my_error );
}
各スレッドの担当箇所を決定領域内か確認
担当要素の計算
収束条件の計算(最大差分)
計算結果をwrite
![Page 47: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/47.jpg)
48
GPUカーネル
__global__ void kern_jacobi_p2p( ... ) {
int ix = ...;
int iy = ...;
if ( out of range ) return;
new_val = 0.25 * ( a[ ix + (iy-1)*nx ] + a[ ix + (iy+1)*nx ]
+ a[ (ix-1) + iy*nx ] + a[ (ix+1) + iy*nx ] );
a_new[ ix + iy*nx ] = new_val
if ( iy == iy_start ) a_new_prev[ ix + iy_end*nx ] = new_val;
if ( iy == iy_end-1 ) a_new_next[ ix ] = new_val;
my_error = fabs( new_val – a[ ix + iy*nx ] );
atomicMax( error, my_error );
}
P2Pアクセス
各スレッドの担当箇所を決定領域内か確認
担当要素の計算
収束条件の計算(最大差分)
計算結果をwrite
隣接GPUメモリに直接書き込み
![Page 48: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/48.jpg)
49
マルチス・レッド + P2Pアクセス
while ( error > tol ) {
cudaMemsetAsync( error_d[dev_id], 0, …, stream_comp );
kern_jacobi_p2p<<<blocks, threads, …, stream_comp>>>(
a_new[dev_id], a[dev_id], error_d[dev_id],
nx, iy_start[dev_id], iy_end[dev_id],
a_new[prev_id], iy_end[prev_id],
a_new[next_id], iy_start[next_id] );
cudaMemcpyAsync( error_h[dev_id], error_d[dev_id], …, stream_comp );
cudaDeviceSynchronize();
#pragma omp barrier
(... reduce error over threads...)
}
明示的な通信は不要
P2Pアクセス用のカーネルを投入
![Page 49: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/49.jpg)
50
マルチ・スレッド + P2PアクセスDGX-1V, 1000反復
並列化効率は低下?
![Page 50: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/50.jpg)
51
マルチ・スレッド + P2PアクセスNVVP Timeline
明示的な通信は無くなった最大誤差の計算に時間がかかっている?
![Page 51: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/51.jpg)
52
マルチス・レッド + P2Pアクセス
while ( error > tol ) {
cudaMemsetAsync( error_d[dev_id], 0, …, stream_comp );
kern_jacobi_p2p<<<blocks, threads, …, stream_comp>>>(
a_new[dev_id], a[dev_id], error_d[dev_id],
nx, iy_start[dev_id], iy_end[dev_id],
a_new[prev_id], iy_end[prev_id],
a_new[next_id], iy_start[next_id] );
cudaMemcpyAsync( error_h[dev_id], error_d[dev_id], …, stream_comp );
#pragma omp barrier
(... reduce error over threads...)
}
収束判定を1サイクル遅延
GPUカーネル実行中に前サイクルの誤差を計算
![Page 52: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/52.jpg)
53
マルチ・スレッド + P2Pアクセス, 遅延判定NVVP Timeline
![Page 53: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/53.jpg)
54
マルチ・スレッド + P2Pアクセス & 遅延判定DGX-1V, 1000反復
(delayed)
並列化効率は改善
![Page 54: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/54.jpg)
55
マルチ・スレッドでマルチGPU
DGX1V: 8 GPUまでヤコビ反復法がスケールすることを確認
問題: マルチノードの用途に拡張できない
![Page 55: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/55.jpg)
56
マルチ・プロセスで、マルチGPUを活用する
![Page 56: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/56.jpg)
57
MPI (MESSAGE PASSING INTERFACE)
• プロセス並列で、最も一般的な方法 (HPCでは)
• プロセス間のデータ交換(通信)のAPIを規定
• 1対1: MPI_Send, MPI_Recv, …
• 集団: MPI_Bcast, MPI_Gather, MPI_Reduce, …
• 複数の実装、複数の言語サポート
• MPICH, MVAPICH, OpenMPI, …
• C/C++, Fortran, Python, …
![Page 57: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/57.jpg)
58
MPIプログラム
#include <mpi.h>
MPI_Init( ... );
MPI_Comm_size( MPI_COMM_WORLD, &size );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
...
(MPIでプロセス間のデータ交換)
...
MPI_Finalize( );
MPIライブラリ開始
MPIライブラリ終了
プロセス数
プロセスID
(0 … size-1)
コンパイル
$ mpicc –o myapp myapp.c
実行
$ mpirun –np 4 myapp
![Page 58: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/58.jpg)
59
MPIプログラム
コンパイル
$ mpicc –o myapp myapp.c
実行
$ mpirun –np 4 myapp
ノードA
myapp
(ランク0)
ノードB
myapp
(ランク1)
ノードC
myapp
(ランク2)
ノードD
myapp
(ランク3)
GPU GPU GPU GPU
マルチ・ノード
![Page 59: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/59.jpg)
60
MPIプログラム
コンパイル
$ mpicc –o myapp myapp.c
実行
$ mpirun –np 4 myapp
ファット・ノード
myapp
(ランク0)
myapp
(ランク1)
myapp
(ランク2)
myapp
(ランク3)
GPU0 GPU1 GPU2 GPU3
シングル・ノード
![Page 60: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/60.jpg)
61
マルチ・プロセス (MPI)cudaSetDevice( rank );
prev_rank = (rank – 1) % size;
next_rank = (rank + 1) % size;
while ( error > tol ) {
cudaMemsetAsync( error_d, 0, … );
kern_jacobi<<<blocks, threads, …>>>( a_new, a, error_d, nx, iy_start, iy_end );
cudaMemcpyAsync( error_h, error_d, … );
cudaDeviceSynchronize( );
MPI_Sendrecv( a_new + iy_start *nx, nx, MPI_FLOAT, prev_rank, ...,
a_new + iy_end *nx, nx, MPI_FLOAT, next_rank, ...,
MPI_COMM_WORLD, ... );
MPI_Sendrecv( a_new + (iy_end-1)*nx, nx, MPI_FLOAT, next_rank, ...,
a_new , nx, MPI_FLOAT, prev_rank, ...,
MPI_COMM_WORLD, ... );
error = 0.0
MPI_Allreduce( error_h, &error, 1, MPI_FLOAT, MPI_MAX, MPI_COMM_WORLD );
swap( a_new, a );
}
GPUカーネル実行
MPI通信 (後述)
プロセス間の最大誤差取得
![Page 61: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/61.jpg)
62
MPI通信: 境界交換
MPI_Sendrecv(
a_new + iy_start *nx, nx, MPI_FLOAT, prev_rank, ...,
a_new + iy_end *nx, nx, MPI_FLOAT, next_rank, ...,
MPI_COMM_WORLD, ... );
送信
受信
![Page 62: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/62.jpg)
63
MPI通信: 境界交換
MPI_Sendrecv(
a_new + iy_start *nx, nx, MPI_FLOAT, prev_rank, ...,
a_new + iy_end *nx, nx, MPI_FLOAT, next_rank, ...,
MPI_COMM_WORLD, ... );
MPI_Sendrecv(
a_new + (iy_end-1) *nx, nx, MPI_FLOAT, next_rank, ...,
a_new , nx, MPI_FLOAT, prev_rank, ...,
MPI_COMM_WORLD, ... );
送信
受信
送信
受信
![Page 63: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/63.jpg)
64
通常のMPI
2. MPI_Send( host buffer, …) 2. MPI_Recv( host buffer, …)
1. cudaMemcpy(GPU to Host)
3. cudaMemcpy(Host to Device)
通常のMPIは、GPUメモリを扱えないMPI通信の前後で、cudaMemcpyでGPU・Host間のメモリコピー
![Page 64: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/64.jpg)
65
CUDA AWARE MPI
MVAPICHとOpenMPIがサポート
• CPUとGPU間のデータコピーはMPIライブラリが実施
• GPU間でP2Pが使えるなら、直接データ転送
MPIの送信・受信バッファに、GPUメモリを指定できる
MPI_Send( device buffer, …)
MPI_Recv( device buffer, …)
P2P
![Page 65: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/65.jpg)
66
マルチ・プロセス (CUDA AWARE MPI)DGX-1V, 1000反復
![Page 66: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/66.jpg)
67
マルチ・プロセス (CUDA AWARE MPI)NVVP Timeline
![Page 67: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/67.jpg)
68
計算と通信のオーバーラップMPI + CUDAストリーム
// (内部計算)
kern_jacobi<<<..., stream_comp>>>( a_new, a, error_d, nx, iy_start+1, iy_end-1 );
// (境界計算)
kern_jacobi<<<..., stream_prev>>>( a_new, a, error_d, nx, iy_start, iy_start+1 );
kern_jacobi<<<..., stream_next>>>( a_new, a, error_d, nx, iy_end-1, iy_end );
// (境界通信)
cudaStreamSynchronize( stream_prev );
MPI_Sendrecv( a_new + iy_start *nx, nx, MPI_FLOAT, prev_rank, ...,
a_new + iy_end *nx, nx, MPI_FLOAT, next_rank, ...,
MPI_COMM_WORLD, ... );
cudaStreamSynchronize( stream_next );
MPI_Sendrecv( a_new + (iy_end-1)*nx, nx, MPI_FLOAT, next_rank, ...,
a_new , nx, MPI_FLOAT, prev_rank, ...,
MPI_COMM_WORLD, ... );
内部と境界部を、別カーネルで計算
CUDAストリームで依存性を記述
![Page 68: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/68.jpg)
69
マルチ・プロセス + 計算・通信オーバーラップNVVP Timeline
通信と計算がオーバラップ
![Page 69: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/69.jpg)
70
マルチ・プロセス + 計算・通信オーバーラップDGX-1V, 1000反復
![Page 70: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/70.jpg)
71
マルチ・プロセス
計算は、プログラミング言語 (C/C++, Fortran, Python) で記述
通信は、通信ライブラリのAPI (MPI) で記述
計算と通信は、別々に記述するしかない?
![Page 71: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/71.jpg)
72
NVSHMEM
OpenSHMEM
• 別プロセスからアクセス可能な空間
• リモートメモリにアクセスするAPI
• 単方向: shmem_put, shmem_get
• 集合: shmem_broadcast
NVSHMEMは、OpenSHMEMのGPU実装
• GPUカーネルから、リモートメモリにアクセス可能 (現在は、ノード内に限定)
• MPIとの併用可能
Partitioned Global Address Space (PGAS) ライブラリ
![Page 72: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/72.jpg)
73
NVSHMEMプログラム
#include <shmem.h>
#include <shmemx.h>
shmemx_init_attr_t attr;
attr.mpi_comm = MPI_COMM_WORLD;
shmemx_init_attr( SHMEMX_INIT_WITH_MPI_COMM, &attr );
npes = shmem_n_pes();
mype = shmem_my_pe();
...
(NVSHMEMでプロセス間のデータ交換)
...
プロセス数
プロセスID
(0 … npes-1)
![Page 73: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/73.jpg)
74
マルチ・プロセス (NVSHMEM)
cudaSetDevice( mype );
prev_pe = (mype – 1) % npes;
next_pe = (mype + 1) % npes;
a = (float*) shmem_malloc( nx * (my_ny+2) * sizeof(float) );
a_new = (float*) shmem_malloc( nx * (my_ny+2) * sizeof(float) );
while ( error > tol ) {
...
kern_jacobi<<< ..., stream >>>(
a_new, a, error_d, nx, iy_start, iy_end, ... );
shmem_barrier_all_stream( stream );
...
swap( a_new, a );
}
![Page 74: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/74.jpg)
75
GPUカーネル
__global__ void kern_jacobi( ... ) {
int ix = ...;
int iy = ...;
if ( out of range ) return;
new_val = 0.25 * ( a[ ix + (iy-1)*nx ] + a[ ix + (iy+1)*nx ]
+ a[ (ix-1) + iy*nx ] + a[ (ix+1) + iy*nx ] );
a_new[ ix + iy*nx ] = new_val;
if ( iy == iy_start )
shmem_float_p( a_new + ix + iy_end*ny, new_val, prev_pe );
if ( iy == iy_end-1 )
shmem_float_p( a_new + ix , new_val, next_pe );
my_error = fabs( new_val – a[ ix + iy*nx ] );
atomicMax( error, my_error );
}
NVSHMEM
隣接GPUメモリに直接書き込み
![Page 75: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/75.jpg)
76
マルチ・プロセス (NVSHMEM)DGX-1V, 1000反復 マルチ・スレッドと
同レベルの性能
![Page 76: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/76.jpg)
77
まとめ
データ交換(通信) P2P マルチノード
シングル・スレッド Memcpy ○ X
マルチ・スレッド Memcpy ○ X
P2Pアクセス 必須 X
マルチ・プロセス MPI ○ 可能
NVSHMEM 必須 可能(*)
(*) 現時点ではNVSHMEMはノード内限定
![Page 77: GPU HOT TIPS: マルチGPUでプロ グラムを加速す …4 マルチGPU • シングルGPUでは時間のかかる問題を、もっと短い時間で解きたい • DLトレーニング、リアルタイム処理](https://reader034.vdocuments.site/reader034/viewer/2022042319/5f0893cc7e708231d422b2d3/html5/thumbnails/77.jpg)