SlideShare a Scribd company logo
1 of 104
Download to read offline
第5回 GPUのメモリ階層
長岡技術科学大学 電気電子情報工学専攻 出川智啓
今回の内容
2015/05/13GPGPU実践プログラミング2
 GPUのメモリ階層
 グローバルメモリ
 共有メモリ
 バンクコンフリクト
 コンスタントメモリ
 差分法における共有メモリとコンスタントメモリの利用
GPUの主要部品
2015/05/13GPGPU実践プログラミング3
 基盤
 画面出力端子
 電源入力端子
 GPU(チップ)+冷却部品
 メモリ
 特性の把握が重要
http://www.geforce.com/whats‐new/articles /introducing‐the‐geforce‐gtx‐780
に公開されている写真を基に作成
画面出力端子
PCI‐Ex端子
電源入力端子
メモリ
チップ
メモリの階層
2015/05/13GPGPU実践プログラミング4
 オフチップメモリ
 GPUのチップ外部に置かれたメモリ
 基板上に実装
 ビデオメモリ(数GB)
 オンチップメモリ
 GPUのチップ内部に置かれたメモリ
 レジスタ
 レベル1(L1)キャッシュ
 レベル2(L2)キャッシュ
高速,容量小
低速,容量大
CPUの構造に類似
メモリの階層
2015/05/13GPGPU実践プログラミング5
 CPUのメモリ階層に類似
 CPUのメモリ階層
 オフチップメインメモリ
 オンチップレジスタ,L1,L2(,L3)キャッシュ
 GPUメモリの独自の特徴
 GPUのチップから読み書き可能か
 CPUから読み書き可能か
メモリの階層
2015/05/13GPGPU実践プログラミング6
 CPUのメモリ階層
 コアごとにL2キャッシュ,全体でL3キャッシュを持つこともある
メインメモリ
L2キャッシュ
L1キャッシュ L1キャッシュ L1キャッシュ
コア
レジスタ レジスタ
コア
レジスタ レジスタ
・・・
・・・
チップ
コア
レジスタ レジスタ
メモリの階層
2015/05/13GPGPU実践プログラミング7
 GPUのメモリ階層
 CPUにはない独自のメモリを複数持つ
グローバルメモリ
L2キャッシュ
L1キャッシュ 共有メモリ
コア
レジスタ
チップ
テクスチャ
メモリ
コンスタント
メモリ
ローカル
メモリ
テクスチャ
キャッシュ
コンスタント
キャッシュ
メモリの種類
 オンチップメモリ(GPUのチップ内部のメモリ)
 高速アクセス,小容量
 CPUからはアクセス不可
 L1キャッシュと共有メモリは一定サイズを共用
L1キャッシュ/共有(シェアー
ド)メモリ
レジスタ
容量 小 小
速度 高速 高速
GPUからの
読み書き
読み書き可
ブロック内の全スレッドが同じメモリに
アクセス(データを共有する)ことが可
能*
読み書き可
各スレッドが異なるメモリに
アクセス
CPUからの
アクセス
読み書き不可 読み書き不可
2015/05/13GPGPU実践プログラミング8
*同じメモリ,異
なるメモリにつ
いては後ろの
スライドで説明
メモリの種類
 オフチップメモリ(GPUのチップ外部のメモリ)
 低速アクセス,大容量
 CPUから直接アクセス可能
 ローカルメモリだけはアクセス不可
グローバルメモリ ローカルメモリ テクスチャメモリ コンスタントメモリ
容量 大 小 大 小
速度 低速 低速 高速*1 高速*1
GPUからの
読み書き
読み書き可
全てのスレッドが同じ
メモリにアクセス可能*2
読み書き可
各スレッドが異なるメ
モリにアクセス*2
読み込み可
全てのスレッドが同じ
メモリにアクセス可能*2
読み込み可
全てのスレッドが同じ
メモリにアクセス*2
CPUからの
アクセス
読み書き可 読み書き不可 読み書き可 読み書き可
2015/05/13GPGPU実践プログラミング9
*1キャッシュが効く場合
*2同じメモリ,異なるメモリについては後ろのスライドで説明
同じメモリ
2015/05/13GPGPU実践プログラミング10
 複数のスレッドがメモリアドレスを共有
 複数のスレッドが変数を共有
 他のスレッドが書き込んだデータを読むことが可能
 共有できるスレッドの範囲はメモリの種類によって変化
//a,b[]がグローバルメモリに確保されている場合*1
__global__ void kernel(...){
int i = blockIdx.x*blockDim.x + threadIdx.x;
:
b[i] = i; //スレッドiが配列bのi番目に自身のスレッド番号を代入
//b[0,1,...,i‐1,i,...]の値は0,1,...,i‐1,i,...
a = b[i‐1];*2 //スレッドi‐1が書き込んだ値を読み*3,aに代入
:         //最後に書き込まれたaの値を全スレッドが共有
} *1 あくまで動作のイメージを説明するための例で正しく実行できない
*2 iが0の場合は考えない
*3 配列bを全スレッドが共有しているので,書き込んだ値以外を読む事が可能
異なるメモリ
2015/05/13GPGPU実践プログラミング11
 メモリアドレスが共有できず,一つのスレッドのみがその
メモリアドレスにアクセス
 あるスレッドが宣言した変数へアクセスできない
//a,b[]がレジスタに確保されている場合*1
__global__ void kernel(...){
int i = blockIdx.x*blockDim.x + threadIdx.x;
:
b[i] = i; //スレッドiが配列bのi番目に自身のスレッド番号を代入
//b[0,1,...,i‐1,i,...]の値はb[i]以外不定
a = b[i‐1];*2 //b[i‐1]の値(不定)をaに代入*3
:         //aの値はスレッドによって異なる
} *1 あくまで動作のイメージを説明するための例で正しく実行できない
*2 iが0の場合は考えない
*3 配列bは他のスレッドからアクセスできないため,代入した値以外は不定のまま
 Tesla世代
 L1,L2キャッシュなし
 テクスチャキャッシュ,コンスタ
ントキャッシュは利用可能
 高速なメモリの活用が重要
 共有メモリ
 レジスタ
メモリの種類
2015/05/13GPGPU実践プログラミング12
オフチップメモリ
オンチップメモリ
ホスト
メモリ
コンスタントメモリ
テクスチャメモリ
GPU
Chip
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA 
Core
CUDA 
Core
CUDA 
Core
CUDA 
Core
共有メモリ
SM
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA 
Core
CUDA 
Core
CUDA 
Core
CUDA 
Core
共有メモリ
SM
グローバルメモリ ローカル
メモリ
ローカル
メモリ ・・・
 Fermi世代以降
 共有メモリとL1キャッシュが
一体で利用可能
 グローバルメモリへのアクセ
スはL2キャッシュ経由
 Fermi世代では標準でL1
キャッシュも有効化*
メモリの種類
2015/05/13GPGPU実践プログラミング13
オフチップメモリ
オンチップメモリ
ホスト
メモリ
L2キャッシュ
コンスタントメモリ
テクスチャメモリ
GPU
Chip
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA 
Core
CUDA 
Core
CUDA 
Core
CUDA 
Core
L1キャッ
シュ
共有
メモリ
SM
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA 
Core
CUDA 
Core
CUDA 
Core
CUDA 
Core
L1キャッ
シュ
共有
メモリ
SM
グローバルメモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
・・・
・・・
*Kepler世代では標準でL1キャッシュが無効化
メモリの種類と並列化階層の対応
 オンチップメモリ
 ブロックまたはスレッドごとに
異なる値を持つ
 オフチップメモリ
 GPU全体で共通の値を持つ
 ローカルメモリはレジスタが
不足した時に使われる
2015/05/13GPGPU実践プログラミング14
各GPU(Grid)内
でデータを共有
各ブロック内で
データを共有
各スレッドが個別の
データを保有
L2キャッシュ
コンスタントメモリ
テクスチャメモリ
Grid
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
Thre
ad 0
Thre
ad 1
Thre
ad 2
Thre
ad 3
L1キャッ
シュ
共有
メモリ
Block(0,0,0)
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
Thre
ad 0
Thre
ad 1
Thre
ad 2
Thre
ad 3
L1キャッ
シュ
共有
メモリ
Block(1,0,0)
グローバルメモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
・・・
・・・
ホスト
メモリ
L2キャッシュ
コンスタントメモリ
テクスチャメモリ
GPU
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA 
Core
CUDA 
Core
CUDA 
Core
CUDA 
Core
L1キャッ
シュ
共有
メモリ
SM
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA 
Core
CUDA 
Core
CUDA 
Core
CUDA 
Core
L1キャッ
シュ
共有
メモリ
SM
グローバルメモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
・・・
・・・
グローバルメモリ
 ビデオメモリ(数GB)
 CPUのメインメモリに相当
 読み込みがある一定サイズ
でまとめて行われる
 レイテンシが大きい
 効率よくアクセスするための
条件がある
 コアレスアクセス
 アラインアクセス
2015/05/13GPGPU実践プログラミング15
Tesla世代ではコアレスアクセスの条件に
メモリのアラインが含まれている
Chip
ホスト
メモリ
グローバルメモリへのアクセス
(Tesla世代)
 16スレッドが協調して同時にアクセス
 1 Warp = 32スレッド
 Warpの半分(Half Warp, 16スレッド)が協調して処理を実行
 コアレスアクセスか否かで読み込みの速度が変化
 新しい世代のGPUでは,コアレスアクセスになる条件やコアレス
アクセスできないときの速度の落ち込みが緩和
 コアレスアクセスはGPUのプログラムで最重要
 GPUの処理能力と比較するとデータ供給が不足しがち
 極力データ供給不足が生じないようプログラムを作成
2015/05/13GPGPU実践プログラミング16
コアレスアクセスになる条件
(Tesla世代)
 データのサイズ
 32bit, 64bit, 128bit(4byte, 8byte, 16byte)
 アドレスの隣接
 16スレッドがアクセスするアドレスがスレッド番号順に隣接
 スレッド番号順にデータサイズ分ずつアドレスが増加
 アクセスする最初のアドレス
 16スレッドがアクセスするアドレスの先頭が,64byteまたは
128byteの倍数
2015/05/13GPGPU実践プログラミング17
コアレスアクセスの例*
(Tesla世代)
 データ型が
32bit=4byte
 各スレッドが連
続して隣接アド
レスにアクセス
 先頭アドレス
が128バイト
境界
16スレッド
 データ型が
32bit=4byte
 各スレッドが連
続して隣接アド
レスにアクセス
 実際にデータ
を取得するか
は無関係
 先頭アドレス
