More Related Content Similar to GPGPU Seminar (GPGPU and CUDA Fortran) (20) GPGPU Seminar (GPGPU and CUDA Fortran)3. GPU(Graphics Processing Unit)とは
画像処理専用のハードウェア
具体的には画像処理用のチップ
チップ単体では販売されていない
PCI‐Exカードで販売
チップ単体と区別せずにGPUと呼ぶことも多い
ノートPCに搭載
PCI‐Exカードとして販売されるGPUには,ビデオメモリと呼ばれ
るDRAMが搭載
GPGPU講習会3 2016/01/13
4. GPU(Graphics Processing Unit)とは
GPGPU講習会4
代表的な製品
NVIDIA GeForce
AMD Radeon
Intel HD Graphics(内蔵)
代表的な用途
3Dグラフィックス処理
3Dゲーム,3DCAD,3DCG作成
エンコード・デコード支援
GPU上に専用チップを搭載していることが多い
デスクトップPCのGUI処理
Windows Aeroが比較的高性能なGPUを要求
2016/01/13
5. GPU(Graphics Processing Unit)の役割
グラフィックスを表示するために様々な処理を行い,処
理の結果をディスプレイに出力
3次元グラフィックスの発展に伴って役割が大きく変化
3次元座標変換
ポリゴンとピクセルの
対応付け
ピクセル色計算
テクスチャ参照
フレームバッファ(ビデ
オメモリ)への書き込み
ディスプレイ出力
CPU
ディスプレイコントローラ GPU
3次元座標変換
ポリゴンとピクセルの
対応付け
ピクセル色計算
テクスチャ参照
フレームバッファ(ビデ
オメモリ)への書き込み
ディスプレイ出力
現在過去
CPUが3D描画
の演算を実行
GPUが出力
描画情報
画面出力
GPUが演算から
出力までの全て
を担当
CPUは描画情報
の生成やGPUへ
の情報の引き渡
し , GPU の 制 御
を行う
描画情報
画面出力
GPGPU講習会5 2016/01/13
13. Teslaアーキテクチャ*
GPGPU講習会
Tesla C1060の仕様
SM数 30
CUDA Core数 240(=8 Core/SM×30 SM)
キャッシュを搭載せず
13
*CUDAのサポートから外れます
2016/01/13
SP SP
SP SP
SP SP
SP SP
SFU SFU
16 KB
Shared Memory
Register File
(16384×32‐bit)
Streaming
Multiprocessor
SMSMSM
14. Teslaアーキテクチャの構造
GPGPU講習会
Tesla C1060の仕様
CUDAコア数(単精度) 240 Cores
CUDAコアクロック周波数 1,296 MHz
単精度演算ピーク性能 622*1
(933*2
) GFLOPS
倍精度演算ユニット数 30*3
Units
倍精度演算ピーク性能 78 GFLOPS
メモリクロック周波数 800 MHz
メモリバス幅 512 bit
最大メモリバンド幅*4
102 GB/s
*1単精度演算ピーク性能 = コアクロック周波数×コア数×命令の同時発行数(2)
*2CUDA CoreとSFUが同時に命令を発行できれば1296 MHz×240×3
*3一つのSMに倍精度演算器が一つ搭載(と言われている)
*4最大メモリバンド幅=メモリクロック周波数×メモリバス幅/8×2(Double Data Rate)
14 2016/01/13
15. Fermiアーキテクチャ
GPGPU講習会
Tesla M2050の仕様
SM数 14
CUDA Core数 448(=32 Core/SM×14 SM)
L1/L2 キャッシュを搭載
ECC(誤り訂正機能)を搭載
15 2016/01/13
Register File
(16384 × 32‐bit)
64 KB Shared
Memory / L1 Cache
SM
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
SFU×4
L2 Cache
GigaThread Engine
PCI Express 3.0 Host Interface
Memory Controller
GPC
Raster Engine
GPC
Raster Engine
SM
Raster Engine
GPC
Raster Engine
GPC
Memory ControllerMemory Controller
Memory ControllerMemory ControllerMemory Controller
詳細はhttp://www.nvidia.co.jp/docs/IO/
81860/NVIDIA_Fermi_Architecture_Whitep
aper_FINAL_J.pdfを参照のこと
17. Keplerアーキテクチャの構造
GPGPU講習会
Tesla K20c/mの仕様
SMX数 13
Streaming Multiprocessor eXtreme (?)
CUDA Core数 2,496(=192 Core/SM×13 SMX)
17 2016/01/13
詳細はhttps://www.nvidia.co.jp/content
/apac/pdf/tesla/nvidia‐kepler‐gk110‐ar
chitecture‐whitepaper‐jp.pdfを参照のこと
Register File (65536 × 32‐bit)
64 KB Shared Memory / L1 Cache
48 KB Read‐Only Data Cache
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
DP Unit
SMX
SMX
L2 Cache
GigaThread Engine
PCI Express 3.0 Host Interface
Memory ControllerMemory ControllerMemory Controller
Memory ControllerMemory ControllerMemory Controller
19. Maxwellアーキテクチャ
GeForce GTX TITAN Xの仕様
SM数 24
CUDA Core数 3,072(=128 Core/SM×24 SM)
GPGPU講習会19 2016/01/13
第1世代の詳細はhttps://www.nvidia.co.jp/cont
ent/product‐detail‐pages/geforce‐gtx‐750‐ti
/geforce‐gtx‐750ti‐whitepaper.pdfを参照のこと
64 KB Shared Memory
L1 Cache
SMM
Register File
(16,384 × 32‐
bit)
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
L1 Cache
Register File
(16,384 × 32‐
bit)
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
Register File
(16,384 × 32‐
bit)
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
Register File
(16,384 × 32‐
bit)
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
SFU
SFU
SFU
SFU
SFU
SFU
SFU
SFU
PolyMorph Engine 3.0
SMM
Raster Engine
GPC
Raster Engine
GPC
L2 Cache
GigaThread Engine
PCI Express 3.0 Host Interface
Memory Controller
Raster Engine
GPC
Raster Engine
GPC
Memory Controller
Memory ControllerMemory Controller
20. Maxwellアーキテクチャ
GeForce GTX TITAN Xの仕様*
CUDAコア数(単精度) 3,072 Cores
CUDAコアクロック周波数 1,002 MHz
単精度演算ピーク性能 6.14 TFLOPS
倍精度演算ユニット数 0*1
Units
倍精度演算ピーク性能 192 GFLOPS*2
メモリクロック周波数 3.5 GHz*3
メモリバス幅 384 bit
最大メモリバンド幅 336.5 GB/s
*1http://www.4gamer.net/games/121/G012181/20141225075/
*2倍精度演算は単精度演算の性能の1/32 (1/16 Flop/Core/clock)
*3DDR(Double Data Rate) 7GHz相当と書かれている場合もある
GPGPU講習会
http://http://www.geforce.com/hardware/desk
top‐gpus/geforce‐gtx‐titan‐x/specifications
*http://ja.wikipedia.org/wiki/FLOPS
20 2016/01/13
21. Pascalアーキテクチャ
2016年にリリース予定
倍精度演算器を搭載予定
NVLink
GPU同士やGPUとCPUを接続する独自の方式
通信(CPU ↔ メモリ ↔ PCI Express ↔ メモリ ↔ GPU)の
ボトルネックを解消(PCI Express3.0の5~12倍)
複数のGPUを使って大規模な計算が可能
3Dメモリ(High Bandwidth Memory, HBM)*
3次元積層技術を利用し,メモリの容量と帯域を大幅に増加
最大32GB,メモリ帯域1TB/s
GPGPU講習会
*http://pc.watch.impress.co.jp/docs/column/kaigai/20150421_698806.html
21 2016/01/13
22. Voltaアーキテクチャ
Pascalの後継
詳しい情報は不明
アメリカの次世代スーパーコンピュータへ採用予定
オークリッジ国立研究所 SUMMIT 150~300PFLOPS
ローレンス・リバモア研究所 SIERRA 100PFLOPS以上
地球シミュレータと同等の演算性能を1ノードで実現
現在Top500 2位のスーパーコンピュータと同じ電力で5~10
倍高速,サイズは1/5
GPGPU講習会
*http://www.4gamer.net/games/121/G012181/20141225075/
22 2016/01/13
24. TOP500 List(2015, Nov.)
スーパーコンピュータの性能の世界ランキング
GPUを搭載したコンピュータは2基だけ
GPGPU講習会24
http://www.top500.org/より引用
2016/01/13
計算機名称(設置国) アクセラレータ
実効性能[PFlop/s]
/ピーク性能[PFlop/s]
消費電力[MW]
1 Tianhe‐2 (China) Intel Xeon Phi 33.9/54.9 17.8
2 Titan (U.S.A.) NVIDIA K20x 17.6/27.1 8.20
3 Sequoia (U.S.A.) − 17.2/20.1 7.90
4 K computer (Japan) − 10.5/11.3 12.7
5 Mira (U.S.A.) − 8.59/10.1 3.95
6 Trinity (U.S.A.) − 8.10/11.1
7 Piz Daint (Switzerland) NVIDIA K20x 6.27/7.79 2.33
8 Hazel Hen (Germany) ‐ 5.64/7.40
9 Shaheen II(Saudi Arabia) ‐ 5.54/7.24 2.83
10 Stampede (U.S.A.) Intel Xeon Phi 5.17/8.52 4.51
28. CPUの性能向上
FLOPS = 1コアの演算性能
× コア数
× CPUの動作周波数
1コアの演算性能の向上
演算器(トランジスタ)の増加
コア数の増加
トランジスタ数の増加
CPUの動作周波数
回路の効率化や印可電圧の向上
劇的な性能向上は期待できない
コンパイラの最適化を利用
複数のコアを使うように
プログラムを書かないと
速くならない
GPGPU講習会28 2016/01/13
30. Green500(2015, Nov.)
TOP3の計算機がそれぞれ異なるアクセラレータを搭載
インターネットのサービス提供に利用されている(と思わ
れる)計算機が大量にランクイン
GPGPU講習会30
http://www.green500.org/より引用
2016/01/13
計算機名称 アクセラレータ GFLOPS/W 消費電力[kW]
1 Shoubu PEZY‐SC 7.03 50.32
2 TSUBAME‐KFC NVIDIA Tesla K80 5.33 51.13
3 ASUS ESC4000 AMD FirePro S9150 5.27 57.15
4 Sugon Cluster NVIDIA Tesla K80 4.78 65.00
5 Xstream NVIDIA Tesla K80 4.11 190.0
6 Inspur TS10000 NVIDIA Tesla K40 3.86 58.00
7 Inspur TS10000 NVIDIA Tesla K40 3.78 110.0
8 Inspur TS10000 NVIDIA Tesla K40 3.78 110.0
9 Inspur TS10000 NVIDIA Tesla K40 3.78 110.0
10 Inspur TS10000 NVIDIA Tesla K40 3.78 110.0
54. GPUの選択
計算機がGPUを複数搭載している場合
CUDAで利用するGPUを選択
CUDA APIを利用したGPUの選択
cudaSetDevice()命令
GPGPU講習会
program main
use cudafor
変数宣言 !ここでは標準でGPU0が使われる
GPUやCPUを使った処理 !
stat = cudaSetDevice(3) !ここからGPU3が使われる
...
end program main
54 2016/01/13
57. GPU(Graphics Processing Unit)とは
画像処理専用のハードウェア
具体的には画像処理用のチップ
チップ単体では販売されていない
PCI‐Exカードで販売
チップ単体と区別せずにGPUと呼ぶことも多い
ノートPCに搭載
PCI‐Exカードとして販売されるGPUには,ビデオメモリと呼ばれ
るDRAMが搭載
2016/01/13GPGPU講習会57
59. Fermiアーキテクチャ
2016/01/13GPGPU講習会59
Tesla M2050の仕様
SM数 14
CUDA Core数 448(=32 Core/SM×14 SM)
動作周波数 1,150 MHz
単精度演算ピーク性能 1.03 TFLOPS
Register File
(16384 × 32‐bit)
64 KB Shared
Memory / L1 Cache
SM
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
Core
SFU×4
L2 Cache
GigaThread Engine
PCI Express 3.0 Host Interface
Memory Controller
GPC
Raster Engine
GPC
Raster Engine
SM
Raster Engine
GPC
Raster Engine
GPC
Memory ControllerMemory Controller
Memory ControllerMemory ControllerMemory Controller
詳細はhttp://www.nvidia.co.jp/docs/IO/
81860/NVIDIA_Fermi_Architecture_Whitep
aper_FINAL_J.pdfを参照のこと
62. プログラマブルシェーダを用いた汎用計算
グラフィックスAPI(DirectX, OpenGL)による描画処理
+シェーダ言語(HLSL, GLSL)による演算
void gpumain(){
vec4 ColorA = vec4(0.0, 0.0, 0.0, 0.0); vec4 ColorB = vec4(0.0, 0.0, 0.0, 0.0);
vec2 TexA = vec2(0.0, 0.0); vec2 TexB = vec2(0.0, 0.0);
TexA.x = gl_FragCoord.x; TexA.y = gl_FragCoord.y;
TexB.x = gl_FragCoord.x; TexB.y = gl_FragCoord.y;
ColorA = texRECT( texUnit0, TexA );
ColorB = texRECT( texUnit1, TexB );
gl_FragColor = F_ALPHA*ColorA + F_BETA*ColorB;
}
void main(){
glutInit( &argc, argv );
glutInitWindowSize(64,64);glutCreateWindow("GpgpuHelloWorld");
glGenFramebuffersEXT(1, &g_fb);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_fb);
glGenTextures(4, g_nTexID); // create (reference to) a new texture
glBindTexture(opt1, texid);
glTexParameteri(opt1, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(......);
glTexImage2D(opt1, 0, opt2, width, height, 0, GL_RGBA, GL_FLOAT, 0);
……(以下省略)
GPUの処理(GLSL)
各ピクセルに対して実行
CPUの処理
(OpenGL)
シェーダ言語を用いた配列加算
(c=*a + *b)の例
GPGPU講習会62 2016/01/13
68. Hello World
何を確認するか
最小構成のプログラムの作り方
ファイル命名規則(拡張子は.f90)
コンパイルの方法(gfortran, pgf90等を使用)
program main
implicit none
print *,"hello world"
end program main
GPGPU講習会68 2016/01/13
helloworld.f90
69. CUDA FortranでHello World
何を確認するか
最小構成のプログラムの作り方
ファイル命名規則(拡張子は.cuf)
コンパイルの方法(pgf90を使用)
program main
implicit none
print *,"hello world"
end program main
GPGPU講習会69
program main
implicit none
print *,"hello world"
end program main
違いは拡張子だけ?
2016/01/13
helloworld.cuf helloworld.f90
70. CUDA Fortranプログラムのコンパイル
ソースファイルの拡張子は.cuf
pgf90を用いてコンパイル*
プリプロセッサがソースをホストコード(CPUが処理する内容)
とデバイスコード(GPUが処理する内容)に分離
ホストコードはPGIコンパイラがコンパイル
デバイスコードはCUDA Cのコードへと変換
helloworld.cufにはCPUで処理する箇所しかない
GPGPU講習会70 2016/01/13
*伊藤智義 編,GPUプログラミング入門,講談社,2013,p.142.
71. CUDA FortranでHello World
CUDA Fortran専用の処理を追加
2016/01/13GPGPU講習会71
module cuf_kernel
implicit none
contains
attributes(global) subroutine kernel()
end subroutine kernel
end module cuf_kernel
program main
use cudafor
use cuf_kernel
implicit none
call kernel<<<1,1>>>()
print *,"hello world"
end program main
GPUで実行されるサブルーチン
(カーネル)
attributes(global)が追加
・・・
通常のサブルーチン呼出と
は異なり,<<<>>>が追加
・・・
helloworld_kernel.cuf
86. GPUの並列化の階層
グリッド-ブロック-スレッドの3階層
グリッド(Grid)
並列に実行する処理
GPUが処理を担当する領域全体
スレッド(Thread)
GPUの処理の基本単位
CPUのスレッドと同じ
ブロック(Block)もしくはスレッドブロック(Thread Block)*
スレッドの集まり
GPGPU講習会86 2016/01/13
*スレッドブロックだと長い上にスレッドや変数名
との兼ね合いで混乱を招くのでブロックで統一
90. 各階層の値の設定
設定の条件
GPUの世代によって設定できる上限値が変化
確認の方法
pgaccelinfo
deviceQuery
GPU Computing SDKに含まれているサンプル
CUDA Programming Guide
https://docs.nvidia.com/cuda/cuda‐c‐programming‐
guide/#compute‐capabilities
2016/01/13GPGPU講習会90
92. pgaccelinfo実行結果
Revision Number: 2.0
Global Memory Size: 2817982464
Warp Size: 32
Maximum Threads per Block: 1024
Maximum Block Dimensions: 1024, 1024, 64
Maximum Grid Dimensions: 65535 x 65535 x 65535
GPUの世代
(どのような機能を有しているか)
実
行
時
の
パ
ラ
メ
ー
タ
選
択
の
際
に
重
要
各方向の最大値
1ブロックあたりのスレッド数は最大1024
(1024, 1, 1), (1, 1024, 1)
(32, 32, 1), (4, 4, 64)など
2016/01/13GPGPU講習会92
99. GPUへの移植(メモリの取り扱い)
GPGPU講習会99
ベクトルa,b,cを確保し,a,bの値を読んでcに書き込む
ホスト(CPU)にはプロセッサとメモリが存在
デバイス(GPU)にもプロセッサとメモリが存在
デバイスからホストのメモリは(原則)直接読み書きできない
real :: a(N),b(N),c(N)
do i=1,N
print *,a(i),b(i),c(i);
end do
a
b
c
attributes(global)
subroutine add()
do i=1,N
c(i) = a(i)+b(i)
end do
end subroutine add
2016/01/13
103. module vectoradd_kernel
implicit none
integer,parameter :: N=2**20
contains
attributes(global)&
subroutine add(a, b, c)
implicit none
real :: a(N)
real :: b(N)
real :: c(N)
integer :: i
do i=1,N
c(i) = a(i) + b(i)
end do
end subroutine add
end module vectoradd_kernel
program main
use vectoradd_kernel
use cudafor
implicit none
real,allocatable,device :: a(:)
real,allocatable,device :: b(:)
real,allocatable,device :: c(:)
allocate(a(N)); a=1.0
allocate(b(N)); b=2.0
allocate(c(N)); c=0.0
call add<<<1,1>>>(a,b,c)
deallocate(a)
deallocate(b)
deallocate(c)
end program main
GPUプログラム(1スレッド実行版)
GPGPU講習会103 2016/01/13
vectoradd_1threa
d.cuf
104. module vectoradd_kernel
implicit none
integer,parameter :: N=2**20
contains
attributes(global)&
subroutine add(a, b, c)
implicit none
real :: a(N)
real :: b(N)
real :: c(N)
integer :: i
do i=1,N
c(i) = a(i) + b(i)
end do
end subroutine add
end module vectoradd_kernel
program main
use vectoradd_kernel
use cudafor
implicit none
real,allocatable,device :: a(:)
real,allocatable,device :: b(:)
real,allocatable,device :: c(:)
allocate(a(N)); a=1.0
allocate(b(N)); b=2.0
allocate(c(N)); c=0.0
call add<<<1,1>>>(a,b,c)
deallocate(a)
deallocate(b)
deallocate(c)
end program main
GPUプログラム(1スレッド実行版)
GPGPU講習会104
GPUカーネ
ルの目印
並列実行の
度合を指定
2016/01/13
vectoradd_1threa
d.cuf
device属性
を付与
108. 実行結果
GPGPU講習会108
プロファイルの一連の流れ
method カーネルや関数(API)の名称
gputime GPU上で処理に要した時間(s単位)
cputime CPUで処理(=カーネル起動)に要した時間
実際の実行時間=cputime+gputime
occupancy GPUがどれだけ効率よく利用されているか
‐bash‐3.2$ pgf90 vectoradd_1thread.cuf プログラムをコンパイル
‐bash‐3.2$ export CUDA_PROFILE=1 環境変数CUDA_PROFILEを1にしてプロファイラを有効化
‐bash‐3.2$ ./a.out プログラムを実行(cuda_profile_0.logというファイルが作られる)
‐bash‐3.2$ cat cuda_profile_0.log cuda_profile_0.logの内容を画面に表示
# CUDA_PROFILE_LOG_VERSION 2.0
# CUDA_DEVICE 0 Tesla M2050
# TIMESTAMPFACTOR fffff5f0d8759ef8
method,gputime,cputime,occupancy
method=[ __pgi_dev_cumemset_4f ] gputime=[ 36.320 ] cputime=[ 16.000 ] occupancy=[ 1.000 ]
method=[ __pgi_dev_cumemset_4f ] gputime=[ 35.200 ] cputime=[ 8.000 ] occupancy=[ 1.000 ]
method=[ __pgi_dev_cumemset_4f ] gputime=[ 35.104 ] cputime=[ 7.000 ] occupancy=[ 1.000 ]
method=[ add ] gputime=[ 206041.375 ] cputime=[ 6.000 ] occupancy=[ 0.021 ]
2016/01/13
112. module vectoradd_kernel
implicit none
integer,parameter :: N=2**20
contains
attributes(global) &
subroutine add(a, x, b, y, c)
implicit none
real :: a(N)
real :: b(N)
real :: c(N)
real,value :: x,y !値渡し
integer :: i
do i=1,N
c(i) = x*a(i) + y*b(i)
end do
end subroutine add
end module vectoradd_kernel
program main
use vectoradd_kernel
use cudafor
implicit none
real,allocatable,device :: a(:)
real,allocatable,device :: b(:)
real,allocatable,device :: c(:)
real,allocatable :: host_c(:)
allocate(a(N)); a=1.0
allocate(b(N)); b=2.0
allocate(c(N)); c=0.0
allocate(host_c(N))
call add<<<1,1>>>(a,1.0,b,2.0,c)
host_c = c
print *,sum(host_c)/N
deallocate(a)
deallocate(b)
deallocate(c)
deallocate(host_c)
end program main
GPUプログラム(双方向コピー)
GPGPU講習会
vectoradd_1thread_copy.cuf
112 2016/01/13
113. CUDAでカーネルを作成するときの制限
GPGPU講習会113
x,yはCPU側のメモリに存在
値渡し
CPU→GPUへ値がコピーされる
Fortranはポインタ渡し
値渡しにする場合はvalue
属性を付ける
attributes(global) &
subroutine add(a, x, b, y, c)
implicit none
real :: a(N)
real :: b(N)
real :: c(N)
real,value :: x,y !値渡し
integer :: i
do i=1,N
c(i) = x*a(i) + y*b(i)
end do
end subroutine add
:
program main
:
call add<<<1,1>>>(a,1.0,b,2.0,c)
:
end program main
2016/01/13
117. カーネルの書き換え
1スレッドが実行する処理になるよう変更
1スレッドがある添字 i の要素を担当
integer,parameter :: N=8
attributes(global) subroutine add(a, b, c)
real :: a(N)
real :: b(N)
real :: c(N)
integer :: i
i = ...
c(i) = a(i) + b(i)
end subroutine add
GPGPU講習会117
1スレッドがあるiの担当となり,変数
の初期化と足し算の計算を実行
2016/01/13
120. GPUの並列化の階層
グリッド-ブロック-スレッドの3階層
各階層の情報を参照できる変数
x,y,zを成分(component)にもつdim3派生型
グリッド(Grid)
gridDim グリッド内にあるブロックの数
ブロック(Block)
blockIdx ブロックに割り当てられた番号
blockDim ブロック内にあるスレッドの数
スレッド(Thread)
threadIdx スレッドに割り当てられた番号
GPGPU講習会120 2016/01/13
121. Hello Threads(Fermi世代以降)
<<< , >>>内の数字で表示される内容が変化
2016/01/13GPGPU講習会121
module cuf_kernel
implicit none
contains
attributes(global) subroutine hello()
print *,"gridDim'%'x",gridDim%x,"blockIdx'%'x",blockIdx%x,&
"blockDim'%'x",blockDim%x,"threadIdx'%'x",threadIdx%x
end subroutine hello
end module cuf_kernel
program main
use cudafor
use cuf_kernel
implicit none
integer :: stat
call hello<<<2,4>>>()
stat = cudaThreadSynchronize()
end program main
<<<>>>内の数字を変えると画面表示
される内容が変わる
<<<>>>内の数字とどのパラメータが
対応しているかを確認
・・・
hellothreads.cuf
126. 各スレッドが異なるiを参照するには
N=8, <<<1, 8>>>で実行
+ + + + + + + +
gridDim%x=1
blockIdx%x=1
blockDim%x=8threadIdx%x=
1 2 3 4 5 6 7 8
= (blockIdx%x‐1)*blockDim%x + threadIdx%x
2016/01/13GPGPU講習会126
c(i)
a(i)
b(i)
i= 1 2 3 4 5 6 7 8
127. 各スレッドが異なるiを参照するには
N=8, <<<4, 2>>>で実行
+ + + + + + + +
gridDim%x=4
blockIdx%x=1
blockDim%x=2threadIdx%x=
1 2 1 2 1 2 1 2
2016/01/13GPGPU講習会127
blockIdx%x=2
blockDim%x=2
blockIdx%x=3
blockDim%x=2
blockIdx%x=4
blockDim%x=2
= (blockIdx%x‐1)*blockDim%x + threadIdx%x
c(i)
a(i)
b(i)
i= 1 2 3 4 5 6 7 8
128. カーネルの書き換え
1スレッドが実行する処理になるよう変更
1スレッドがある添字 i の要素を担当
integer,parameter :: N=8
attributes(global) subroutine add(a, b, c)
real :: a(N)
real :: b(N)
real :: c(N)
integer :: i
i = (blockIdx%x‐1)*blockDim%x + threadIdx%x
c(i) = a(i) + b(i)
end subroutine add
GPGPU講習会128 2016/01/13
129. module vectoradd_kernel
implicit none
integer,parameter :: N=2**20
contains
attributes(global)&
subroutine add(a, b, c)
implicit none
real :: a(N)
real :: b(N)
real :: c(N)
integer :: i
i = (blockIdx%x‐1)*blockDim%x&
+ threadIdx%x
c(i) = a(i) + b(i)
end subroutine add
end module vectoradd_kernel
program main
use vectoradd_kernel
use cudafor
implicit none
real,allocatable,device :: a(:)
real,allocatable,device :: b(:)
real,allocatable,device :: c(:)
allocate(a(N)); a=1.0
allocate(b(N)); b=2.0
allocate(c(N)); c=0.0
call add<<<N/256,256>>>(a,b,c)
deallocate(a)
deallocate(b)
deallocate(c)
end program main
GPUで並列実行するプログラム
GPGPU講習会
vectoradd.cuf
129 2016/01/13
130. 処理時間の比較
配列の要素数 N=220
1ブロックあたりのスレッド数 256
GPUはマルチスレッドで処理しないと遅い
GPUを使えばどのような問題でも速くなるわけではない
並列に処理できるようプログラムを作成する必要がある
implementation Processing time [ms]
CPU (1 Thread) 4.55
GPU (1 Thread) 206
GPU (256 Threads) 0.115
GPGPU講習会130 2016/01/13
131. 各階層の値の設定
設定の条件
GPUの世代によって設定できる上限値が変化
確認の方法
pgaccelinfo
deviceQuery
GPU Computing SDKに含まれているサンプル
CUDA Programming Guide
https://docs.nvidia.com/cuda/cuda‐c‐programming‐
guide/#compute‐capabilities
階層の値によって実行時の性能が変化
GPUの一番基本的なチューニング
2016/01/13GPGPU講習会131
133. pgaccelinfo実行結果
Revision Number: 2.0
Global Memory Size: 2817982464
Warp Size: 32
Maximum Threads per Block: 1024
Maximum Block Dimensions: 1024, 1024, 64
Maximum Grid Dimensions: 65535 x 65535 x 65535
GPUの世代
(どのような機能を有しているか)
実
行
時
の
パ
ラ
メ
ー
タ
選
択
の
際
に
重
要
各方向の最大値
1ブロックあたりのスレッド数は最大1024
(1024, 1, 1), (1, 1024, 1)
(32, 32, 1), (4, 4, 64)など
2016/01/13GPGPU講習会133
134. NB,NTをparameterとして定義,変更して実行
module vectoradd_kernel
implicit none
integer,parameter :: N=2**20
integer,parameter :: NT=256
integer,parameter :: NB=(N/NT)
contains
attributes(global) &
subroutine add(a, b, c)
implicit none
real :: a(N)
real :: b(N)
real :: c(N)
integer :: i
i = (blockIdx%x‐1)*blockDim%x &
+ threadIdx%x
c(i) = a(i) + b(i)
end subroutine add
end module vectoradd_kernel
program main
use vectoradd_kernel
use cudafor
implicit none
real,allocatable,device :: a(:)
real,allocatable,device :: b(:)
real,allocatable,device :: c(:)
allocate(a(N)); a=1.0
allocate(b(N)); b=2.0
allocate(c(N)); c=0.0
call add<<<NB,NT>>>(a,b,c)
deallocate(a)
deallocate(b)
deallocate(c)
end program main
並列度の変更によるチューニング
GPGPU講習会134
vectoradd_param.cu
2016/01/13
137. module vectoradd_kernel
implicit none
integer,parameter :: Nx=2**10
integer,parameter :: Ny=2**10
contains
subroutine add(a, b, c)
implicit none
real :: a(Nx,Ny)
real :: b(Nx,Ny)
real :: c(Nx,Ny)
integer :: i,j
//iとjのループを入れ替えるとどうなるか?
do j=1,Ny
do i=1,Nx
c(i,j) = a(i,j) + b(i,j)
end do
end do
end subroutine add
end module vectoradd_kernel
program main
use vectoradd_kernel
implicit none
real :: a(Nx,Ny)
real :: b(Nx,Ny)
real :: c(Nx,Ny)
a=1.0
b=2.0
c=0.0
call add(a,b,c)
print *,sum(c)/(Nx*Ny)
end program main
ベクトル和(2次元版)
2016/01/13GPGPU講習会137
vectoradd2d.f90
140. GPUの並列化の階層
グリッド-ブロック-スレッドの3階層
各階層の情報を参照できる変数
x,y,zを成分(component)にもつdim3派生型
グリッド(Grid)
gridDim グリッド内にあるブロックの数
ブロック(Block)
blockIdx ブロックに割り当てられた番号
blockDim ブロック内にあるスレッドの数
スレッド(Thread)
threadIdx スレッドに割り当てられた番号
GPGPU講習会140 2016/01/13
141. Hello Threads(2次元版)
<<< , >>>の中にどのように数字を書くか
2016/01/13GPGPU講習会141
module cuf_kernel
implicit none
contains
attributes(global) subroutine hello()
print *,"gridDim'%'x=", gridDim%x, "blockIdx'%'x=", blockIdx%x,&
"blockDim'%'x=",blockDim%x,"threadIdx'%'x=", threadIdx%x
print *,"gridDim'%'y=", gridDim%y, "blockIdx'%'y=", blockIdx%y,&
"blockDim'%'y=",blockDim%y,"threadIdx'%'y=", threadIdx%y
end subroutine hello
end module cuf_kernel
program main
use cudafor
use cuf_kernel
implicit none
integer :: stat
call hello<<<?,?>>>()
stat = cudaThreadSynchronize()
end program main
hellothreads2d.cu
142. Hello Threads(2次元版)
1次元と同様<<<2,4>>>等として実行
実行結果(画面出力)
2016/01/13GPGPU講習会142
gridDim'%'x= 2 blockIdx'%'x= 1 blockDim'%'x= 4 threadIdx'%'x= 1
gridDim'%'x= 2 blockIdx'%'x= 1 blockDim'%'x= 4 threadIdx'%'x= 2
gridDim'%'x= 2 blockIdx'%'x= 1 blockDim'%'x= 4 threadIdx'%'x= 3
gridDim'%'x= 2 blockIdx'%'x= 1 blockDim'%'x= 4 threadIdx'%'x= 4
gridDim'%'x= 2 blockIdx'%'x= 2 blockDim'%'x= 4 threadIdx'%'x= 1
gridDim'%'x= 2 blockIdx'%'x= 2 blockDim'%'x= 4 threadIdx'%'x= 2
gridDim'%'x= 2 blockIdx'%'x= 2 blockDim'%'x= 4 threadIdx'%'x= 3
gridDim'%'x= 2 blockIdx'%'x= 2 blockDim'%'x= 4 threadIdx'%'x= 4
gridDim'%'y= 1 blockIdx'%'y= 1 blockDim'%'y= 1 threadIdx'%'y= 1
gridDim'%'y= 1 blockIdx'%'y= 1 blockDim'%'y= 1 threadIdx'%'y= 1
gridDim'%'y= 1 blockIdx'%'y= 1 blockDim'%'y= 1 threadIdx'%'y= 1
gridDim'%'y= 1 blockIdx'%'y= 1 blockDim'%'y= 1 threadIdx'%'y= 1
gridDim'%'y= 1 blockIdx'%'y= 1 blockDim'%'y= 1 threadIdx'%'y= 1
gridDim'%'y= 1 blockIdx'%'y= 1 blockDim'%'y= 1 threadIdx'%'y= 1
gridDim'%'y= 1 blockIdx'%'y= 1 blockDim'%'y= 1 threadIdx'%'y= 1
gridDim'%'y= 1 blockIdx'%'y= 1 blockDim'%'y= 1 threadIdx'%'y= 1
並列度の指定が
できていない
143. 2次元的な並列度の指定
2016/01/13GPGPU講習会143
<<<,>>>の中にどのように数字を書くか
1次元の場合は数字を書くことができた
2次元,3次元は数字を並べて書くことができない
dim3派生型を利用
type(dim3) block=dim3(2,4,1)
type(dim3) thread=dim3(4,2,1);
call hello<<<block, thread>>>()
call hello<<<dim3(2,4,1), dim3(4,2,1)>>>()
dim3型変数block,
threadを利用
・・・
あるいは直接dim3派生型として記述・・・
146. 各スレッドが異なるi,jを参照するには
2016/01/13GPGPU講習会146
Nx=8, Ny=8, x,y方向スレッド数4,ブロック数2
gridDim%x=2, gridDim%y=2
blockDim%x=4,blockDim%y=4
(1,1)(2,1)(3,1)(4,1)(1,1)
(4,4) (4,4)
(1,2)(2,2)(3,2)(4,2)
(1,3)(2,3)(3,3)(4,3)
(1,4)(2,4)(3,4)(4,4) (4,4)
(1,1) (1,1)
threadIdx%x,threadIdx%y
i= 1 2 3 4 5 6 7 8
j=12 34 567 8
・・・
・・・
・・・
・・・
・・・
・・・
147. (1,1)(2,1)(3,1)(4,1)(1,1)
(4,4) (4,4)
(1,2)(2,2)(3,2)(4,2)
(1,3)(2,3)(3,3)(4,3)
(1,4)(2,4)(3,4)(4,4) (4,4)
(1,1) (1,1)
・・・
・・・
・・・
・・・
・・・
・・・
各スレッドが異なるi,jを参照するには
2016/01/13GPGPU講習会147
Nx=8, Ny=8, x,y方向スレッド数4,ブロック数2
blockDim%x=4
blockDim%y=4
threadIdx%x,threadIdx%y
blockIdx%x=1 blockIdx%x=2
blockIdx%y=1blockIdx%y=2
gridDim%x=2
gridDim.y=2
148. (1,1)(2,1)(3,1)(4,1)(1,1)
(4,4) (4,4)
(1,2)(2,2)(3,2)(4,2)
(1,3)(2,3)(3,3)(4,3)
(1,4)(2,4)(3,4)(4,4) (4,4)
(1,1) (1,1)
・・・
・・・
・・・
・・・
・・・
・・・
各スレッドが異なるi,jを参照するには
2016/01/13GPGPU講習会148
Nx=8, Ny=8, x,y方向スレッド数4,ブロック数2
i = (blockIdx%x‐1)*blockDim%x + threadIdx%x
j = (blockIdx%y‐1)*blockDim%y + threadIdx%y
block(1,1) block(2,1)
block(1,2) block(2,2)
threadIdx%x,threadIdx%y
i= 1 2 3 4 5 6 7 8
j=12 34 567 8
149. module vectoradd_kernel
implicit none
integer,parameter :: Nx=2**10
integer,parameter :: Ny=2**10
integer,parameter :: NTx=16
integer,parameter :: NTy=16
integer,parameter :: NBx=(Nx/NTx)
integer,parameter :: NBy=(Ny/NTy)
contains
attributes(global) subroutine add(a, b, c)
implicit none
real :: a(Nx,Ny)
real :: b(Nx,Ny)
real :: c(Nx,Ny)
integer :: i,j
i=(blockIdx%x‐1)*blockDim%x+threadIdx%x
j=(blockIdx%y‐1)*blockDim%y+threadIdx%y
c(i,j) = a(i,j) + b(i,j)
end subroutine add
end module vectoradd_kernel
program main
use vectoradd_kernel
use cudafor
implicit none
real,allocatable,device :: a(:,:)
real,allocatable,device :: b(:,:)
real,allocatable,device :: c(:,:)
type(dim3) :: thread=dim3(NTx,NTy,1)
type(dim3) :: block=dim3(NBx,NBy,1)
allocate(a(Nx,Ny)); a=1.0
allocate(b(Nx,Ny)); b=2.0
allocate(c(Nx,Ny)); c=0.0
call add<<<block, thread>>>(a,b,c)
deallocate(a)
deallocate(b)
deallocate(c)
end program main
ベクトル和(2次元並列版)
2016/01/13GPGPU講習会149
vectoradd2d.cuf
150. 実行結果
GPGPU講習会150
2次元版
カーネル スレッド数 実行時間[s]
add 16×16(=256) 155
2016/01/13
# CUDA_PROFILE_LOG_VERSION 2.0
# CUDA_DEVICE 0 Tesla M2050
# TIMESTAMPFACTOR fffff5f14d408b28
method,gputime,cputime,occupancy
:
method=[ add ] gputime=[ 154.976 ] cputime=[ 6.000 ] occupancy=[ 1.000 ]
151. 実行結果
GPGPU講習会151
1次元版(vectoradd.cuf)
カーネル スレッド数 実行時間[s]
add 256 113
# CUDA_PROFILE_LOG_VERSION 2.0
# CUDA_DEVICE 0 Tesla M2050
# TIMESTAMPFACTOR fffff5f0d1572620
method,gputime,cputime,occupancy
:
method=[ add ] gputime=[ 114.816 ] cputime=[ 6.000 ] occupancy=[ 1.000 ]
2016/01/13
155. GPUの主要部品
GPGPU講習会
基盤
画面出力端子
電源入力端子
GPU(チップ)+冷却部品
メモリ
特性の把握が重要
http://www.geforce.com/whats‐new/articles /introducing‐the‐geforce‐gtx‐780
に公開されている写真を基に作成
画面出力端子
PCI‐Ex端子
電源入力端子
メモリ
チップ
155 2016/01/13
161. メモリの種類
オンチップメモリ(GPUのチップ内部に置かれたメモリ)
高速アクセス,小容量
CPUからはアクセス不可
L1キャッシュと共有メモリは一定サイズを共用
GPGPU講習会161
L1キャッシュ/共有(シェアー
ド)メモリ
レジスタ
容量 小 小
速度 高速 高速
GPUからの
読み書き
読み書き可
ブロック内の全スレッドが同じメモリに
アクセス(データを共有する)ことが可
能*
読み書き可
各スレッドが異なるアドレス
にアクセス
CPUからの
アクセス
読み書き不可 読み書き不可
2016/01/13
*同じメモリ,異
なるメモリにつ
いては後ろの
スライドで説明
162. メモリの種類
オフチップメモリ(GPUのチップ外部に置かれたメモリ)
低速アクセス,大容量
CPUから直接アクセス可能
ローカルメモリだけはアクセス不可
GPGPU講習会162
グローバルメモリ ローカルメモリ テクスチャメモリ コンスタントメモリ
容量 大 小 大 小
速度 低速 低速 高速*1 高速*1
GPUからの
読み書き
読み書き可
全てのスレッドが同じ
メモリにアクセス可能*2
読み書き可
各スレッドが異なるメ
モリにアクセス*2
読み込み可
全てのスレッドが同じ
メモリにアクセス可能*2
読み込み可
全てのスレッドが同じ
メモリにアクセス*2
CPUからの
アクセス
読み書き可 読み書き不可 読み書き可 読み書き可
2016/01/13
*1キャッシュが効く場合
*2同じメモリ,異なるメモリについては後ろのスライドで説明
163. 同じメモリ
2016/01/13GPGPU講習会163
複数のスレッドがメモリアドレスを共有
複数のスレッドが変数を共有
他のスレッドが書き込んだデータを読むことが可能
共有できるスレッドの範囲はメモリの種類によって変化
!a,b()がグローバルメモリに確保されている場合*1
attributes(global) subroutine kernel(...)
integer i
i=blockIdx%x*blockDim%x + threadIdx%x
b(i) = i !スレッドiが配列bのi番目に自身のスレッド番号を代入
!b(1,2,...,i‐1,i,...)の値は1,2,...,i‐1,i,...
a = b(i‐1)*2 !スレッドi‐1が書き込んだ値を読み*3,aに代入
: !最後に書き込まれたaの値を全スレッドが共有
end subroutine *1 あくまで動作のイメージを説明するための例で正しく実行できない
*2 iが1の場合は考えない
*3 配列bを全スレッドが共有しているので,書き込んだ値以外を読む事が可能
165. Tesla世代
L1,L2キャッシュなし
テクスチャキャッシュ,コンスタ
ントキャッシュは利用可能
高速なメモリの活用が重要
共有メモリ
レジスタ
メモリの種類
2016/01/13GPGPU講習会165
オフチップメモリ
オンチップメモリ
ホスト
メモリ
コンスタントメモリ
テクスチャメモリ
GPU
Chip
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA
Core
CUDA
Core
CUDA
Core
CUDA
Core
共有メモリ
SM
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA
Core
CUDA
Core
CUDA
Core
CUDA
Core
共有メモリ
SM
グローバルメモリ ローカル
メモリ
ローカル
メモリ ・・・
166. Fermi世代以降
共有メモリとL1キャッシュが
一体で利用可能
グローバルメモリへのアクセ
スはL2キャッシュ経由
Fermi世代では標準でL1
キャッシュも有効化*
メモリの種類
2016/01/13GPGPU講習会166
オフチップメモリ
オンチップメモリ
ホスト
メモリ
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キャッシュが無効化
167. メモリの種類と並列化階層の対応
オンチップメモリ
ブロックまたはスレッドごとに
異なる値を持つ
ローカルメモリはレジスタが
不足した時に使われる
オフチップメモリ
GPU全体で共通の値を持つ
2016/01/13GPGPU講習会167
各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)
グローバルメモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
・・・
・・・
ホスト
メモリ
168. レジスタ
各スレッドが個別に利用
カーネル内で変数を宣言する
とレジスタを利用
非常に高速
キャッシュとしても利用可能
2016/01/13GPGPU講習会168
*Keplerからは65536本
少容量
32768本*×32bit
利用可能分を超え
るとローカルメモリ
へ追い出される
レジスタスピル
L2キャッシュ
コンスタントメモリ
テクスチャメモリ
GPU
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA
Core
CUDA
Core
CUDA
Core
CUDA
Core
L1キャッ
シュ
共有
メモリ
SM
レジ
スタ
レジ
スタ
レジ
スタ
レジ
スタ
CUDA
Core
CUDA
Core
CUDA
Core
CUDA
Core
L1キャッ
シュ
共有
メモリ
SM
グローバルメモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
ローカル
メモリ
・・・
・・・
Chip
ホスト
メモリ
172. コアレスアクセスの例*
(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
2016/01/13GPGPU講習会172
*CUDA Programming Guide
メモリアドレスに対する
スレッドのアクセス要求
178. メモリ読込の例
2016/01/13GPGPU講習会178
アライン/コアレスアクセス
ミスアライン/コアレスアクセス
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
(カーネル内でのスレッド番号とは異なる)
メモリアドレス
179. メモリ読込の例
2016/01/13GPGPU講習会179
アライン/アンコアレスアクセス
ミスアライン/アンコアレスアクセス
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
メモリアドレスに対する
スレッドのアクセス要求