SlideShare uma empresa Scribd logo
1 de 37
Baixar para ler offline
CUDAのアセンブリ言語
基礎のまとめ
PTXとSASSの概説
高度情報科学技術研究機構
山岸孝輝
2019-08-01
ver.1.2 1
CUDAのアセンブリ言語
相当するものは2つ
PTX:コンパイル時の中間コード
SASS:いわゆるアセンブリ
特徴
PTX:マニュアル充実/比較的読みやすい/実行
の挙動を完全には押さえていない
SASS:情報少ない/それ故読みがたい/正確に
追える
今回はPTXを中心として一部SASSにも触れ
る
ver.1.2 2
Compute Capability
が異なる実行環境にて
JITコンパイルに対応
させる手段
実行形式に一緒に組み
込んでおくことが可能
どういうときに役立つのか
想定している最適化や機能活用を確認出来る
冗長な処理の有無
効率的な命令(FMA等)の利用(--use_fast_math)
テクスチャ(リードオンリーデータ)キャッシュの利用
ループアンローリング、関数のインライン展開
ハード資源の消費を確認
レジスタ使用量とレジスタスピル
命令レベルの並列性・パイプライン処理
連続する命令間での依存性の有無
詳細なホットスポット特定とデバッグ(GUI利用)
PTXやSASS上でのコスト分布をGUIで表示
PTXやSASS上で実行をGUIで追跡可能
PTXはインラインで組み込める
柔軟なコーディングが可能
ver.1.2 3
まずは出力してみましょう
やり方は2つ
実行前と実行後
実行前に出力
PTX:コンパイル時にオプション指定
SASS:実行形式に専用ツールを適用
実行後にプロファイラ結果として出力
コードの行情報やコスト分布との対応がとれる
(GUI活用)
ver.1.2 4
出力例(実行前)
PTX出力(実行形式は作成されない)
SASS出力
PTXに補助情報を追加して出力
ver.1.2 5
$nvcc –ptx –arch sm_60 axpy.cu
$nvcc –cubin –arch sm_60 axpy.cu
$cuobjdump –sass axpy.cubin > axpy.sass
$nvcc –lineinfo –src–in–ptx –ptx –arch
sm_60 axpy.cu
GPUカーネル
ver.1.2 6
__global__ void axpy(double *y){
int i = threadIdx.x;
double a;
a = 8.0;
y[i] = y[i] + a;
}
簡単な例でまずは読んでみましょう
apyであることは仕様です
PTXの基本
命令と指示行(.で始まる)で構成される
命令の基本形とその例
指示行はレジスタの確保やヘッダ情報な
どを示している
ver.1.2 7
命令.型名 レジスタ, レジスタ/即値;
add.f64 %fd2, %fd1, 0d4020000000000000;
.reg レジスタの確保
.version PTXのversion
.visible 関数のスコープ
命令.オプション.型名 レジスタ, レジスタ/即値, レジスタ/即値;
詳細はNVIDIAのPTXマ
ニュアルを参照
PTX(関数全体)
ver.1.2 8
01 .version 6.0
02 .target sm_60
03 .address_size 64
04
05 // .globl _Z4axpyPd
06
07 .visible .entry _Z4axpyPd(
08 .param .u64 _Z4axpyPd_param_0
08 )
09 {
10 .reg .b32 %r<2>;
11 .reg .f64 %fd<3>;
12 .reg .b64 %rd<5>;
13
14
15 ld.param.u64 %rd1, [_Z4axpyPd_param_0];
16 cvta.to.global.u64 %rd2, %rd1;
17 mov.u32 %r1, %tid.x;
18 mul.wide.s32 %rd3, %r1, 8;
19 add.s64 %rd4, %rd2, %rd3;
20 ld.global.f64 %fd1, [%rd4];
21 add.f64 %fd2, %fd1, 0d4020000000000000;
22 st.global.f64 [%rd4], %fd2;
23 ret;
24 }
01-03 ヘッダ
07-08 関数のインターフェース部
.visible スコープ(global)
.entry 関数の開始
.param 引数
.u64 unsigned int 64bit
_Z4axpyPd_param_0 引数ポインタ
10-12 レジスタ
.b32 untyped 32bit r1,r2
.f64 float 64bit fd1,,fd3
.b64 untyped 64bit rd1,,rd5
15-23(関数本体)は
次スライドで詳しく
PTX(関数本体)
ver.1.2 9
15 ld.param.u64 %rd1, [_Z4axpyPd_param_0];
16 cvta.to.global.u64 %rd2, %rd1;
17 mov.u32 %r1, %tid.x;
18 mul.wide.s32 %rd3, %r1, 8;
19 add.s64 %rd4, %rd2, %rd3;
20 ld.global.f64 %fd1, [%rd4];
21 add.f64 %fd2, %fd1, 0d4020000000000000;
22 st.global.f64 [%rd4], %fd2;
23 ret;
__global__ void axpy(double *y){
int i = threadIdx.x;
double a;
a = 8.0;
y[i] = y[i] + a;
}
15 引数の先頭アドレスをレジスタrd1に
ロード、符号無し64bit
16 rd1をrd2(グローバルメモリ上のアド
レス)に変換
17 スレッドidをr1にコピー、符号無し
32bit
18 r1と8(倍精度なので8バイト刻み)の
積をrd3に代入 64bit(wide)で確保
19 rd2にrd3を加えてrd4に代入(各スレッ
ドが担当するデータのアドレス)
20 rd4が指すデータをfd1(グローバルメ
モリ)にロード、64bit浮動小数点
21 fd1に8.0d0を加えてfd2に代入
22 fd2をrd4が指すデータに代入
23 関数戻り
補助情報を出した場合
ver.1.2 10
.version 6.0
…
.visible .entry _Z4axpyPd(
.param .u64 _Z4axpyPd_param_0
)
{
…
ld.param.u64 %rd1, [_Z4axpyPd_param_0];
///home/takateru.yamagishi/00CUDA/06mcBMT/axpy/CUDAC/axpy.CC.a01.cu:10 int i = threadIdx.x;
.loc 1 10 9
cvta.to.global.u64 %rd2, %rd1;
mov.u32 %r1, %tid.x;
///home/takateru.yamagishi/00CUDA/06mcBMT/axpy/CUDAC/axpy.CC.a01.cu:14 y[i] = y[i] + a;
.loc 1 14 3
mul.wide.s32 %rd3, %r1, 8;
…
st.global.f64 [%rd4], %fd2;
///home/takateru.yamagishi/00CUDA/06mcBMT/axpy/CUDAC/axpy.CC.a01.cu:16 }
.loc 1 16 1
ret;
}
.file 1 "/home/takateru.yamagishi/00CUDA/06mcBMT/axpy/CUDAC/axpy.CC.a01.cu", 1538446405, 895
.file 2 "/opt/cuda/9.0/bin/..//include/cuda_device_runtime_api.h", 1522911204, 14588
.file 3 "/opt/cuda/9.0/bin/..//include/cuda_runtime.h", 1522911204, 88442
loc指示行はファイル関連情
報を示している
.loc 1 10 9
File 1の10行目の9列目
IF文を含むカーネル
ver.1.2 11
__global__ void axpy(double *y){
int i = threadIdx.x;
double a;
a = 8.0;
if( y[i] > 0 ){
y[i] = y[i] + a;
}
else{
y[i] = 0;
}
}
IF文を含むカーネル(PTX)
ver.1.2 12
01 .reg .pred %p<2>;
02 .reg .b32 %r<2>;
03 .reg .f64 %fd<4>;
04 .reg .b64 %rd<5>;
05 ld.param.u64 %rd1, [_Z4axpyPd_param_0];
06 cvta.to.global.u64 %rd2, %rd1;
07 mov.u32 %r1, %tid.x;
08 mul.wide.s32 %rd3, %r1, 8;
09 add.s64 %rd4, %rd2, %rd3;
10 ld.global.f64 %fd1, [%rd4];
11 setp.gt.f64 %p1, %fd1, 0d0000000000000000;
12 add.f64 %fd2, %fd1, 0d4020000000000000;
13 selp.f64 %fd3, %fd2, 0d0000000000000000, %p1;
14 st.global.f64 [%rd4], %fd3;
15 ret;
01 predicate(bool)レジスタ p1, p2
02 untyped32bitレジスタ r1, r2
03 float64bitレジスタ fd1-fd4
04 untyped64bitレジスタ rd1-rd5
05 引数の先頭アドレスをレジスタrd1に
ロード、符号無し64bit
06 rd1をrd2(グローバルメモリ上のアド
レス)に変換
07 スレッドidをr1にコピー、符号無し
32bit
08 r1の8(倍精度なので8バイト刻み)の
積をrd3に代入 64bit(wide)で確保
09 rd2にrd3を加えてrd4に代入(各ス
レッドが担当するデータのアドレス)
10 rd4が指すデータをfd1(グローバルメ
モリ)にロード、64bit浮動小数点
11 p1 = (fd1 > 0d0)
12 fd1に8.0d0を加えてfd2に代入
13 fd3 = p1 ? fd2 : 0d0
14 fd3をrd4が指すデータに代入
15 関数戻り
forループを含むカーネル 1
ver.1.2 13
__global__ void axpy(double *y)
{
int i = threadIdx.x;
double a;
a = 8.0;
int NN = 100;
for(int ii=0; ii<NN; ii++)
{
y[i] = y[i] + a;
}
}
.reg .b32 %r<2>;
.reg .f64 %fd<102>;
.reg .b64 %rd<5>;
ld.param.u64 %rd1, [_Z4axpyPd_param_0];
cvta.to.global.u64 %rd2, %rd1;
mov.u32 %r1, %tid.x;
mul.wide.s32 %rd3, %r1, 8;
add.s64 %rd4, %rd2, %rd3;
ld.global.f64 %fd1, [%rd4];
add.f64 %fd2, %fd1, 0d4020000000000000;
add.f64 %fd3, %fd2, 0d4020000000000000;
add.f64 %fd4, %fd3, 0d4020000000000000;
add.f64 %fd5, %fd4, 0d4020000000000000;
add.f64 %fd6, %fd5, 0d4020000000000000;
add.f64 %fd7, %fd6, 0d4020000000000000;
add.f64 %fd8, %fd7, 0d4020000000000000;
add.f64 %fd9, %fd8, 0d4020000000000000;
…
add.f64 %fd97, %fd96, 0d4020000000000000;
add.f64 %fd98, %fd97, 0d4020000000000000;
add.f64 %fd99, %fd98, 0d4020000000000000;
add.f64 %fd100, %fd99, 0d4020000000000000;
add.f64 %fd101, %fd100, 0d4020000000000000;
st.global.f64 [%rd4], %fd101;
ret;
}
ループ展開されていた
ループの回転数が固定の場合
forループを含むカーネル 2
ver.1.2 14
__global__ void axpy(double *y,
int NN)
{
int i = threadIdx.x;
double a;
a = 8.0;
// int NN = 100;
for(int ii=0; ii<NN; ii++)
{
y[i] = y[i] + a;
}
}
.reg .pred %p<7>;
.reg .b32 %r<18>;
.reg .f64 %fd<22>;
.reg .b64 %rd<5>;
ld.param.u64 %rd2, [_Z4axpyPdi_param_0];
ld.param.u32 %r7, [_Z4axpyPdi_param_1];
setp.lt.s32 %p1, %r7, 1;
@%p1 bra BB0_12;
-------------------------中略-------------------------------
BB0_10:
add.f64 %fd13, %fd21, 0d4020000000000000;
add.f64 %fd14, %fd13, 0d4020000000000000;
add.f64 %fd15, %fd14, 0d4020000000000000;
add.f64 %fd21, %fd15, 0d4020000000000000;
add.s32 %r17, %r17, 4;
setp.lt.s32 %p6, %r17, %r7;
@%p6 bra BB0_10;
BB0_11:
st.global.f64 [%rd1], %fd21;
BB0_12:
ret;
}
ループの回転数は動的に決定
回転数は動的なのでループ
展開は無し
プレディケード
レジスタの用意
• プレディケードレジスタを
基にラベルへのjump命令
• bra命令はレベルにジャンプ
して(PCをそこに移して)
実行を継続する命令となる
PTXの構文の基本
フォーマット
ASCII
改行で区切り
区切り以外の空白は無視
#でCプリプロセッサを扱う
大文字小文字を区別 小文字を利用
.versionと.targetディレクティブで始まる
詳しくはNVIDIAのマニュアルを参照
ver.1.2 15
実例を読んだ上で基本をまとめる
PTXの構文の基本(続き)
コメント
C/C++と同じ
記法
ラベル(オプション)で始まりセミコロンまで
識別子
C/C++とほぼ同じ扱い
定数も扱える
int, float, boolの型が可能
ver.1.2 16
[ラベル] [@p] 命令[.オプション.型名] [レジスタ] [レジスタ/即値,] [レジスタ/即値,]..;
指示行に使う指示子
ver.1.2 17
.reg レジスタの確保 .param 関数の引数
.version PTXのversion
.extern/visible/weak 関数のスコープ
NVIDIA公式マニュアルから引用
PTXは命令と指示行(以下の指示子で始まる)で構成される
これらの中には先頭以外で使われるものもある
命令
ver.1.2 18
[ラベル] [@p] 命令[.オプション.型名] [レジスタ] [レジスタ/即値,] [レジスタ/即値,]..
NVIDIA公式マニュアルから引用
State Spaces
データが存在する場所を明示する必要
ver.1.2 19
指示行の先頭に使われる、または命令のオプションとして使われる場合も
NVIDIA公式マニュアルから引用
Types(型)
型を明示する
ver.1.2 20
指示行または命令のオプションとして使われる
NVIDIA公式マニュアルから引用
Variables
普通に(識別子はC/C++とほぼ同じ)宣言
可能
Vector(2 or 4)
Arrayの宣言と初期化
ver.1.2 21
NVIDIA公式マニュアルから引用
CUDA CとCUDA Fortran
この二つの違いはPTXよりも上位
CUDA FortranからCUDA Cライクに変換された後は基本違
いなし(その後は共にnvccでコンパイルされる)
CUDA Fortranの方が冗長な処理が入っていることも
特に配列のidexとか
余計なコストになるかもしれないが今回は評価していない
今回扱うような簡単なケースではPTXにそれほど大きな違い
は無かった
関連論文
Satake et al. (2012)
熱伝導方程式の最適化 CUDA CとCUDA FのPTX比較も通じて
2012年の結果故最新のコンパイラにはそのままは当てはまらない
可能性あり
重要なことは違いが起こりうることを知っておくこと
評価が重要でそのためのアセンブリ言語基礎
ver.1.2 22
比較コード
ver.1.2 23
__global__ void axpy(double *y){
int i = threadIdx.x;
double a;
a = 8.0;
y[i] = y[i] + a;
}
attributes(global) SUBROUTINE axpy(y)
REAL(8), device :: y(N)
REAL(8) :: a
INTEGER :: i
i = threadidx%x
a = 8d0
y(i) = y(i) + a
END SUBROUTINE axpy
PTXの比較
ver.1.2 24
.version 6.0
.target sm_60
.address_size 64
// .globl _Z4axpyPd
.visible .entry _Z4axpyPd(
.param .u64 _Z4axpyPd_param_0
)
{
.reg .b32 %r<2>;
.reg .f64 %fd<3>;
.reg .b64 %rd<5>;
ld.param.u64 %rd1, [_Z4axpyPd_param_0];
cvta.to.global.u64 %rd2, %rd1;
mov.u32 %r1, %tid.x;
mul.wide.s32 %rd3, %r1, 8;
add.s64 %rd4, %rd2, %rd3;
ld.global.f64 %fd1, [%rd4];
add.f64 %fd2, %fd1, 0d4020000000000000;
st.global.f64 [%rd4], %fd2;
ret;
}
.version 6.0
.target sm_60
.address_size 64
// .globl sub_axpy_
.visible .entry sub_axpy_(
.param .u64 sub_axpy__param_0
)
{
.reg .b32 %r<3>;
.reg .f64 %fd<3>;
.reg .b64 %rd<5>;
ld.param.u64 %rd1, [sub_axpy__param_0];
mov.u32 %r1, %tid.x;
shl.b32 %r2, %r1, 3;
cvt.s64.s32 %rd2, %r2;
cvta.to.global.u64 %rd3, %rd1;
add.s64 %rd4, %rd3, %rd2;
ld.global.f64 %fd1, [%rd4];
add.f64 %fd2, %fd1, 0d4020000000000000;
st.global.f64 [%rd4], %fd2;
ret;
}
CUDA C CUDA Fortran
SASS
PTXよりもさらに低級
ドキュメント少ない
4ページほどの命令セット説明tableのみ公開
PTXと一般的なアセンブリ言語の知識を組み合
わせて解読するものでいくらかの経験必要
出力方法例(再掲)
ver.1.2 25
$nvcc –cubin –arch sm_60 axpy.cu
$cuobjdump –sass axpy.cubin > axpy.sass
SASSの例
ver.1.2 26
code for sm_60
Function : _Z4axpyPd
.headerflags @"EF_CUDA_SM60 EF_CUDA_PTX_SM(EF_CUDA_SM60)"
/* 0x083fc400e3e007f6 */
/*0008*/ MOV R1, c[0x0][0x20]; /* 0x4c98078000870001 */
/*0010*/ S2R R0, SR_TID.X; /* 0xf0c8000002170000 */
/*0018*/ ISCADD R2.CC, R0.reuse, c[0x0][0x140], 0x3; /* 0x4c18818005070002 */
/* 0x001dc800fc4007ec */
/*0028*/ SHR R0, R0, 0x1d; /* 0x3829000001d70000 */
/*0030*/ IADD.X R3, R0, c[0x0][0x144]; /* 0x4c10080005170003 */
/*0038*/ LDG.E.64 R4, [R2]; /* 0xeed5200000070204 */
/* 0x001f98011e204714 */
/*0048*/ DADD R4, R4, 8; /* 0x3870004020070404 */
/*0050*/ STG.E.64 [R2], R4; /* 0xeedd200000070204 */
/*0058*/ NOP; /* 0x50b0000000070f00 */
/* 0x001f8000ffe007ff */
/*0068*/ EXIT; /* 0xe30000000007000f */
/*0070*/ BRA 0x70; /* 0xe2400fffff87000f */
/*0078*/ NOP; /* 0x50b0000000070f00 */
前掲のPTX出力例と比較
SASSの例
ver.1.2 27
code for sm_60
Function : _Z4axpyPd
.headerflags @"EF_CUDA_SM60 EF_CUDA_PTX_SM(EF_CUDA_SM60)"
/* 0x083fc400e3e007f6 */
/*0008*/ MOV R1, c[0x0][0x20]; /* 0x4c98078000870001 */
/*0010*/ S2R R0, SR_TID.X; /* 0xf0c8000002170000 */
/*0018*/ ISCADD R2.CC, R0.reuse, c[0x0][0x140], 0x3; /* 0x4c18818005070002 */
/* 0x001dc800fc4007ec */
/*0028*/ SHR R0, R0, 0x1d; /* 0x3829000001d70000 */
/*0030*/ IADD.X R3, R0, c[0x0][0x144]; /* 0x4c10080005170003 */
/*0038*/ LDG.E.64 R4, [R2]; /* 0xeed5200000070204 */
/* 0x001f98011e204714 */
/*0048*/ DADD R4, R4, 8; /* 0x3870004020070404 */
/*0050*/ STG.E.64 [R2], R4; /* 0xeedd200000070204 */
/*0058*/ NOP; /* 0x50b0000000070f00 */
/* 0x001f8000ffe007ff */
/*0068*/ EXIT; /* 0xe30000000007000f */
/*0070*/ BRA 0x70; /* 0xe2400fffff87000f */
/*0078*/ NOP; /* 0x50b0000000070f00 */
MOV: Move
S2R: Move Special
Register to Register
ISCADD: Scaled Integer
Addition
SHR: Shift Right
IADD: Integer Addition
LDG: Load from Global
Memory
DADD: FP64 Add
STG: Store to Global
Memory
前掲のPTX出力例と比較
SASSの活用
現実的にはPTXと併せて活用するのがよい
かもしれない
まずはPTXで、追い切れないときはSASS
そもそも併用しないとSASSを解読し難い
ある程度読めるようになると、GUI上での
分析で使えると思います
ver.1.2 28
GUIでのSASS活用例 2つ
NVVPでcodeとSASS
を並べて分析可能
行単位でコストと
SASSを併記して表示
ver.1.2 29
https://devblogs.nvidia.com/cuda-pro-tip-view-
assembly-code-correlation-nsight-visual-studio-
edition/
https://devblogs.nvidia.com/cuda-pro-tip-
view-assembly-code-correlation-nsight-visual-
studio-edition/
SASS分析によりローカルメモリへのデー
タ退避と同期がコスト増加原因と特定
原因特定の確度を高めることが可能
詳細は引用元をご参照ください
PTX・SASSの活用例
FMA利用の確認など(from CUDA Fortran for Scientists and Engineers)
#pragma unrollの問題(三木洋平, 2015)
PTXでは入っているがSASSでは消えた
手で展開したそうです
レジスタスピルの改善
本気で追い込むにはSASSじゃないとダメらしい
ver.1.2 30
attributes(global) subroutine k(a,b,c)
implicit none
real :: a, b, c
c = a*b+c
end subroutine k
fma.rn.f32 %f4, %f2, %f3, %f1;
mul.rn.f32 %f4, %f2, %f3;
add.f32 %f5, %f1, %f4;
-Mcuda=nofma指定時
テクスチャキャッシュの利用
読み込みのみの変数はテクスチャメモリに配
置してテクスチャキャッシュ(リードオン
リーデータキャッシュ)を利用すると良い場
合もある
レイテンシが通常のグローバルメモリよりも大き
いので、十分な並列性が無い場合は使用しない方
が良い
NVVPのレイテンシ解析でテクスチャに起因するレ
イテンシが多くカウントされる場合などは注意し
た方がよい
CUDA Fortranではカーネル側でintent(in)を
データ属性として指定するだけでテクスチャ
に配置される(意識していない場合も)
ver.1.2 31
意識していないものの実際をアセンブリで確認してみる
CUDA Fortran + intent(in)
参照のみと指定された
変数xはテクスチャメ
モリに確保される
陽にテクスチャを指定
することも可能
ver.1.2 32
attributes(global) SUBROUTINE daxpy(n, x, y)
INTEGER, value :: n
REAL(8), device, intent(in) :: x(n)
REAL(8), device :: y(n)
REAL(8) :: a
INTEGER :: i
i = threadidx%x
a = 8d0
y(i) = a * x(i) + y(i)
end subroutine daxpy
[参考 CUDA Cでの利用]
• 組み込み関数__ldg利用(陽に指定)
• グローバルメモリのポインタに対して
restrict修飾子適用(コンパイラ判断)
[モジュールにて宣言]
real, texture, pointer :: t(:)
[利用側にてbindさせる]
real, target, device :: a(n)
t => a ! texureがdeviceを指す
PTXでの確認
ver.1.2 33
.visible .entry test_daxpy_(
.param .u32 test_daxpy__param_0,
.param .u64 test_daxpy__param_1,
.param .u64 test_daxpy__param_2
)
{
.reg .b32 %r<2>;
.reg .f64 %fd<4>;
.reg .b64 %rd<8>;
ld.param.u64 %rd1, [test_daxpy__param_1];
ld.param.u64 %rd2, [test_daxpy__param_2];
cvta.to.global.u64 %rd3, %rd2;
cvta.to.global.u64 %rd4, %rd1;
mov.u32 %r1, %tid.x;
mul.wide.s32 %rd5, %r1, 8;
add.s64 %rd6, %rd4, %rd5;
ld.global.nc.f64 %fd1, [%rd6];
add.s64 %rd7, %rd3, %rd5;
ld.global.f64 %fd2, [%rd7];
fma.rn.f64 %fd3, %fd1, 0d4020000000000000, %fd2;
st.global.f64 [%rd7], %fd3;
ret;
}
ld.global.nc [※PTXマニュアルから]
Load a register variable from global
state space via non-coherent cache.
intent(in)指定しない場合:
ld.global.f64 %fd1, [%rd6];
SASSでの確認
ver.1.2 34
code for sm_60
Function : test_daxpy_
.headerflags @"EF_CUDA_SM60 EF_CUDA_PTX_SM(EF_CUDA_SM60)"
/* 0x083fc400e3e007f6 */
/*0008*/ MOV R1, c[0x0][0x20] ; /* 0x4c98078000870001 */
/*0010*/ S2R R0, SR_TID.X ; /* 0xf0c8000002170000 */
/*0018*/ SHL R4, R0.reuse, 0x3 ; /* 0x3848000000370004 */
/* 0x001f8800fcc007e5 */
/*0028*/ SHR R0, R0, 0x1d ; /* 0x3829000001d70000 */
/*0030*/ IADD R6.CC, R4, c[0x0][0x148] ; /* 0x4c10800005270406 */
/*0038*/ IADD.X R7, R0, c[0x0][0x14c] ; /* 0x4c10080005370007 */
/* 0x001f8800fec007f0 */
/*0048*/ { IADD R4.CC, R4, c[0x0][0x150] ; /* 0x4c10800005470404 */
/*0050*/ LDG.E.CI.64 R2, [R6] }
/* 0xeed5a00000070602 */
/*0058*/ IADD.X R5, R0, c[0x0][0x154] ; /* 0x4c10080005570005 */
/* 0x003fc420e28007b5 */
/*0068*/ LDG.E.64 R8, [R4] ; /* 0xeed5200000070408 */
/*0070*/ DFMA R2, R2, 8, R8 ; /* 0x3670044020070202 */
/*0078*/ STG.E.64 [R4], R2 ; /* 0xeedd200000070402 */
/* 0x001f8000ffe007ff */
/*0088*/ EXIT ; /* 0xe30000000007000f */
/*0090*/ BRA 0x90 ; /* 0xe2400fffff87000f */
/*0098*/ NOP; /* 0x50b0000000070f00 */
/* 0x001f8000fc0007e0 */
/*00a8*/ NOP; /* 0x50b0000000070f00 */
/*00b0*/ NOP; /* 0x50b0000000070f00 */
/*00b8*/ NOP; /* 0x50b0000000070f00 */
テクスチャメモリへのロードを
指定するオプションCI
※公式マニュアルには説明無し
intent(in)指定しない場合:
LDG.E.64 R2, [R6]
Reductionでの命令レベルの並列性
ver.1.2 35
__inline__ __device__
int warpReduceSum(int val) {
for (int offset = warpSize/2; offset >
0; offset /= 2)
val += __shfl_down(val, offset);
return val;
}
__inline__ __device__
int3 warpReduceSumTriple(int3 val) {
for (int offset = warpSize / 2; offset >
0; offset /= 2) {
val.x += __shfl_down(val.x, offset);
val.y += __shfl_down(val.y, offset);
val.z += __shfl_down(val.z, offset);
}
return val;
}
Faster Parallel Reductions on Kepler https://devblogs.nvidia.com/faster-parallel-reductions-kepler/
SASS for a single shuffle reductions
SASS for interleaved shuffle reductions
依存性のある処理を続けて配置させないことでストールを回避
終わりに
PTXとSASSの読み方を纏めました
公開資料を片手に読み進めるきっかけになれば
PTXとSASSを読むことはGPUのアーキテク
チャの理解を進める有効な手段です
是非活用してノウハウを蓄積しましょう
ver.1.2 36
参考文献
CUDA C Programming Guide, NVIDIA
CUDAコンパイルのフローなど
CUDA BINARY UTILITIES, NVIDIA
cuobjdumpコマンド, SASSの解説
PARALLEL THREAD EXECUTION ISA, NVIDIA
PTXの詳細な解説
CUDA Fortran for Scientists and Engineers, Gregory
Ruetschら, Morgan Kaufmann
PTXでのFMA等命令の確認について簡単に記載
GPUプログラミング入門, 伊藤ら, 講談社
Satake et al. (2012)も含む
CUDAプログラミング入門, 青山幸也
PTXの読み方を詳細に解説
SASSの読み方 http://int.main.jp/txt/sass/
SASSを解説した唯一の和文公開文書
ver.1.2 37