が128バイト
境界
T15
T14
T13
T12
T11
T10
T9
T8
T7
T6
T5
T4
T3
T2
A188
A184
A180
A176
A172
A168
A164
A160
A156
A152
A148
A144
A140
A136
T1 A132
T0 A128
T15
T14
T13
T12
T11
T10
T9
T8
T7
T6
T5
T4
T3
T2
A188
A184
A180
A176
A172
A168
A164
A160
A156
A152
A148
A144
A140
A136
T1 A132
T0 A128
2015/05/13GPGPU実践プログラミング18
*CUDA Programming Guide
メモリアドレスに対する
スレッドのアクセス要求
T15
T14
T13
T12
T11
T10
T9
T8
T7
T6
T5
T4
T3
T2
A188
A184
A180
A176
A172
A168
A164
A160
A156
A152
A148
A144
A140
A136
T1 A132
T0 A128
T15
T14
T13
T12
T11
T10
T9
T8
T7
T6
T5
T4
T3
T2
A188
A184
A180
A176
A172
A168
A164
A160
A156
A152
A148
A144
A140
A136
T1 A132
T0 A128
T15
T14
T13
T12
T11
T10
T9
T8
T7
T6
T5
T4
T3
T2
A188
A184
A180
A176
A172
A168
A164
A160
A156
A152
A148
A144
A140
A136
T1 A132
T0 A128
T15
T14
T13
T12
T11
T10
T9
T8
T7
T6
T5
T4
T3
T2
A188
A184
A180
A176
A172
A168
A164
A160
A156
A152
A148
A144
A140
A136
T1 A132
T0 A128
コアレスアクセスにならない例
(Tesla世代)
2015/05/13GPGPU実践プログラミング19
・・・
各スレッドが番
号順にアクセス
していない
先頭が128バイト
境界ではない
アドレスが連続し
ていない
データが32bit, 
64bit, 128bit
ではない
コアレスアクセスにならない例
(Tesla世代)
2015/05/13GPGPU実践プログラミング20
 128バイト境界からわずか
にずれている場合
 Tesla世代以降は64バイト
ブロックと32バイトブロック
に分けて読込
 メモリアクセス要求は2回
 コアレスアクセスの半分程
度の性能は得られる
A190
64バイトブロック
でデータ読込
32バイトブロック
でデータ読込
T15
T14
T13
T12
T11
T10
T9
T8
T7
T6
T5
T4
T3
T2
A188
A184
A180
A176
A172
A168
A164
A160
A156
A152
A148
A144
A140
A136
T1 A132
T0 A128
グローバルメモリへのアクセス
(Fermi世代)
2015/05/13GPGPU実践プログラミング21
 Tesla世代のGPU
 グローバルメモリへのアクセスに強い制約があった
 以前のGPUよりは改善
 Fermi世代以降のGPU
 Tesla世代のGPUから大幅に改善
 効率のよいアクセスの条件
 コアレスアクセス+アラインアクセス
 L1キャッシュの利用状況によっても変化
グローバルメモリからの読込
(Fermi世代)
2015/05/13GPGPU実践プログラミング22
 メモリ操作の命令はWarpごとに発行
 1 Warp内の32スレッドが協調
 各スレッドのメモリアクセス要求を一つに集約
 メモリアクセス要求の処理
 128バイトもしくは32バイト単位
 すべてL2キャッシュを通過
 アーキテクチャによってはL1キャッシュも通過
 L1キャッシュの使用はコンパイルオプションで設定可能
 Fermi世代は標準でL1キャッシュが有効化
 Kepler世代は標準でL1キャッシュが無効化
グローバルメモリからの読込
(Fermi世代)
2015/05/13GPGPU実践プログラミング23
 コアレスメモリアクセス(coalesce access)
 メモリアドレスの連続性に着目
 1 Warp内の32スレッドが隣り合ったメモリにアクセス
 データサイズが4バイトの時,スレッド1がアクセスするメモリアドレス
はスレッド0がアクセスするメモリアドレス+4
 アラインメモリアクセス(align access)
 メモリの配置に着目
 Warpがアクセスするデータの先頭アドレスがキャッシュ粒度
の倍数
 L2キャッシュのみを使う場合は32バイトの倍数
 L1キャッシュも使う場合は128バイトの倍数
メモリ読込の例
2015/05/13GPGPU実践プログラミング24
 アライン/コアレスアクセス
 ミスアライン/コアレスアクセス
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
0 1 2 3 4 5 6 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
0 1 2 3 4 5 6 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
メモリアドレスに対する
スレッドのアクセス要求
Warp内でのスレッドID
(カーネル内でのスレッド番号とは異なる)
メモリアドレス
メモリ読込の例
2015/05/13GPGPU実践プログラミング25
 アライン/アンコアレスアクセス
 ミスアライン/アンコアレスアクセス
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
0 1 2 3 4 5 6 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
0 1 2 3 4 56 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
0 1 2 3 4 56 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
メモリアドレスに対する
スレッドのアクセス要求
キャッシュの有効化/無効化
2015/05/13GPGPU実践プログラミング26
 L1キャッシュの有効・無効でパフォーマンスが変化する
場合がある
 アクセスパターンによってはパフォーマンスが向上
 Fermi世代(compute capability 2.x)ではL1キャッシュ
が標準で有効
 Kepler世代のK40以降ではL1キャッシュが標準で無効
 L1キャッシュに関するコンパイルオプション
 グローバルメモリに対する読込リクエストにおけるL1キャッ
シュ利用の有無
 ‐Xptxas ‐dlcm=cg L1キャッシュを無効化
 ‐Xptxas ‐dlcm=ca L1キャッシュを有効化
キャッシュされる読込
2015/05/13GPGPU実践プログラミング27
 L1キャッシュとL2キャッシュを通過
 読込は128バイト単位で実行
 L1キャッシュのキャッシュラインのサイズで実行
 読込の評価に利用する用語
 メモリトランザクション
 メモリのアクセス要求に対して排他的にメモリにアクセスして行う処理
の単位
 バスの利用率
 必要なデータサイズ/読込完了に必要な読込データサイズ
 アライン/コアレスアクセス
 Warp内の全スレッドが要求するメモリアドレスが128バイトの範
囲内
 全スレッドが隣り合ったメモリにアクセス
 先頭データのメモリアドレスが128バイトの倍数
 読込に必要な128バイトのトランザクションは一つ
 読み込んだデータ全てを利用
 バスの利用率は128/128=100%
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
キャッシュされる読込の例
2015/05/13GPGPU実践プログラミング28
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
0 1 2 3 4 5 6 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
Warp内でのスレッドID
(カーネル内でのスレッド番号とは異なる)
メモリアドレス
メモリアドレスに対するスレッドのアクセス要求
読込に必要な128バイトトランザクション
128バイトのキャッシュライン
読み込むデータ
キャッシュされる読込の例
2015/05/13GPGPU実践プログラミング29
 アライン/アンコアレスアクセス
 Warp内の全スレッドが要求するメモリアドレスが128バイトの
範囲内(一つのキャッシュラインに収まる)
 各スレッドがアクセスするメモリアドレスが不連続
 先頭データのメモリアドレスが128バイトの倍数
 読込に必要な128バイトのトランザクションは一つ
 読み込んだデータ全てを利用
 バスの利用率は128/128=100%
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
0 1 2 3 4 5 6 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
キャッシュされる読込の例
2015/05/13GPGPU実践プログラミング30
 ミスアライン/コアレスアクセス
 Warpがアクセスするデータの先頭アドレスが128の倍数では
ない(一つのキャッシュラインに収まらない)
 全スレッドが隣り合ったメモリにアクセス
 先頭データのメモリアドレスが128バイトの倍数ではない
 読込に必要な128バイトのトランザクションは二つ
 読み込んだデータの半分だけを利用
 バスの利用率は128/(128×2)=50%
0 1 2 3 4 5 6 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
キャッシュされる読込の例
2015/05/13GPGPU実践プログラミング31
 ミスアライン/アンコアレスアクセス
 Warp内の全スレッドが同じアドレスにアクセス要求
 一つのキャッシュラインに収まる
 読込に必要な128バイトのトランザクションは一つ
 読み込んだ128バイトのうち利用されるのは4バイトのみ
 バスの利用率は4/128=3.125%
0 1 2 3 4 56 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
キャッシュされる読込の例
2015/05/13GPGPU実践プログラミング32
 ミスアライン/アンコアレスアクセス
 Warp内の各スレッドが広範囲に点在するデータにアクセス
 複数のキャッシュラインにまたがる(上の例では3個)
 読込に必要な128バイトのトランザクションは最悪で32個
 読み込んだデータのうち128バイトのみを利用
 バスの利用率は最悪で128/(128×32)=3.125%
 上の例では128/(128×3)=33.3%
 何度も読み込むための待ちが発生
0 1 2 3 4 56 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
キャッシュされない読込
2015/05/13GPGPU実践プログラミング33
 L1キャッシュを無効化
 L2キャッシュのみを通過
 読込は32バイト単位で実行
 メモリセグメントのサイズで実行
 細かい単位で実行されるため,ミスアライン・アンコアレスメモ
リアクセスのパフォーマンスが改善される可能性がある
 セグメント
 メモリの管理方式の一つ
 まとまった大きさで管理されたメモリ空間
 アライン/コアレスアクセス
 Warp内の全スレッドが要求するメモリアドレスが128バイト(四
つのセグメントに収まる)
 全スレッドが隣り合ったメモリにアクセス
 先頭データのメモリアドレスが32バイトの倍数
 読込に必要な32バイトのトランザクションは四つ
 読み込んだデータ全てを利用
 バスの利用率は128/(32×4)=100%
キャッシュされない読込の例
2015/05/13GPGPU実践プログラミング34
0 1 2 3 4 5 6 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
Warp内でのスレッドID
(カーネル内でのスレッド番号とは異なる)
メモリアドレス
メモリアドレスに対するスレッドのアクセス要求
読込に必要な32バイトトランザクション
32バイトのメモリセグメント
読み込むデータ
キャッシュされない読込の例
2015/05/13GPGPU実践プログラミング35
 アライン/アンコアレスアクセス
 Warp内の全スレッドが要求するメモリアドレスが128バイト(四
つのセグメントに収まる)
 各スレッドがアクセスするメモリアドレスが不連続
 先頭データのメモリアドレスが32バイトの倍数
 読込に必要な32バイトのトランザクションは四つ
 読み込んだデータ全てを利用
 バスの利用率は128/(32×4)=100%
0 1 2 3 4 5 6 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
キャッシュされない読込の例
2015/05/13GPGPU実践プログラミング36
 ミスアライン/コアレスアクセス
 Warpがアクセスするデータの先頭アドレスが128の倍数では
ない(五つのセグメントにまたがる)
 全スレッドが隣り合ったメモリにアクセス
 先頭データのメモリアドレスが32バイトの倍数でない
 読込に必要な32バイトのトランザクションは五つ
 読み込んだデータの8割は利用
 バスの利用率は128/(32×5)=80% 改善!
0 1 2 3 4 5 6 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
キャッシュされない読込の例
2015/05/13GPGPU実践プログラミング37
 ミスアライン/アンコアレスアクセス
 Warp内の全スレッドが同じアドレスにアクセス要求
 一つのセグメントに収まる
 読込に必要な32バイトのトランザクションは一つ
 読み込んだ32バイトのうち利用されるのは4バイトのみ
 バスの利用率は4/32=12.5% 改善!
0 1 2 3 4 56 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
キャッシュされない読込の例
2015/05/13GPGPU実践プログラミング38
 ミスアライン/アンコアレスアクセス
 Warp内の各スレッドが広範囲に点在するデータにアクセス
 複数のセグメントにまたがる(上の例では10個)
 読込に必要な32バイトのトランザクションは最悪で32個
 最悪でも32バイトのセグメント32個に分散
 バスの利用率は最悪で128/(32×32)=12.5% 改善!
 上の例では128/(32×10)=40% 改善!
 何度も読み込むための待ちは依然として発生
0 1 2 3 4 56 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
グローバルメモリへの書込(Fermi世代)
2015/05/13GPGPU実践プログラミング39
 L2キャッシュのみを通過
 L1キャッシュは通過しない
 読込は32バイト単位で実行
 メモリセグメントのサイズで実行
 トランザクションでは一つ,二つ,四つのセグメントを使用
 1セグメントのトランザクション二つより,4セグメントのトランザクショ
