pragma acc loop copyin(src[0:N])

大規模データをパイプライン処理するためのディレクティブとそのトランスレータ
伊野文彦,中野瑛仁, 萩原兼一
大阪大学大学院情報科学研究科
ino@ist.osaka-u.ac.jp
5. PACCの記述例
1. 背景
• アクセラレータ(GPUやXeon Phiなど)の出現
• 3点ステンシル
– 主記憶から独立したメモリ空間
– 高速だが小さなメモリ容量
– 固有のプログラミング言語や最適化手法が必要
#pragma pacc pipeline targetin(src(0,N,0)[N:N*N-2*N]) ¥¥
targetout(dst(0,N,0)[N:N*N-2*N]) 袖領域の大きさ(左右別々に指定)
{
#pragma pacc update device(src[N:N*N-2*N])
#pragma pacc parallel loop dim(1)
直下のループ文を
for (y=1; y<N-1; y++) {
配列次元と関連付け
for (x=1; x<N-1; x++) {
N
dst[y*N+x] = src[y*N+x-1] + src[y*N+x+1];
}
}
#pragma pacc update host(dst[N:N*N-2*N])
}
• 科学計算プログラムの移植に伴う性能最適化のコストが大きい
• 複数の計算機システムで高い実効性能を達成できる性質
(性能可搬性)が求められている
コンパイラへのディレクティブによるプログラミング
2. 動機
• CPUで扱えていたサイズの問題をアクセラレータで解くために
逐次コードを書き直す必要がある
• 評価アプリケーション[2]
– Black Scholes
証券などのオプション価格を算出
– Sobel Filter
画像の輪郭を抽出するフィルタ
dst[i] = src[i-1]+src[i+1];
for (j=0;i<N/chunk;j++)
#pragma acc loop copyin(src[chunk*j:min(chunk,¥
N-chunk*j)])copyout(chunk*j:min(chunk,N-chunk*j)])
for (i=1; i<min(chunk,N-chunk*j)-1; i++) {
Black Scholes
dst[chunk*j+i] = src[chunk*j+i-1]+src[chunk*j+i+1];
9
5
4
dst[i] = src[i-1]+src[i+1];
入力
C++
frontend
ROSE
24
4
18
20
データサイズ(GB)および実装
OpenACC
PACC (no pipe)
OpenACC
PACC (no pipe)
OpenACC
0
30
3
PACC (no pipe)
20
0
バッファコピー
ダウンロード
カーネル
リードバック
メモリ確保
その他
6
30
6
10
9
8
7
6
5
4
3
2
1
0
12
18
データサイズ(GB)
24
30
バッファコピー
ダウンロード
カーネル
リードバック
メモリ確保
その他
2
OpenACC
12
18
データサイズ(GB)
40
PACC (no pipe)
6
OpenACC (orig)
10
ビデオメモリ不足
0
PACC (pipe)
50
OpenACC
2
PACC (no pipe)
Rewrite rules for PACC
バッファの用意,ループ構造や参照先の書き換え
実行コード
4
PACC (no pipe)
4
18
20
データサイズ(GB)および実装
7. まとめ
変換:PACC → OpenACC
コンパイル
6
2
• OpenACCコンパイラが実行コードを生成
Pipelined OpenACC code
8
実行時間(秒)
 配列の分割
 ループ構造の書き換え
 OpenACCディレクティブの挿入
出力
10
0
• トランスレータがPACCコードをOpenACCコードに変換
For (x=1; x<nChunks+1; x++)
#pragma acc …
for (y=1; y<chunk-1; y++) {
tmp_dst[x][y] = tmp_src[x][y-1]
+ tmp_src[x][y+1];
}
OpenACC (orig)
60
1
– パイプライン化に必要な情報を指示
PACC code
12
OpenMP (12 threads)
2
• 開発者がPACCディレクティブを逐次コードに挿入
}
PACC (pipe)
7
4. PACC: Pipelined ACCelerator
for (i=1; i<N-1; i++) {
14
8
– メモリに格納できる大きさにデータを分割
– パイプライン処理による高速化
{
16
PACC (no pipe)
0
• 手段:ディレクティブ拡張PACC(Pipelined ACCelerator)とその
source-to-sourceトランスレータ
#pragma pacc parallel …
OpenMP (12 threads)
PACC (no pipe)
– 対象をパイプライン処理できるものに限定
18
実行時間(秒)
• 目的:アクセラレータ上でメモリ不足に陥る計算をディレクティブの
追加だけで高速処理したい
70
実行時間(秒)
3. 目的
実行時間(秒)
性能可搬性の低下
}
Sobel Filter
20
}
OpenACC
書き換え
OpenACC
}
PACC (no pipe)
}
– Windows 7 64bit
– Intel Core i7 3930K (6 cores, 32 GB)
– NVIDIA Tesla K20 (5 GB)
– PGI compiler 14.4, CUDA 6.0
OpenACC
• srcとdstの型が4バイトとするとN=1Gで8GBのメモリが必要
• アクセラレータはメモリ不足で実行不可
• 実験環境
PACC (no pipe)
#pragma acc loop copyin(src[0:N]) copyout(dst[1:N-2])
for (i=1; i<N-1; i++) {
N
6. 評価実験
– 原因:アクセラレータのメモリは主記憶よりも小さい
{
反復1回あたりの参照領域の大きさ
(袖領域を除く)
中間
表現
Unparser
• 逐次プログラムの構造を変えることなく,ビデオメモリ容量を
超える大規模データのパイプライン処理を実現
• 主記憶に乗り切る程度のデータを処理可能
• OpenMP版と比べて3~5倍の高速化
• 重い演算を伴うステンシル計算に有効
抽象構文木
• ROSEフレームワーク[1]による変換
– 抽象構文木の構築
– 変数の型やスコープの解析
– 再帰下降構文解析器を作るための雛形
[1] http://rosecompiler.org/
[2] http://www.caps-entreprise.com/resources-and-support/openacc-examples/
This study was partly supported by the JST CREST program “An Evolutionary Approach
to Construction of a Software Development Environment for Massively-Parallel
Computing Systems.”