Mais conteúdo relacionado

Mais procurados

GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust) GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
智啓 出川
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
Norishige Fukushima
 

Mais procurados (20)

プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
 
Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門
 
[DL輪読会]Relational inductive biases, deep learning, and graph networks
[DL輪読会]Relational inductive biases, deep learning, and graph networks[DL輪読会]Relational inductive biases, deep learning, and graph networks
[DL輪読会]Relational inductive biases, deep learning, and graph networks
 
マルチコアを用いた画像処理
マルチコアを用いた画像処理マルチコアを用いた画像処理
マルチコアを用いた画像処理
 
Tensor コアを使った PyTorch の高速化
Tensor コアを使った PyTorch の高速化Tensor コアを使った PyTorch の高速化
Tensor コアを使った PyTorch の高速化
 
モデルアーキテクチャ観点からのDeep Neural Network高速化
モデルアーキテクチャ観点からのDeep Neural Network高速化モデルアーキテクチャ観点からのDeep Neural Network高速化
モデルアーキテクチャ観点からのDeep Neural Network高速化
 
AIチップ戦国時代における深層学習モデルの推論の最適化と実用的な運用を可能にするソフトウェア技術について
AIチップ戦国時代における深層学習モデルの推論の最適化と実用的な運用を可能にするソフトウェア技術についてAIチップ戦国時代における深層学習モデルの推論の最適化と実用的な運用を可能にするソフトウェア技術について
AIチップ戦国時代における深層学習モデルの推論の最適化と実用的な運用を可能にするソフトウェア技術について
 