ン一つの方が効率的
 Warp内の全スレッドが要求するメモリアドレスが128バイト(四
つのセグメントに収まる)
 全スレッドが隣り合ったメモリにアクセス
 先頭データのメモリアドレスが32バイトの倍数
 書込処理には4セグメントのトランザクションが一つ必要
グローバルメモリへの書込の例
2015/05/13GPGPU実践プログラミング40
0 1 2 3 4 5 6 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
Warp内でのスレッドID
(カーネル内でのスレッド番号とは異なる)
メモリアドレス
メモリアドレスに対するスレッドのアクセス要求
書込に必要な32バイトトランザクション
32バイトのメモリセグメント
読み込むデータ
 Warp内の全スレッドが要求するメモリアドレスが192バイトの範
囲に分散(三つのセグメントに収まる)
 先頭データのメモリアドレスが32バイトの倍数
 書込処理には1セグメントのトランザクションが三つ必要
グローバルメモリへの書込の例
2015/05/13GPGPU実践プログラミング41
0 1 2 3 4 5 6 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
 Warp内の全スレッドが要求するメモリアドレスが64バイトの範
囲に収まる(二つのセグメントに収まる)
 隣り合ったメモリにアクセス
 先頭データのメモリアドレスが32バイトの倍数
 書込処理には2セグメントのトランザクションが一つ必要
グローバルメモリへの書込の例
2015/05/13GPGPU実践プログラミング42
0 1 2 3 4 5 6 7 8 9 1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
0 1
6
3
2
4
8
6
4
8
0
9
6
1
1
2
1
2
8
1
4
4
1
6
0
1
7
6
1
9
2
2
0
8
2
2
4
2
4
0
2
5
6
2
7
2
2
8
8
3
0
4
3
2
0
3
3
6
3
5
2
3
5
8
L2キャッシュ
コンスタントメモリ
テクスチャメモリ
GPU
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA 
Core
CUDA 
Core
CUDA 
Core
CUDA 
Core
L1キャッ
シュ
共有
メモリ
SM
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA 
Core
CUDA 
Core
CUDA 
Core
CUDA 
Core
L1キャッ
シュ
共有
メモリ
SM
グローバルメモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
・・・
・・・
Chip
共有(シェアード)メモリ
 ブロック内のスレッドが共通
のデータ(メモリアドレス)に
アクセス可能
 物理的にSMに近い
 遅延はグローバルメモリの
20~30分の1,帯域幅は10倍
2015/05/13GPGPU実践プログラミング43
 Fermi世代以前のGPUで
マネージドキャッシュとして
利用
 1ブロックあたり
16,32*,48kB
*Kepler世代から
ホスト
メモリ
共有(シェアード)メモリ
 修飾子 __shared__ を付けて宣言
 データをブロック内で共有するために同期を取る
 共有メモリ上でデータを変更してもグローバルメモリに
は反映されない
 グローバルメモリへの書き戻しが必要
2015/05/13GPGPU実践プログラミング44
__global__ void kernel(flaot *a){
__shared__ float shared_a[NT];//NTはスレッド数
int i = blockDim.x*blockIdx.x + theadIdx.x;
shared_a[threadIdx.x] = a[i];
__syncthreads();
//共有メモリを使った処理
__syncrthreads();
a[i] = shared_a[threadIdx.x];
}
共有(シェアード)メモリ利用のイメージ
2015/05/13GPGPU実践プログラミング45
a[i]
a[i]
shared_a[tx]
i=   0    1   2    3   4    5   6    7
tx=threadIdx.x=   0    1   2    3   0    1   2    3
tx=  0    1   2    3     0    1   2    3
ブロック内で同期
共有メモリを使った処理
shared_a[tx]
blockIdx.x=0 blockIdx.x=1
共有メモリを使った処理
一つのブロック内
で使用する分のみ
を確保
同期を取り,共有
メモリ内に正しく
データが入ってい
ることを保証ブロック内で同期
処理の流れ
ブロック内でのスレッドの同期
2015/05/13GPGPU実践プログラミング46
 __syncthreads();
 カーネル実行中にスレッドの同期を取る
 __syncthreads()が書かれた行にスレッドが到達すると,同一ブ
ロック内の他の全てのスレッドがその行に達するまで待機
 異なるブロック間での同期は不可能
 1ブロックあたりのスレッド数が32以下では不要*
 32スレッドが一つのwarpとして協調して処理を実行するため
 ifの中に記述するとカーネルが終了しないことがある
if(条件){
__syncthreads();
//条件が真にならないスレッドはifの中に入らないため,
//カーネルが永久に終わらない
}
*Warp同期プログラミン
グは将来のGPUでサポー
トが廃止される予定
共有(シェアード)メモリの宣言
 修飾子 __shared__ を付けて宣言
 配列として宣言
 要素数を静的(コンパイル時)に決定する場合
 __shared__ 型 変数名[要素数]
 多次元配列も宣言可能(1,2,3次元)
 要素数を動的(カーネル実行時)に決定する場合
 extern __shared__ 型 変数名[]
 メモリサイズをカーネル呼出時のパラメータで指定
 <<<ブロック数,スレッド数,共有メモリのサイズ>>>
2015/05/13GPGPU実践プログラミング47
=要素数*sizeof(共有メモリの型)
共有(シェアード)メモリ容量の選択
2015/05/13GPGPU実践プログラミング48
 共有メモリとL1キャッシュは64kBを共用
 どちらを多く利用するかを決定する関数が用意されている
 64kB全ての利用は不可能
 L1キャッシュ48kB/共有メモリ16kB
 cudaDeviceSetCacheConfig(cudaFuncCachePreferL1);
 L1キャッシュ16kB/共有メモリ48kB
 cudaDeviceSetCacheConfig(cudaFuncCachePreferShared);
 コンパイルオプションとして ‐Xptxas ‐dlcm=cgを与えるとL1キャッ
シュを利用しなくなるが,48kB以上は利用できない
 L1キャッシュ32kB/共有メモリ32kB*
 cudaDeviceSetCacheConfig(cudaFuncCachePreferEqual);
*Kepler世代以降
カーネル単位での共有メモリ容量の選択
2015/05/13GPGPU実践プログラミング49
 デバイス(GPU)単位ではなくカーネル単位で共有メモリ
の容量を決定する関数も用意
 cudaFuncSetCacheConfig(関数ポインタ,容量の設定)
 容量の設定はcudaDeviceSetCacheConfigと同じ
 cudaFuncCachePreferL1
 cudaFuncCachePreferShared
 cudaFuncCachePreferEqual*
 cudaFuncCachePreferNone(デフォルト)
 カーネルごとに一度設定するだけでよい
 デバイスごとの設定(cudaDeviceSetCacheConfig)を上書き
*Kepler世代以降
共有(シェアード)メモリへのアクセス
(Tesla世代)
 高速にアクセスするための制約が緩い
 16スレッド(Half Warp)単位でアクセス
 16個のバンクから構成
 32bit=4バイトが1バンク
 一つのバンクにアクセスできるのはHalf Warp内の1
スレッドのみ
 複数のスレッドが一つのバンクに同時にアクセスすると バ
ンクコンフリクト(バンク衝突)が発生
 共有メモリへのアクセスが逐次化される
2015/05/13GPGPU実践プログラミング50
バンクコンフリクトにならない例
(Tesla世代)
 Half Warpが
異なるバンクに
アクセス
 隣接データに
アクセス
 データのサイ
ズは32bit 
(float型)
 コアレスアクセ
スに類似
 Half Warpが
異なるバンク
にアクセス
 ランダムアク
セス
 データのサイ
ズは32bit
 アドレスが不
連続でもよい
 コアレスアク
セスと異なる
15
14
13
12
11
10
9
8
7
6
5
4
3
2
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1 1
0 0
15
14
13
12
11
10
9
8
7
6
5
4
3
2
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1 1
0 0
2015/05/13GPGPU実践プログラミング51
メモリアドレスに対する
スレッドのアクセス要求 Half Warp内でのスレッドID
バンク番号
 96bit(12バイト)ごとに
アクセス
 float型データ3個分の
構造体など
 同じバンクにはアクセス
していない
124
120
116
112
108
104
100
96
92
88
84
80
76
72
68
64
188
184
180
176
172
164
160
160
156
152
148
144
140
136
132
128
バンクコンフリクトにならない例
(Tesla世代)
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
60
56
52
48
44
40
36
32
28
24
20
16
12
8
4
0
2015/05/13GPGPU実践プログラミング52
メモリアドレスに対する
スレッドのアクセス要求
メモリアドレス
0
2
3
5
1
6
8
14
4
7
9
15
10
11
12
13
バンク番号
バンクコンフリクトする例
(Tesla世代)
 64bit(8バイト)ごとにア
クセス
 double型では必ずバン
クコンフリクトが発生
 2wayバンクコンフリクト
 スレッド0と8, 1と9,2と
10...は同時に共有メモ
リにアクセスできない
124
120
116
112
108
104
100
96
92
88
84
80
76
72
68
64
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
60
56
52
48
44
40
36
32
28
24
20
16
12
8
4
0
2015/05/13GPGPU実践プログラミング53
メモリアドレスに対する
スレッドのアクセス要求
0
2
3
5
1
6
8
14
4
7
9
15
10
11
12
13
バンク
コンフリクト
バンク
コンフリクト
バンク
コンフリクト
バンク
コンフリクト
バンク
コンフリクト
バンク
コンフリクト
バンク
コンフリクト
バンク
コンフリクト
バンク番号
バンクコンフリクトする例
(Tesla世代)
 256bit(32バイト)ごとに
アクセス
 8wayバンクコンフリクト
124
120
116
112
108
104
100
96
92
88
84
80
76
72
68
64
188
184
180
176
172
164
160
160
156
152
148
144
140
136
132
128
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
60
56
52
48
44
40
36
32
28
24
20
16
12
8
4
0
252
248
244
240
236
232
228
224
220
216
212
208
204
200
196
192
2015/05/13GPGPU実践プログラミング54
メモリアドレスに対する
スレッドのアクセス要求
0
2
3
5
1
6
8
14
4
7
9
15
10
11
12
13
バンク
コンフリクト
バンク
コンフリクト
バンク番号
バンクコンフリクトしない例
(Tesla世代)
 16スレッドが一つの
バンクの同一アドレス
にアクセス
 配列のある要素の
データを全スレッドが
共有
 バンクコンフリクトは
発生しない
 ブロードキャストが行
われる
60
56
52
48
44
40
36
32
28
24
20
16
12
8
4
0
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
2015/05/13GPGPU実践プログラミング55
メモリアドレスに対する
スレッドのアクセス要求
0
2
3
5
1
6
8
14
4
7
9
15
10
11
12
13
バンク番号
共有(シェアード)メモリへのアクセス
(Fermi世代以降)
 32スレッド(1 Warp)単位でアクセス
 32個のバンクから構成
 Compute Capabilityが2.x 32bit=4バイトが1バンク
 帯域幅はクロックサイクルふたつあたり32ビット
 Compute Capabilityが3.x 64bit=8バイトが1バンク
 帯域幅はクロックサイクルあたり64ビット
 バンクコンフリクトはFermiと同じか少ない
 関数でバンクサイズを設定可能
 cudaDeviceSetShareMemConfig(設定);
 設定
 cudaSharedMemBankSizeFourByte 4バイト
 cudaSharedMemBankSizeEightByte 8バイト
2015/05/13GPGPU実践プログラミング56
12
8
バンクコンフリクトにならないアクセス
(Fermi世代)
2015/05/13GPGPU実践プログラミング57
 Warp内の32スレッドが異なるバンクにある32ビットの
データに隣接アクセス
 理想的なアクセスパターン
 Warpが発行した共有メモリの読込,書込命令が一つのトラン
ザクションで処理される
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
バンク番号 0 1 2 3
14
4
4 5 6 7
16
0
8 9 10 11
17
6
12 13 14 15
19
2
16 17 18 19
20
8
20 21 22 23
22
4
24 25 26 27
24
0
28 29 30 31
バンクコンフリクトにならないアクセス
(Fermi世代)
2015/05/13GPGPU実践プログラミング58
 Warp内の32スレッドが異なるバンクにある32ビットの
データにランダムアクセス
 各スレッドは異なるバンクにアクセス
 バンクコンフリクトは発生しない
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
12
8
0 1 2 3
14
4
4 5 6 7
16
0
8 9 10 11
17
6
12 13 14 15
19
2
16 17 18 19
20
8
20 21 22 23
22
4
24 25 26 27
24
0
28 29 30 31バンク番号
バンクコンフリクトにならないアクセス
(Fermi世代)
2015/05/13GPGPU実践プログラミング59
 複数のスレッドが一つのバンクの同一アドレスにアクセ
ス
 バンクコンフリクトは発生しない
 メモリトランザクションが一つ実行され,アクセスした複数のス
レッドに値がブロードキャストされる
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
12
8
0 1 2 3
14
4
4 5 6 7
16
0
8 9 10 11
17
6
12 13 14 15
19
2
16 17 18 19
20
8
20 21 22 23
22
4
24 25 26 27
24
0
28 29 30 31バンク番号
バンクコンフリクトになるアクセス
(Fermi世代)
2015/05/13GPGPU実践プログラミング60
 複数のスレッドが一つのバンクの異なるアドレスにアクセ
ス
 バンクコンフリクトが発生(下の例では4‐way)
 メモリアクセスが逐次化(最悪で32倍の時間がかかる)
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
0
12
8
25
6
38
4
0 1 2 3
16
14
4
27
2
40
0
4 5 6 7
32
16
0
28
8
41
6
8 9 10 11
48
17
6
30
4
43
2
12 13 14 15
64
19
2
32
0
44
8
16 17 18 19
80
20
8
33
6
46
4
20 21 22 23
96
22
4
35
2
48
0
24 25 26 27
11
2
24
0
35
8
49
6
28 29 30 31バンク番号
バンク
コンフリクト
バンク
コンフリクト
バンク
コンフリクト
共有メモリの使いどころ
2015/05/13GPGPU実践プログラミング61
 Fermi世代以降はキャッシュを搭載
 単純な処理ではキャッシュが大いに活躍
 プログラマが管理できるキャッシュ
 キャッシュされない条件下で共有メモリを利用
 2次元的な処理を行う場合に有効
 行列-行列積など(9, 10回目の授業を乞うご期待)
 メモリアクセスパターンの最適化
 グローバルメモリへのアクセスの制約を回避
L2キャッシュ
コンスタントメモリ
テクスチャメモリ
GPU
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA 
Core
CUDA 
Core
CUDA 
Core
CUDA 
Core
L1キャッ
シュ
共有
メモリ
SM
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA 
Core
CUDA 
Core
CUDA 
Core
CUDA 
Core
L1キャッ
シュ
共有
メモリ
SM
グローバルメモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
・・・
・・・
Chip
ホスト
メモリ
レジスタ
 各スレッドが個別に利用
 カーネル内で変数を宣言する
とレジスタを利用
 非常に高速
 キャッシュとしても利用可能
2015/05/13GPGPU実践プログラミング62
 少容量
 32768本*×32bit
 利用可能分を超え
るとローカルメモリ
へ追い出される
 レジスタスピル
*Keplerからは65536本
並列化の階層とメモリの階層
並列化の階層 メモリの階層
Grid
Block
Thread
Warp
グローバルメモリ
共有メモリ
GPU
Streaming 
Multiproc
essor
CUDA 
Core
オフチップ
メモリ
オンチッ
プメモリ
ハードウェア
構成
ハードウェア
構成
レジスタ
2015/05/13GPGPU実践プログラミング63
メモリの種類
 オフチップメモリ(GPUのチップ外部のメモリ)
 低速アクセス,大容量
 CPUから直接アクセス可能
 ローカルメモリだけはアクセス不可
2015/05/13GPGPU実践プログラミング64
グローバルメモリ ローカルメモリ テクスチャメモリ コンスタントメモリ
容量 大 小 大 小
速度 低速 低速 高速* 高速*
GPUからの
読み書き
読み書き可
全てのスレッドが同じ
アドレスにアクセス可
能
読み書き可
各スレッドが異なるアド
レスにアクセス
読み込み可
全てのスレッドが同じ
アドレスにアクセス可
能
読み込み可
全てのスレッドが同じ
アドレスにアクセス
CPUからの
アクセス
読み書き可 読み書き不可 読み書き可 読み書き可
*キャッシュが効く場合
コンスタントメモリ
 GPU全体で同じメモリにア
クセス
 コンスタントキャッシュを利
用することで,効率的な読
み込みが可能
 キャッシュはオンチップ
 GPU全体で64kB
2015/05/13GPGPU実践プログラミング65
L2キャッシュ
コンスタントメモリ
テクスチャメモリ
GPU
Chip
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA 
Core
CUDA 
Core
CUDA 
Core
CUDA 
Core
L1キャッ
シュ
共有
メモリ
SM
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA 
Core
CUDA 
Core
CUDA 
Core
CUDA 
Core
L1キャッ
シュ
共有
メモリ
SM
グローバルメモリ
ホスト
メモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
・・・
・・・
コンスタントメモリの利用
 修飾子 __constant__ を付けて宣言
 メモリは読込専用
 CPUからは変更可能
 専用のメモリ転送命令でコピー
 cudaMemcpyToSymbol
 CPU上のメモリをコンスタントメモリにコピーする
 cudaMemcpyToSymbol(転送先変数名, 転送元アドレス,
バイト数, オフセット, 方向);
 オフセット,方向は無くてもよい
 オフセットを省略すると0が使われる
 方向を省略するとcudaMemcpyHostToDeviceが使われる
2015/05/13GPGPU実践プログラミング66
コンスタントメモリの利用
 cudaError_t cudaMemcpyToSymbol(
const char *  symbol,
const void *  src,
size_t count,
size_t offset = 0,
enum cudaMemcpyKind kind = cudaMemcpyHostToDevice
)
 Parameters
 symbol ‐ Symbol destination on device
 src ‐ Source memory address
 count  ‐ Size in bytes to copy
 offset  ‐ Offset from start of symbol in bytes
 kind  ‐ Type of transfer
2015/05/13GPGPU実践プログラミング
http://docs.nvidia.com/cuda/cuda‐runtime‐api/
67
コンスタントメモリの宣言
 サイズは静的に決定
 __constant__ 型 変数名;
 __constant__ 型 変数名[要素数];
 配列としても宣言可能
 要素数はコンパイル時に確定している必要がある
 cudaMalloc()やcudaFree()は不要
 グローバル変数として宣言し,複数のカーネルからアク
セス
 読込専用のメモリならではの使い方
 書込可能なメモリでは厳禁
2015/05/13GPGPU実践プログラミング68
コンスタントメモリへのアクセス
(Tesla世代)
 コンスタントメモリへ高速にアクセスできる要因
1. ブロードキャストによるデータの分配
 16スレッド(Half Warp)単位でアクセスし,1回の読込を他
のスレッドにブロードキャストできる
 16スレッドが同じアドレスにアクセスすると最も効率がよい
2. コンスタントメモリキャッシュ
 SMごとに存在する独自のオンチップキャッシュ
 他のHalf Warpがキャッシュされたデータへアクセスしても,
コンスタントメモリからの読込が発生しない
2015/05/13GPGPU実践プログラミング69
コンスタントメモリへのアクセス
(Tesla世代)
 オフチップメモリ(DRAM)からの読込量を抑制
 オフチップメモリ(DRAM)からの読込による実行速度低
下を回避
 コンスタントメモリへのアクセスの制約
 Half Warp内のスレッド全てが異なるコンスタントメモリのア
ドレスを参照すると,読込が逐次化
 読込命令の処理に最悪で16倍の時間を要する
2015/05/13GPGPU実践プログラミング70
コンスタントメモリへのアクセス
(Tesla世代)
 Half Warp内のスレッド全てが同じメモ
リアドレスにアクセス
 1スレッドの読込をブロードキャストによっ
て残りのスレッドが共有
 他のHalf Warpも同じメモリアドレスに
アクセス
 データがキャッシュされているため,キャッ
シュから高速に読み出し
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0 0
2015/05/13GPGPU実践プログラミング71
Half Warp内でのスレッドID
メモリアドレス
コンスタントメモリへのアクセス
(Tesla世代)
 Half Warp内のスレッド全てが異なる
メモリアドレスにアクセス
 読込が逐次化
 読込処理の時間は,Half Warpがアクセ
スするコンスタントメモリアドレスの数に比
例
 最悪で処理に16倍の時間がかかる
 おそらくグローバルメモリアクセスよりも遅くなる
2015/05/13GPGPU実践プログラミング
15
14
13
12
11
10
9
8
7
6
5
4
3
2
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1 1
0 0
72
コンスタントメモリへのアクセス
(Fermi世代)
 コンスタントメモリへ高速にアクセスできる要因
1. ブロードキャストによるデータの分配
 32スレッド(Warp)単位でアクセスし,1回の読込を他のスレッ
ドにブロードキャストできる
 32スレッドが同じアドレスにアクセスすると最も効率がよい
2. コンスタントメモリキャッシュ
 SMごとに存在する独自のオンチップキャッシュ
 他のWarpがキャッシュされたデータへアクセスしても,コンス
タントメモリからの読込が発生しない
2015/05/13GPGPU実践プログラミング73
コンスタントメモリへのアクセス
(Fermi世代)
 オフチップメモリ(DRAM)からの読込量を抑制
 オフチップメモリ(DRAM)からの読込による実行速度低
下を回避
 コンスタントメモリへのアクセスの制約
 Warp内のスレッド全てが異なるコンスタントメモリのアドレス
を参照すると,読込が逐次化
 読込命令の処理に最悪で32倍の時間を要する
2015/05/13GPGPU実践プログラミング74
0 16 32 48 64 80 96 11
2
コンスタントメモリへのアクセス
(Fermi世代)
 Warp内のスレッド全てが同じコンスタントメモリアドレス
にアクセス
 1スレッドの読込をブロードキャストによって残りのスレッドが
共有
 他のWarpも同じメモリアドレスにアクセス
 データがキャッシュされているため,キャッシュから高速に読
み出し
2015/05/13GPGPU実践プログラミング75
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
0 16 32 48 64 80 96 11
2
コンスタントメモリへのアクセス
(Fermi世代)
 Warp内のスレッド全てが異なるコンスタントメモリアドレ
スにアクセス
 読込が逐次化
 読込処理の時間は,Warpがアクセスするコンスタントメモリア
ドレスの数に比例
 最悪で処理に32倍の時間がかかる
 おそらくグローバルメモリアクセスよりも遅くなる