Deep Learningのための専用プロセッサ「MN-Core」の開発と活用(2022/10/19東大大学院「 融合情報学特別講義Ⅲ」)
Deep Learningのための専用プロセッサ「MN-Core」の開発と活用(2022/10/19東大大学院「 融合情報学特別講義Ⅲ」)Deep Learningのための専用プロセッサ「MN-Core」の開発と活用(2022/10/19東大大学院「 融合情報学特別講義Ⅲ」)
Deep Learningのための専用プロセッサ「MN-Core」の開発と活用(2022/10/19東大大学院「 融合情報学特別講義Ⅲ」)
 
2値化CNN on FPGAでGPUとガチンコバトル(公開版)
2値化CNN on FPGAでGPUとガチンコバトル(公開版)2値化CNN on FPGAでGPUとガチンコバトル(公開版)
2値化CNN on FPGAでGPUとガチンコバトル(公開版)
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみた
 
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust) GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例
 
DockerコンテナでGitを使う
DockerコンテナでGitを使うDockerコンテナでGitを使う
DockerコンテナでGitを使う
 
モデル高速化百選
モデル高速化百選モデル高速化百選
モデル高速化百選
 
第11回 配信講義 計算科学技術特論A(2021)
第11回 配信講義 計算科学技術特論A(2021)第11回 配信講義 計算科学技術特論A(2021)
第11回 配信講義 計算科学技術特論A(2021)
 