2015/05/13GPGPU実践プログラミング76
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
コンスタントメモリ利用の例
2015/05/13GPGPU実践プログラミング
 ベクトル和
 ベクトルAとBの値が全て同じ
 コンスタントメモリにデータを一つ置き,全スレッドが参照
・・・
・・・
・・・c[i]
a[i]
b[i]
+ + + + +
・・・c[i]
a
b
+
77
#define N (8*1024) //64kBに収める
#define Nbytes (N*sizeof(float))
#define NT (256)
#define NB (N/NT)
__global__ void init(float *a,
float *b, float *c){
int i = blockIdx.x*blockDim.x
+ threadIdx.x;
a[i] = 1.0;
b[i] = 2.0;
c[i] = 0.0;
}
__global__ void add(float *a,
float *b, float *c){
int i = blockIdx.x*blockDim.x
+ threadIdx.x;
c[i] = a[i] + b[i];
}
int main(void){
float *a,*b,*c;
cudaMalloc((void **)&a, Nbytes);
cudaMalloc((void **)&b, Nbytes);
cudaMalloc((void **)&c, Nbytes);
init<<< NB, NT>>>(a,b,c);
add<<< NB, NT>>>(a,b,c);
return 0;
}
GPUプログラム(グローバルメモリ利用)
2015/05/13GPGPU実践プログラミング
vectoradd.cu
78
#define N (8*1024) //64kBに収める
#define Nbytes (N*sizeof(float))
#define NT (256)
#define NB (N/NT)
__constant__ float a[N],b[N];
__global__ void init(float *c){
int i = blockIdx.x*blockDim.x
+ threadIdx.x;
c[i] = 0.0f;
}
__global__ void add(float *c){
int i = blockIdx.x*blockDim.x
+ threadIdx.x;
c[i] = a[i] + b[i];
}
int main(void){
float *c;
float *host_a,*host_b;
int i;
host_a=(float *)malloc(Nbytes);
host_b=(float *)malloc(Nbytes);
cudaMalloc((void **)&c,Nbytes);
for(i=0;i<N;i++){
host_a[i] = 1.0f;
host_b[i] = 2.0f;
}
cudaMemcpyToSymbol
(a,host_a,Nbytes);
cudaMemcpyToSymbol
(b,host_b,Nbytes);
init<<< NB, NT>>>(c);
add<<< NB, NT>>>(c);
return 0;
}
コンスタントメモリ(単純な置き換え)
2015/05/13GPGPU実践プログラミング
vectoradd_constant.cu
79
実行時間
2015/05/13GPGPU実践プログラミング
 入力配列サイズ N = 213
 スレッド数 NT = 256
 各スレッドがコンスタントメモリの異なるアドレスにアクセスす
ると,グローバルメモリよりも遅くなる
カーネル 実行時間 [ms]
vectoradd 7.65×10‐3
vectoradd_constant 1.01×10‐2
80
#define N (8*1024) //64kBに収める
#define Nbytes (N*sizeof(float))
#define NT (256)
#define NB (N/NT)
__constant__ float a, b;
__global__ void init(float *c){
int i = blockIdx.x*blockDim.x
+ threadIdx.x;
c[i] = 0.0f;
}
__global__ void add(float *c){
int i = blockIdx.x*blockDim.x
+ threadIdx.x;
c[i] = a + b;
}
int main(void){
float *c;
float host_a,host_b;
host_a=1.0f;
host_b=2.0f;
cudaMalloc((void **)&c,Nbytes);
//host_a,host_bが配列ではないので
//アドレスを取り出すために&を付ける
cudaMemcpyToSymbol
(a,&host_a,sizeof(float));
cudaMemcpyToSymbol
(b,&host_b,sizeof(float));
init<<< NB, NT>>>(c);
add<<< NB, NT>>>(c);
return 0;
}
コンスタントメモリ(同一アドレス参照)
2015/05/13GPGPU実践プログラミング
vectoradd_broadcast.cu
81
実行時間
2015/05/13GPGPU実践プログラミング
 入力配列サイズ N = 213
 スレッド数 NT = 256
 各スレッドがコンスタントメモリの同一アドレスにアクセスする
と高速化
カーネル 実行時間 [ms]
vectoradd 7.65×10‐3
vectoradd_constant 1.01×10‐2
vectoradd_broadcast 7.55×10‐3
82
実行時間
2015/05/13GPGPU実践プログラミング
 入力配列サイズ N = 220
 スレッド数 NT = 256
 データ転送量が多くなるとコンスタントメモリを利用する事で
かなりの高速化が達成できる
 定数を参照する場合,#defineで定義した方が高速に実行で
きるので使いどころが難しい
 畳み込みのような処理を行うカーネル内で,全スレッドが同じ係数
テーブルにアクセスするような場合に有効
カーネル 実行時間 [ms]
vectoradd 0.116
vectoradd_broadcast 0.042
83
共有メモリの典型的な使い方
2015/05/13GPGPU実践プログラミング84
 差分法
 あるスレッドが中心差分を計算するために配列の要素i‐1, 
i, i+1を参照
 配列要素は複数回参照される
 Fermi世代以降はキャッシュが利用可能
1 1 2 2 1 1
dudx[i]
u[i]
+ + + +
Δx2
1
参照される回数
共有メモリの典型的な使い方
 境界で異なる処理を行うためにif分岐が必要
 キャッシュを搭載していてもグローバルメモリへのアクセスを
伴うif分岐は高負荷
 データの再利用とif文の排除に共有メモリを利用
2 2 3 3 2 2
dudx[i]
u[i]
+ + + + + +
2015/05/13GPGPU実践プログラミング85
Δx2
1
参照される回数
共有メモリによる明示的なキャッシュ
2015/05/13GPGPU実践プログラミング86
 グローバルメモリから共有メモリにデータをキャッシュ
 共有メモリ上で境界条件を処理
 中心差分の計算からifを排除
dudx[i]
u[i]
共有メモリ
blockIdx.x=0 blockIdx.x=1
計算のために必要になる余分な領域(袖領域)
共有メモリによる明示的なキャッシュ
2015/05/13GPGPU実践プログラミング87
 グローバルメモリから共有メモリにデータをキャッシュ
 共有メモリ上で境界条件を処理
 中心差分の計算からifを排除
dudx[i]
u[i]
共有メモリ
blockIdx.x=0 blockIdx.x=1
何らかの方法で
境界条件を反映
何らかの方法で
境界条件を反映
共有メモリによる明示的なキャッシュ
2015/05/13GPGPU実践プログラミング88
 グローバルメモリから共有メモリにデータをキャッシュ
 共有メモリ上で境界条件を処理
 中心差分の計算からifを排除
dudx[i]
u[i]
共有メモリ
++ + + + +
blockIdx.x=0 blockIdx.x=1
全スレッドが同じ式
で中心差分を計算
#include<stdlib.h>
#include<math.h>
#define Lx (2.0*M_PI)
#define Nx (1024*1024)
#define dx (Lx/(Nx‐1))
#define Nbytes (Nx*sizeof(double))
#define NT (256)
#define NB (Nx/NT)
void init(double *u){
int i;
for(i=0; i<Nx; i++){
u[i] = sin(i*dx);
}
}
__global__ void differentiate
(double *u, double *dudx){
int i = blockIdx.x*blockDim.x
+ threadIdx.x;
if(i==0)
dudx[i]=(‐3.0*u[i ]
+4.0*u[i+1]
‐ u[i+2])/(2.0*dx);
if(0<i && i<Nx‐1)
dudx[i] = ( u[i+1]
‐u[i‐1])/(2.0*dx);
if(i==Nx‐1)
dudx[i]=(     u[i‐2]
‐4.0*u[i‐1]
+3.0*u[i ])/(2.0*dx);
}
GPUプログラム(単純な実装)
2015/05/13GPGPU実践プログラミング89
differentiate.cu
int main(void){
double *host_u,*host_dudx;
double *u,*dudx;
host_u =(double *)malloc(Nbytes);
host_dudx=(double *)malloc(Nbytes);
cudaMalloc((void **)&u,Nbytes);
cudaMalloc((void **)&dudx,Nbytes);
init(host_u);
cudaMemcpy(u,host_u,Nbytes, 
cudaMemcpyHostToDevice);
differentiate<<<NB, NT>>>(u,dudx);
cudaMemcpy(host_dudx, dudx, Nbytes, 
cudaMemcpyDeviceToHost);
free(host_u);
free(host_dudx);
cudaFree(u);
cudaFree(dudx);
return 0;
}
GPUプログラム(単純な実装)
2015/05/13GPGPU実践プログラミング90
differentiate.cu
__global__ void differentiate(double *u, double *dudx){
int i = blockIdx.x*blockDim.x + threadIdx.x;
__shared__ double su[1+NT+1];
int tx = threadIdx.x+1;
su[tx] = u[i];
__syncthreads();
if(blockIdx.x> 0           && threadIdx.x==0           ) su[tx‐1] = u[i‐1];
if(blockIdx.x< gridDim.x‐1 && threadIdx.x==blockDim.x‐1) su[tx+1] = u[i+1];
if(blockIdx.x==0           && threadIdx.x==0           )
su[tx‐1] = 3.0*su[tx]‐3.0*su[tx+1]+su[tx+2];
if(blockIdx.x==gridDim.x‐1 && threadIdx.x==blockDim.x‐1)
su[tx+1] = 3.0*su[tx]‐3.0*su[tx‐1]+su[tx‐2];
__syncthreads();
dudx[i] = ( su[tx+1]‐su[tx‐1])/(2.0*dx);
}
共有メモリを用いた書き換え
2015/05/13GPGPU実践プログラミング91
differentiate_shared.cu
共有メモリの宣言と代入
int i = blockIdx.x*blockDim.x + threadIdx.x;
__shared__ double su[1+NT+1]; //右と左の袖領域を追加して宣言
int tx = threadIdx.x+1;
su[tx] = u[i];
__syncthreads();
2015/05/13GPGPU実践プログラミング92
u[i]
su[NT+2]
i=   0    1    2            3    4    5
threadIdx.x= 0    1    2          0    1    2
tx=   0    1    2    3   4       0    1    2    3    4
NT=3NT=3
u[0] u[1] u[2]             u[3] u[4] u[5]
袖領域の処理
if(blockIdx.x> 0           && threadIdx.x==0           ) su[tx‐1] = u[i‐1];
if(blockIdx.x< gridDim.x‐1 && threadIdx.x==blockDim.x‐1) su[tx+1] = u[i+1];
2015/05/13GPGPU実践プログラミング93
u[i]
su[NT+2]
i=   0    1    2            3    4    5
0    1    2=threadIdx.x
tx=   0    1    2    3   4       0    1    2    3    4
blockIdx.x=0 blockIdx.x=1
u[0] u[1] u[2]         u[3] u[4] u[5]
袖領域の処理
if(blockIdx.x> 0           && threadIdx.x==0           ) su[tx‐1] = u[i‐1];
if(blockIdx.x< gridDim.x‐1 && threadIdx.x==blockDim.x‐1) su[tx+1] = u[i+1];
2015/05/13GPGPU実践プログラミング94
u[i]
su[NT+2]
i=   0    1    2            3    4    5
0=threadIdx.x
tx=   0    1    2    3   4       0    1    2    3    4
blockIdx.x=0 blockIdx.x=1
u[0] u[1] u[2]        u[2] u[3] u[4] u[5]
袖領域の処理
if(blockIdx.x> 0           && threadIdx.x==0           ) su[tx‐1] = u[i‐1];
if(blockIdx.x< gridDim.x‐1 && threadIdx.x==blockDim.x‐1) su[tx+1] = u[i+1];
2015/05/13GPGPU実践プログラミング95
u[i]
su[NT+2]
i=   0    1    2            3    4    5
tx=   0    1    2    3   4       0    1    2    3    4
blockIdx.x=0 blockIdx.x=1
u[0] u[1] u[2] u[2] u[3] u[4] u[5]
threadIdx.x= 0    1    2
袖領域の処理
if(blockIdx.x> 0           && threadIdx.x==0           ) su[tx‐1] = u[i‐1];
if(blockIdx.x< gridDim.x‐1 && threadIdx.x==blockDim.x‐1) su[tx+1] = u[i+1];
2015/05/13GPGPU実践プログラミング96
u[i]
su[NT+2]
i=   0    1    2            3    4    5
tx=   0    1    2    3   4       0    1    2    3    4
blockIdx.x=0 blockIdx.x=1
u[0] u[1] u[2] u[3] u[2] u[3] u[4] u[5]
threadIdx.x=2
境界条件の処理
if(blockIdx.x==0           && threadIdx.x==0           )
su[tx‐1] = 3.0*su[tx]‐3.0*su[tx+1]+su[tx+2];
if(blockIdx.x==gridDim.x‐1 && threadIdx.x==blockDim.x‐1)
su[tx+1] = 3.0*su[tx]‐3.0*su[tx‐1]+su[tx‐2];
2015/05/13GPGPU実践プログラミング97
su[NT+2]
tx=   0    1    2    3   4       0    1    2    3    4
blockIdx.x=0 blockIdx.x=1
u[0] u[1] u[2] u[3] u[2] u[3] u[4] u[5]
2101 33 uuuu 
Δx
uu
Δx
uuu
dx
du
i 22
43 11210
0






境界での差分式と中心差分式が一致するようにu−1を決定
u[‐1]
境界条件の処理
if(blockIdx.x==0           && threadIdx.x==0           )
su[tx‐1] = 3.0*su[tx]‐3.0*su[tx+1]+su[tx+2];
if(blockIdx.x==gridDim.x‐1 && threadIdx.x==blockDim.x‐1)
su[tx+1] = 3.0*su[tx]‐3.0*su[tx‐1]+su[tx‐2];
2015/05/13GPGPU実践プログラミング98
su[NT+2]
tx=   0    1    2    3   4       0    1    2    3    4
blockIdx.x=0 blockIdx.x=1
u[0] u[1] u[2] u[3] u[2] u[3] u[4] u[5]
321 33   NNNN uuuu
Δx
uu
Δx
uuu
dx
du NNNNN
Ni 22
43 2321
1






境界での差分式と中心差分式が一致するようにuNを決定
u[‐1] u[6]
中心差分の計算
__syncthreads();
dudx[i] = ( su[tx+1]‐su[tx‐1])/(2.0*dx);
2015/05/13GPGPU実践プログラミング99
su[NT+2]
tx=   0    1    2    3   4       0    1    2    3    4
blockIdx.x=0 blockIdx.x=1
u[0] u[1] u[2] u[3] u[2] u[3] u[4] u[5]
dudx[i]
++ + + + + 全スレッドが同じ式
で中心差分を計算Δx2
1
u[‐1] u[6]
実行時間
2015/05/13GPGPU実践プログラミング
 入力配列サイズ N = 220
 スレッド数 NT = 256
 わずかに高速化
 明示的に共有メモリを利用している分,キャッシュを利用する
よりも遅くなると思っていたが速くなった!
カーネル 実行時間 [ms]
differentiate 0.203
shared 0.194 
100
コンスタントメモリによる定数の再利用
2015/05/13GPGPU実践プログラミング101
 中心差分計算の分母 2.0*dx
 全てのスレッドが利用
 計算中に変更されない定数
 #defineで定義
 #define Lx (2.0*M_PI)
 #define Nx (1024*1024)
 #define dx (Lx/(Nx‐1))
 dxを事前に計算しているようだが,逆数までは求めてくれない
 2.0*dxの逆数を計算してコンスタントメモリに送り,全ス
レッドから参照
#include<stdlib.h>
#include<math.h>/*‐lmオプションが必要*/
#define Lx (2.0*M_PI)
#define Nx (1024*1024)
#define dx (Lx/(Nx‐1))
#define Nbytes (Nx*sizeof(double))
#define NT (256)
#define NB (Nx/NT)
__constant__ double idx2;
void init(double *u){
int i;
for(i=0; i<Nx; i++){
u[i] = sin(i*dx);
}
}
__global__ void differentiate
(double *u, double *dudx){
int i = blockIdx.x*blockDim.x
+ threadIdx.x;
__shared__ double su[1+NT+1];
int tx = threadIdx.x+1;
su[tx] = u[i];
__syncthreads();
ここはdifferentiate_shared.cuと同じ
dudx[i]=(su[tx+1]‐su[tx‐1])*idx2;
}
GPUプログラム(コンスタントメモリ)
2015/05/13GPGPU実践プログラミング102
differentiate_constant.cu
int main(void){
double *host_u,*host_dudx;
double *u,*dudx;
//コンスタントメモリにデータを送るために
//ホストで1/(2.0*dx)を計算
double h_idx2 = 1.0/(2.0*dx);
host_u =(double *)malloc(Nbytes);
host_dudx=(double *)malloc(Nbytes);
cudaMalloc((void **)&u,Nbytes);
cudaMalloc((void **)&dudx,Nbytes);
init(host_u);
cudaMemcpy(u,host_u,Nbytes, 
cudaMemcpyHostToDevice);
//コンスタントメモリへデータを送る
cudaMemcpyToSymbol(idx2, &h_idx2,
sizeof(double));
differentiate<<<NB, NT>>>(u,dudx);
cudaMemcpy(host_dudx, dudx, Nbytes, 
cudaMemcpyDeviceToHost);
free(host_u);
free(host_dudx);
cudaFree(u);
cudaFree(dudx);
return 0;
}
GPUプログラム(コンスタントメモリ)
2015/05/13GPGPU実践プログラミング103
differentiate_constant.cu
実行時間
2015/05/13GPGPU実践プログラミング
 入力配列サイズ N = 220
 スレッド数 NT = 256
 わずかに高速化し,効果がある事を確認
 #defineでidx2を定義した方が高速(0.182 ms)
カーネル 実行時間 [ms]
differentiate 0.203
shared 0.194 
constant 0.186
104

More Related Content

What's hot

CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説Takateru Yamagishi
 
研究者のための Python による FPGA 入門
研究者のための Python による FPGA 入門研究者のための Python による FPGA 入門
研究者のための Python による FPGA 入門ryos36
 
2015年度GPGPU実践プログラミング 第15回 GPU最適化ライブラリ
2015年度GPGPU実践プログラミング 第15回 GPU最適化ライブラリ2015年度GPGPU実践プログラミング 第15回 GPU最適化ライブラリ
2015年度GPGPU実践プログラミング 第15回 GPU最適化ライブラリ智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算 (移流方程式)
2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算(移流方程式)2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算(移流方程式)
2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算 (移流方程式)智啓 出川
 
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編Fixstars Corporation
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門Fixstars Corporation
 
FPGA, AI, エッジコンピューティング
FPGA, AI, エッジコンピューティングFPGA, AI, エッジコンピューティング
FPGA, AI, エッジコンピューティングHideo Terada
 
オープンソースコンパイラNNgenでつくるエッジ・ディープラーニングシステム
オープンソースコンパイラNNgenでつくるエッジ・ディープラーニングシステムオープンソースコンパイラNNgenでつくるエッジ・ディープラーニングシステム
オープンソースコンパイラNNgenでつくるエッジ・ディープラーニングシステムShinya Takamaeda-Y
 
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) 智啓 出川
 
Tensor コアを使った PyTorch の高速化
Tensor コアを使った PyTorch の高速化Tensor コアを使った PyTorch の高速化
Tensor コアを使った PyTorch の高速化Yusuke Fujimoto
 
計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミングNorishige Fukushima
 
第1回 配信講義 計算科学技術特論A (2021)
第1回 配信講義 計算科学技術特論A (2021)第1回 配信講義 計算科学技術特論A (2021)
第1回 配信講義 計算科学技術特論A (2021)RCCSRENKEI
 
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013Ryo Sakamoto
 
TensorFlow XLAは、 中で何をやっているのか?
TensorFlow XLAは、 中で何をやっているのか?TensorFlow XLAは、 中で何をやっているのか?
TensorFlow XLAは、 中で何をやっているのか?Mr. Vengineer
 
開発者が語る NVIDIA cuQuantum SDK
開発者が語る NVIDIA cuQuantum SDK開発者が語る NVIDIA cuQuantum SDK
開発者が語る NVIDIA cuQuantum SDKNVIDIA Japan
 
画像処理ライブラリ OpenCV で 出来ること・出来ないこと
画像処理ライブラリ OpenCV で 出来ること・出来ないこと画像処理ライブラリ OpenCV で 出来ること・出来ないこと
画像処理ライブラリ OpenCV で 出来ること・出来ないことNorishige Fukushima
 
[Track2-2] 最新のNVIDIA AmpereアーキテクチャによるNVIDIA A100 TensorコアGPUの特長とその性能を引き出す方法
[Track2-2] 最新のNVIDIA AmpereアーキテクチャによるNVIDIA A100 TensorコアGPUの特長とその性能を引き出す方法[Track2-2] 最新のNVIDIA AmpereアーキテクチャによるNVIDIA A100 TensorコアGPUの特長とその性能を引き出す方法
[Track2-2] 最新のNVIDIA AmpereアーキテクチャによるNVIDIA A100 TensorコアGPUの特長とその性能を引き出す方法Deep Learning Lab(ディープラーニング・ラボ)
 

What's hot (20)

CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
 
研究者のための Python による FPGA 入門
研究者のための Python による FPGA 入門研究者のための Python による FPGA 入門
研究者のための Python による FPGA 入門
 
2015年度GPGPU実践プログラミング 第15回 GPU最適化ライブラリ
2015年度GPGPU実践プログラミング 第15回 GPU最適化ライブラリ2015年度GPGPU実践プログラミング 第15回 GPU最適化ライブラリ
2015年度GPGPU実践プログラミング 第15回 GPU最適化ライブラリ
 
2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算 (移流方程式)
2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算(移流方程式)2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算(移流方程式)
2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算 (移流方程式)
 
GPU最適化入門
GPU最適化入門GPU最適化入門
GPU最適化入門
 
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
 
Gpu vs fpga
Gpu vs fpgaGpu vs fpga
Gpu vs fpga
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
 
FPGA, AI, エッジコンピューティング
FPGA, AI, エッジコンピューティングFPGA, AI, エッジコンピューティング
FPGA, AI, エッジコンピューティング
 
オープンソースコンパイラNNgenでつくるエッジ・ディープラーニングシステム
オープンソースコンパイラNNgenでつくるエッジ・ディープラーニングシステムオープンソースコンパイラNNgenでつくるエッジ・ディープラーニングシステム
オープンソースコンパイラNNgenでつくるエッジ・ディープラーニングシステム
 
CuPy解説
CuPy解説CuPy解説
CuPy解説
 
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)
 
Tensor コアを使った PyTorch の高速化
Tensor コアを使った PyTorch の高速化Tensor コアを使った PyTorch の高速化
Tensor コアを使った PyTorch の高速化
 
計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング
 