グラフニューラルネットワーク入門
グラフニューラルネットワーク入門グラフニューラルネットワーク入門
グラフニューラルネットワーク入門
 
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
 

Semelhante a CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説

Write good parser in perl
Write good parser in perlWrite good parser in perl
Write good parser in perl
Jiro Nishiguchi
 
20130329 rtm3
20130329 rtm320130329 rtm3
20130329 rtm3
openrtm
 
RDS(MySQL)の利用と注意点
RDS(MySQL)の利用と注意点RDS(MySQL)の利用と注意点
RDS(MySQL)の利用と注意点
Hiroyasu Suzuki
 
HandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLHandlerSocket plugin for MySQL
HandlerSocket plugin for MySQL
akirahiguchi
 
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
kasaharatt
 
130522 rt講習会(説明用)
130522 rt講習会(説明用)130522 rt講習会(説明用)
130522 rt講習会(説明用)
openrtm
 
C16 45分でわかるPostgreSQLの仕組み by 山田努
C16 45分でわかるPostgreSQLの仕組み by 山田努C16 45分でわかるPostgreSQLの仕組み by 山田努
C16 45分でわかるPostgreSQLの仕組み by 山田努
Insight Technology, Inc.
 

Semelhante a CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説 (20)

Write good parser in perl
Write good parser in perlWrite good parser in perl
Write good parser in perl
 