第1回 配信講義 計算科学技術特論A (2021)
第1回 配信講義 計算科学技術特論A (2021)第1回 配信講義 計算科学技術特論A (2021)
第1回 配信講義 計算科学技術特論A (2021)
 
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
 
TensorFlow XLAは、 中で何をやっているのか?
TensorFlow XLAは、 中で何をやっているのか?TensorFlow XLAは、 中で何をやっているのか?
TensorFlow XLAは、 中で何をやっているのか?
 
開発者が語る NVIDIA cuQuantum SDK
開発者が語る NVIDIA cuQuantum SDK開発者が語る NVIDIA cuQuantum SDK
開発者が語る NVIDIA cuQuantum SDK
 
画像処理ライブラリ OpenCV で 出来ること・出来ないこと
画像処理ライブラリ OpenCV で 出来ること・出来ないこと画像処理ライブラリ OpenCV で 出来ること・出来ないこと
画像処理ライブラリ OpenCV で 出来ること・出来ないこと
 
[Track2-2] 最新のNVIDIA AmpereアーキテクチャによるNVIDIA A100 TensorコアGPUの特長とその性能を引き出す方法
[Track2-2] 最新のNVIDIA AmpereアーキテクチャによるNVIDIA A100 TensorコアGPUの特長とその性能を引き出す方法[Track2-2] 最新のNVIDIA AmpereアーキテクチャによるNVIDIA A100 TensorコアGPUの特長とその性能を引き出す方法
[Track2-2] 最新のNVIDIA AmpereアーキテクチャによるNVIDIA A100 TensorコアGPUの特長とその性能を引き出す方法
 

Viewers also liked

2015年度GPGPU実践基礎工学 第11回 GPUでの並列 プログラミング(ベクトル和)
2015年度GPGPU実践基礎工学 第11回 GPUでの並列プログラミング(ベクトル和)2015年度GPGPU実践基礎工学 第11回 GPUでの並列プログラミング(ベクトル和)
2015年度GPGPU実践基礎工学 第11回 GPUでの並列 プログラミング(ベクトル和)智啓 出川
 
2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造
2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造
2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造智啓 出川
 
2015年度GPGPU実践プログラミング 第14回 N体問題
2015年度GPGPU実践プログラミング 第14回 N体問題2015年度GPGPU実践プログラミング 第14回 N体問題
2015年度GPGPU実践プログラミング 第14回 N体問題智啓 出川
 
2015年度GPGPU実践プログラミング 第13回 多粒子の運動
2015年度GPGPU実践プログラミング 第13回 多粒子の運動2015年度GPGPU実践プログラミング 第13回 多粒子の運動
2015年度GPGPU実践プログラミング 第13回 多粒子の運動智啓 出川
 
2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史
2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史
2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史智啓 出川
 
2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ智啓 出川
 
2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)
2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)
2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)智啓 出川
 
2015年度GPGPU実践プログラミング 第11回 画像処理
2015年度GPGPU実践プログラミング 第11回 画像処理2015年度GPGPU実践プログラミング 第11回 画像処理
2015年度GPGPU実践プログラミング 第11回 画像処理智啓 出川
 
2015年度GPGPU実践プログラミング 第7回 総和計算
2015年度GPGPU実践プログラミング 第7回 総和計算2015年度GPGPU実践プログラミング 第7回 総和計算
2015年度GPGPU実践プログラミング 第7回 総和計算智啓 出川
 
2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例
2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例
2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例智啓 出川
 
2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造
2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造
2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造智啓 出川
 
2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)
2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)
2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)智啓 出川
 
2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)
2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)
2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)智啓 出川
 
2015年度GPGPU実践プログラミング 第9回 行列計算(行列-行列積)
2015年度GPGPU実践プログラミング 第9回 行列計算(行列-行列積)2015年度GPGPU実践プログラミング 第9回 行列計算(行列-行列積)
2015年度GPGPU実践プログラミング 第9回 行列計算(行列-行列積)智啓 出川
 
2015年度GPGPU実践プログラミング 第12回 偏微分方程式の差分計算
2015年度GPGPU実践プログラミング 第12回 偏微分方程式の差分計算2015年度GPGPU実践プログラミング 第12回 偏微分方程式の差分計算
2015年度GPGPU実践プログラミング 第12回 偏微分方程式の差分計算智啓 出川
 
2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール
2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール
2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール智啓 出川
 
2015年度GPGPU実践プログラミング 第4回 GPUでの並列プログラミング(ベクトル和,移動平均,差分法)
2015年度GPGPU実践プログラミング 第4回 GPUでの並列プログラミング(ベクトル和,移動平均,差分法)2015年度GPGPU実践プログラミング 第4回 GPUでの並列プログラミング(ベクトル和,移動平均,差分法)
2015年度GPGPU実践プログラミング 第4回 GPUでの並列プログラミング(ベクトル和,移動平均,差分法)智啓 出川
 
2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア
2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア
2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア智啓 出川
 
2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術
2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術
2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術智啓 出川
 
2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法
2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法
2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法智啓 出川
 

Viewers also liked (20)

2015年度GPGPU実践基礎工学 第11回 GPUでの並列 プログラミング(ベクトル和)
2015年度GPGPU実践基礎工学 第11回 GPUでの並列プログラミング(ベクトル和)2015年度GPGPU実践基礎工学 第11回 GPUでの並列プログラミング(ベクトル和)
2015年度GPGPU実践基礎工学 第11回 GPUでの並列 プログラミング(ベクトル和)
 
2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造
2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造
2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造
 
2015年度GPGPU実践プログラミング 第14回 N体問題
2015年度GPGPU実践プログラミング 第14回 N体問題2015年度GPGPU実践プログラミング 第14回 N体問題
2015年度GPGPU実践プログラミング 第14回 N体問題
 
2015年度GPGPU実践プログラミング 第13回 多粒子の運動
2015年度GPGPU実践プログラミング 第13回 多粒子の運動2015年度GPGPU実践プログラミング 第13回 多粒子の運動
2015年度GPGPU実践プログラミング 第13回 多粒子の運動
 
2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史
2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史
2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史
 
2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ
 
2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)
2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)
2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)
 
2015年度GPGPU実践プログラミング 第11回 画像処理
2015年度GPGPU実践プログラミング 第11回 画像処理2015年度GPGPU実践プログラミング 第11回 画像処理
2015年度GPGPU実践プログラミング 第11回 画像処理
 
2015年度GPGPU実践プログラミング 第7回 総和計算
2015年度GPGPU実践プログラミング 第7回 総和計算2015年度GPGPU実践プログラミング 第7回 総和計算
2015年度GPGPU実践プログラミング 第7回 総和計算
 
2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例
2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例
2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例
 
2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造
2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造
2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造
 
2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)
2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)
2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)
 
2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)
2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)
2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)
 
2015年度GPGPU実践プログラミング 第9回 行列計算(行列-行列積)
2015年度GPGPU実践プログラミング 第9回 行列計算(行列-行列積)2015年度GPGPU実践プログラミング 第9回 行列計算(行列-行列積)
2015年度GPGPU実践プログラミング 第9回 行列計算(行列-行列積)
 
2015年度GPGPU実践プログラミング 第12回 偏微分方程式の差分計算
2015年度GPGPU実践プログラミング 第12回 偏微分方程式の差分計算2015年度GPGPU実践プログラミング 第12回 偏微分方程式の差分計算
2015年度GPGPU実践プログラミング 第12回 偏微分方程式の差分計算
 
2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール
2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール
2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール
 
2015年度GPGPU実践プログラミング 第4回 GPUでの並列プログラミング(ベクトル和,移動平均,差分法)
2015年度GPGPU実践プログラミング 第4回 GPUでの並列プログラミング(ベクトル和,移動平均,差分法)2015年度GPGPU実践プログラミング 第4回 GPUでの並列プログラミング(ベクトル和,移動平均,差分法)
2015年度GPGPU実践プログラミング 第4回 GPUでの並列プログラミング(ベクトル和,移動平均,差分法)
 
2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア
2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア
2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア
 
2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術
2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術
2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術
 
2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法
2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法
2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法
 

Similar to 2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層

2015年度先端GPGPUシミュレーション工学特論 第4回 GPUのメモリ階層の詳細 (共有メモリ)
2015年度先端GPGPUシミュレーション工学特論 第4回 GPUのメモリ階層の詳細(共有メモリ)2015年度先端GPGPUシミュレーション工学特論 第4回 GPUのメモリ階層の詳細(共有メモリ)
2015年度先端GPGPUシミュレーション工学特論 第4回 GPUのメモリ階層の詳細 (共有メモリ)智啓 出川
 
2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境
2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境
2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境智啓 出川
 
20170421 tensor flowusergroup
20170421 tensor flowusergroup20170421 tensor flowusergroup
20170421 tensor flowusergroupManaMurakami1
 
45分で理解する 最近のスパコン事情 斉藤之雄
45分で理解する 最近のスパコン事情 斉藤之雄45分で理解する 最近のスパコン事情 斉藤之雄
45分で理解する 最近のスパコン事情 斉藤之雄Yukio Saito
 
A100 GPU 搭載! P4d インスタンス 使いこなしのコツ
A100 GPU 搭載! P4d インスタンス使いこなしのコツA100 GPU 搭載! P4d インスタンス使いこなしのコツ
A100 GPU 搭載! P4d インスタンス 使いこなしのコツKuninobu SaSaki
 
High speed-pc-router 201505
High speed-pc-router 201505High speed-pc-router 201505
High speed-pc-router 201505ykuga
 
FPGA・リコンフィギャラブルシステム研究の最新動向
FPGA・リコンフィギャラブルシステム研究の最新動向FPGA・リコンフィギャラブルシステム研究の最新動向
FPGA・リコンフィギャラブルシステム研究の最新動向Shinya Takamaeda-Y
 
【A-1】AIを支えるGPUコンピューティングの今
【A-1】AIを支えるGPUコンピューティングの今【A-1】AIを支えるGPUコンピューティングの今
【A-1】AIを支えるGPUコンピューティングの今Developers Summit
 
「Windows Azure でスーパーコンピューティング!」for Microsoft MVP camp 2014 大阪会場
「Windows Azure でスーパーコンピューティング!」for Microsoft MVP camp 2014 大阪会場「Windows Azure でスーパーコンピューティング!」for Microsoft MVP camp 2014 大阪会場
「Windows Azure でスーパーコンピューティング!」for Microsoft MVP camp 2014 大阪会場幸智 Yukinori 黒田 Kuroda
 
機械学習とこれを支える並列計算: ディープラーニング・スーパーコンピューターの応用について
機械学習とこれを支える並列計算: ディープラーニング・スーパーコンピューターの応用について機械学習とこれを支える並列計算: ディープラーニング・スーパーコンピューターの応用について
機械学習とこれを支える並列計算: ディープラーニング・スーパーコンピューターの応用についてハイシンク創研 / Laboratory of Hi-Think Corporation
 
1070: CUDA プログラミング入門
1070: CUDA プログラミング入門1070: CUDA プログラミング入門
1070: CUDA プログラミング入門NVIDIA Japan
 
Getting Started with Jetson Nano
Getting Started with Jetson NanoGetting Started with Jetson Nano
Getting Started with Jetson NanoNVIDIA Japan
 
NVIDIA 更新情報: Tesla P100 PCIe/cuDNN 5.1
NVIDIA 更新情報: Tesla P100 PCIe/cuDNN 5.1NVIDIA 更新情報: Tesla P100 PCIe/cuDNN 5.1
NVIDIA 更新情報: Tesla P100 PCIe/cuDNN 5.1NVIDIA Japan
 
2021 03-09-ac ri-nngen
2021 03-09-ac ri-nngen2021 03-09-ac ri-nngen
2021 03-09-ac ri-nngen直久 住川
 
ZynqMPのブートとパワーマネージメント : (ZynqMP Boot and Power Management)
ZynqMPのブートとパワーマネージメント : (ZynqMP Boot and Power Management)ZynqMPのブートとパワーマネージメント : (ZynqMP Boot and Power Management)
ZynqMPのブートとパワーマネージメント : (ZynqMP Boot and Power Management)Mr. Vengineer
 
20170726 py data.tokyo
20170726 py data.tokyo20170726 py data.tokyo
20170726 py data.tokyoManaMurakami1
 
MemoryPlus Workshop
MemoryPlus WorkshopMemoryPlus Workshop
MemoryPlus WorkshopHitoshi Sato
 
OSC 2012 Hokkaido でのプレゼン資料
OSC 2012 Hokkaido でのプレゼン資料OSC 2012 Hokkaido でのプレゼン資料
OSC 2012 Hokkaido でのプレゼン資料Shin-ya Koga
 
2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ智啓 出川
 

Similar to 2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層 (20)

2015年度先端GPGPUシミュレーション工学特論 第4回 GPUのメモリ階層の詳細 (共有メモリ)
2015年度先端GPGPUシミュレーション工学特論 第4回 GPUのメモリ階層の詳細(共有メモリ)2015年度先端GPGPUシミュレーション工学特論 第4回 GPUのメモリ階層の詳細(共有メモリ)
2015年度先端GPGPUシミュレーション工学特論 第4回 GPUのメモリ階層の詳細 (共有メモリ)
 
2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境
2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境
2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境
 
20170421 tensor flowusergroup
20170421 tensor flowusergroup20170421 tensor flowusergroup
20170421 tensor flowusergroup
 
POWER8ここだけの話
POWER8ここだけの話POWER8ここだけの話
POWER8ここだけの話
 
45分で理解する 最近のスパコン事情 斉藤之雄
45分で理解する 最近のスパコン事情 斉藤之雄45分で理解する 最近のスパコン事情 斉藤之雄
45分で理解する 最近のスパコン事情 斉藤之雄
 
A100 GPU 搭載! P4d インスタンス 使いこなしのコツ
A100 GPU 搭載! P4d インスタンス使いこなしのコツA100 GPU 搭載! P4d インスタンス使いこなしのコツ
A100 GPU 搭載! P4d インスタンス 使いこなしのコツ
 
High speed-pc-router 201505
High speed-pc-router 201505High speed-pc-router 201505
High speed-pc-router 201505
 
FPGA・リコンフィギャラブルシステム研究の最新動向
FPGA・リコンフィギャラブルシステム研究の最新動向FPGA・リコンフィギャラブルシステム研究の最新動向
FPGA・リコンフィギャラブルシステム研究の最新動向
 
【A-1】AIを支えるGPUコンピューティングの今
【A-1】AIを支えるGPUコンピューティングの今【A-1】AIを支えるGPUコンピューティングの今
【A-1】AIを支えるGPUコンピューティングの今
 
「Windows Azure でスーパーコンピューティング!」for Microsoft MVP camp 2014 大阪会場
「Windows Azure でスーパーコンピューティング!」for Microsoft MVP camp 2014 大阪会場「Windows Azure でスーパーコンピューティング!」for Microsoft MVP camp 2014 大阪会場
「Windows Azure でスーパーコンピューティング!」for Microsoft MVP camp 2014 大阪会場
 
機械学習とこれを支える並列計算: ディープラーニング・スーパーコンピューターの応用について
機械学習とこれを支える並列計算: ディープラーニング・スーパーコンピューターの応用について機械学習とこれを支える並列計算: ディープラーニング・スーパーコンピューターの応用について
機械学習とこれを支える並列計算: ディープラーニング・スーパーコンピューターの応用について
 
1070: CUDA プログラミング入門
1070: CUDA プログラミング入門1070: CUDA プログラミング入門
1070: CUDA プログラミング入門
 
Getting Started with Jetson Nano
Getting Started with Jetson NanoGetting Started with Jetson Nano
Getting Started with Jetson Nano
 
NVIDIA 更新情報: Tesla P100 PCIe/cuDNN 5.1
NVIDIA 更新情報: Tesla P100 PCIe/cuDNN 5.1NVIDIA 更新情報: Tesla P100 PCIe/cuDNN 5.1
NVIDIA 更新情報: Tesla P100 PCIe/cuDNN 5.1
 
2021 03-09-ac ri-nngen
2021 03-09-ac ri-nngen2021 03-09-ac ri-nngen
2021 03-09-ac ri-nngen
 
ZynqMPのブートとパワーマネージメント : (ZynqMP Boot and Power Management)
ZynqMPのブートとパワーマネージメント : (ZynqMP Boot and Power Management)ZynqMPのブートとパワーマネージメント : (ZynqMP Boot and Power Management)
ZynqMPのブートとパワーマネージメント : (ZynqMP Boot and Power Management)
 
20170726 py data.tokyo
20170726 py data.tokyo20170726 py data.tokyo
20170726 py data.tokyo
 
MemoryPlus Workshop
MemoryPlus WorkshopMemoryPlus Workshop
MemoryPlus Workshop
 
OSC 2012 Hokkaido でのプレゼン資料
OSC 2012 Hokkaido でのプレゼン資料OSC 2012 Hokkaido でのプレゼン資料
OSC 2012 Hokkaido でのプレゼン資料
 
2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ
 

More from 智啓 出川

Fortranが拓く世界、VSCodeが架ける橋
Fortranが拓く世界、VSCodeが架ける橋Fortranが拓く世界、VSCodeが架ける橋
Fortranが拓く世界、VSCodeが架ける橋智啓 出川
 
Very helpful python code to find coefficients of the finite difference method
Very helpful python code to find coefficients of the finite difference methodVery helpful python code to find coefficients of the finite difference method
Very helpful python code to find coefficients of the finite difference method智啓 出川
 
Why do we confuse String and Array of Characters in Fortran?
Why do we confuse String and Array of Characters in Fortran?Why do we confuse String and Array of Characters in Fortran?
Why do we confuse String and Array of Characters in Fortran?智啓 出川
 
Pythonによる累乗近似
Pythonによる累乗近似Pythonによる累乗近似
Pythonによる累乗近似智啓 出川
 
数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)
数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)
数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)智啓 出川
 
オブジェクト指向Fortranが拓く(はずだった)新しい世界
オブジェクト指向Fortranが拓く(はずだった)新しい世界オブジェクト指向Fortranが拓く(はずだった)新しい世界
オブジェクト指向Fortranが拓く(はずだった)新しい世界智啓 出川
 
Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...
Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...
Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...智啓 出川
 
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE) GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE) 智啓 出川
 
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS) GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS) 智啓 出川
 
GPGPU Education at Nagaoka University of Technology: A Trial Run
GPGPU Education at Nagaoka University of Technology: A Trial RunGPGPU Education at Nagaoka University of Technology: A Trial Run
GPGPU Education at Nagaoka University of Technology: A Trial Run智啓 出川
 
Cuda fortranの利便性を高めるfortran言語の機能
Cuda fortranの利便性を高めるfortran言語の機能Cuda fortranの利便性を高めるfortran言語の機能
Cuda fortranの利便性を高めるfortran言語の機能智啓 出川
 
PGI CUDA FortranとGPU最適化ライブラリの一連携法
PGI CUDA FortranとGPU最適化ライブラリの一連携法PGI CUDA FortranとGPU最適化ライブラリの一連携法
PGI CUDA FortranとGPU最適化ライブラリの一連携法智啓 出川
 
教育機関でのJetsonの活用の可能性
教育機関でのJetsonの活用の可能性教育機関でのJetsonの活用の可能性
教育機関でのJetsonの活用の可能性智啓 出川
 
GPGPU Seminar (GPGPU and CUDA Fortran)
GPGPU Seminar (GPGPU and CUDA Fortran)GPGPU Seminar (GPGPU and CUDA Fortran)
GPGPU Seminar (GPGPU and CUDA Fortran)智啓 出川
 
GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)
GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)
GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)智啓 出川
 
GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調
2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調
2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用
2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用
2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用 (高度な最適化)
2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用(高度な最適化)2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用(高度な最適化)
2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用 (高度な最適化)智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用 (支配方程式,CPUプログラム)
2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用(支配方程式,CPUプログラム)2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用(支配方程式,CPUプログラム)
2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用 (支配方程式,CPUプログラム)智啓 出川
 

More from 智啓 出川 (20)

Fortranが拓く世界、VSCodeが架ける橋
Fortranが拓く世界、VSCodeが架ける橋Fortranが拓く世界、VSCodeが架ける橋
Fortranが拓く世界、VSCodeが架ける橋
 
Very helpful python code to find coefficients of the finite difference method
Very helpful python code to find coefficients of the finite difference methodVery helpful python code to find coefficients of the finite difference method
Very helpful python code to find coefficients of the finite difference method
 
Why do we confuse String and Array of Characters in Fortran?
Why do we confuse String and Array of Characters in Fortran?Why do we confuse String and Array of Characters in Fortran?
Why do we confuse String and Array of Characters in Fortran?
 
Pythonによる累乗近似
Pythonによる累乗近似Pythonによる累乗近似
Pythonによる累乗近似
 
数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)
数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)
数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)
 
オブジェクト指向Fortranが拓く(はずだった)新しい世界
オブジェクト指向Fortranが拓く(はずだった)新しい世界オブジェクト指向Fortranが拓く(はずだった)新しい世界
オブジェクト指向Fortranが拓く(はずだった)新しい世界
 
Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...
Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...
Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...
 
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE) GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
 
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS) GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
 
GPGPU Education at Nagaoka University of Technology: A Trial Run
GPGPU Education at Nagaoka University of Technology: A Trial RunGPGPU Education at Nagaoka University of Technology: A Trial Run
GPGPU Education at Nagaoka University of Technology: A Trial Run
 
Cuda fortranの利便性を高めるfortran言語の機能
Cuda fortranの利便性を高めるfortran言語の機能Cuda fortranの利便性を高めるfortran言語の機能
Cuda fortranの利便性を高めるfortran言語の機能
 
PGI CUDA FortranとGPU最適化ライブラリの一連携法
PGI CUDA FortranとGPU最適化ライブラリの一連携法PGI CUDA FortranとGPU最適化ライブラリの一連携法
PGI CUDA FortranとGPU最適化ライブラリの一連携法
 
教育機関でのJetsonの活用の可能性
教育機関でのJetsonの活用の可能性教育機関でのJetsonの活用の可能性
教育機関でのJetsonの活用の可能性
 
GPGPU Seminar (GPGPU and CUDA Fortran)
GPGPU Seminar (GPGPU and CUDA Fortran)GPGPU Seminar (GPGPU and CUDA Fortran)
GPGPU Seminar (GPGPU and CUDA Fortran)
 
GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)
GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)
GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)
 
GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)
 
2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調
2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調
2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調
 
2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用
2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用
2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用
 
2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用 (高度な最適化)
2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用(高度な最適化)2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用(高度な最適化)
2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用 (高度な最適化)
 
2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用 (支配方程式,CPUプログラム)
2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用(支配方程式,CPUプログラム)2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用(支配方程式,CPUプログラム)
2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用 (支配方程式,CPUプログラム)
 

2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層