20130329 rtm3
20130329 rtm320130329 rtm3
20130329 rtm3
 
RDS(MySQL)の利用と注意点
RDS(MySQL)の利用と注意点RDS(MySQL)の利用と注意点
RDS(MySQL)の利用と注意点
 
[db tech showcase Tokyo 2014] B26: PostgreSQLを拡張してみよう by SRA OSS, Inc. 日本支社 高塚遥
[db tech showcase Tokyo 2014] B26: PostgreSQLを拡張してみよう  by SRA OSS, Inc. 日本支社 高塚遥[db tech showcase Tokyo 2014] B26: PostgreSQLを拡張してみよう  by SRA OSS, Inc. 日本支社 高塚遥
[db tech showcase Tokyo 2014] B26: PostgreSQLを拡張してみよう by SRA OSS, Inc. 日本支社 高塚遥
 
プロセスとコンテキストスイッチ
プロセスとコンテキストスイッチプロセスとコンテキストスイッチ
プロセスとコンテキストスイッチ
 
Citus 10 verification result (Japanese)
Citus 10 verification result (Japanese)Citus 10 verification result (Japanese)
Citus 10 verification result (Japanese)
 
Rust-DPDK
Rust-DPDKRust-DPDK
Rust-DPDK
 
GPUとSSDがPostgreSQLを加速する~クエリ処理スループット10GB/sへの挑戦~ [DB Tech Showcase Tokyo/2017]
GPUとSSDがPostgreSQLを加速する~クエリ処理スループット10GB/sへの挑戦~ [DB Tech Showcase Tokyo/2017]GPUとSSDがPostgreSQLを加速する~クエリ処理スループット10GB/sへの挑戦~ [DB Tech Showcase Tokyo/2017]
GPUとSSDがPostgreSQLを加速する~クエリ処理スループット10GB/sへの挑戦~ [DB Tech Showcase Tokyo/2017]
 
HandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLHandlerSocket plugin for MySQL
HandlerSocket plugin for MySQL
 
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
 
PostgreSQL 12の話
PostgreSQL 12の話PostgreSQL 12の話
PostgreSQL 12の話
 
RTミドルウェアサマーキャンプ2018「Rtshellj入門」
RTミドルウェアサマーキャンプ2018「Rtshellj入門」RTミドルウェアサマーキャンプ2018「Rtshellj入門」
RTミドルウェアサマーキャンプ2018「Rtshellj入門」
 
Rtshell 2017
Rtshell 2017Rtshell 2017
Rtshell 2017
 
serverspecでサーバ環境のテストを書いてみよう
serverspecでサーバ環境のテストを書いてみようserverspecでサーバ環境のテストを書いてみよう
serverspecでサーバ環境のテストを書いてみよう
 
Flutterを体験してみませんか
Flutterを体験してみませんかFlutterを体験してみませんか
Flutterを体験してみませんか
 
さわってみようTOPPERS/SSP
さわってみようTOPPERS/SSPさわってみようTOPPERS/SSP
さわってみようTOPPERS/SSP
 
130522 rt講習会(説明用)
130522 rt講習会(説明用)130522 rt講習会(説明用)
130522 rt講習会(説明用)
 
OSS-DB Gold技術解説セミナー@db tech showcase 東京 2014
OSS-DB Gold技術解説セミナー@db tech showcase 東京 2014OSS-DB Gold技術解説セミナー@db tech showcase 東京 2014
OSS-DB Gold技術解説セミナー@db tech showcase 東京 2014
 
C16 45分でわかるPostgreSQLの仕組み by 山田努
C16 45分でわかるPostgreSQLの仕組み by 山田努C16 45分でわかるPostgreSQLの仕組み by 山田努
C16 45分でわかるPostgreSQLの仕組み by 山田努
 
Starc verilog hdl2013d
Starc verilog hdl2013dStarc verilog hdl2013d
Starc verilog hdl2013d
 

CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説