1070: cuda プログラミング入門
TRANSCRIPT
CUDAプログラミング入門菱洋エレクトロ CUDAエンジニア 石井琢人
菱洋エレクトロについて1961年設立
半導体・システム情報機器・組み込み製品の販売及びサポートを行う
代表取締役会長:小川贒八郎
従業員:600人
本社:東京都中央区築地
THE WORLD LEADER IN VISUAL COMPUTING
PCGeForce | Quadro
DATA CENTERTesla | GRID
MOBILETegra | SHIELD
ENTERPRISE VIRTUALIZATION
AUTONOMOUS MACHINES
HPC & CLOUD SERVICE PROVIDERSGAMING DESIGN
NVIDIA GPU の歴史
GPU 統合シェーダ + CUDA
2010
Fermi3 Billion
Transistors
NVIDIA GPU ロードマップ
SG
EM
M /
W
2012 20142008 2010 2016
48
36
12
0
24
60
2018
72
Tesla Fermi
Kepler
Maxwell
Pascal
Volta
前世代比 3倍の性能 (Fermi vs Kepler)
Tesla
M2090
Tesla
K40
CUDA コア数 512 2880
倍精度演算性能
DGEMM
665 G
400 GF
1.43 TF
1.33 TF
単精度演算性能
SGEMM
1.33 TF
0.89 TF
4.29 TF
3.22 TF
メモリバンド幅 178 GB/s 288 GB/s
メモリサイズ 6 GB 12 GB
消費電力 225W 235W
3.22 TFLOPS
0.89 TFLOPS
1.33 TFLOPS
0.40 TFLOPS
0
0.2
0.4
0.6
0.8
1
1.2
1.4
Tesla M2090 Tesla K40
TFLO
PS
Double Precision FLOPS (DGEMM)
0
0.5
1
1.5
2
2.5
3
3.5
Tesla M2090 Tesla K40
TFLO
PS
Single Precision FLOPS (SGEMM)
Tesla Kepler Family World’s Fastest and Most Efficient HPC Accelerators
GPUsSingle Precision
Peak (SGEMM)
Double Precision
Peak (DGEMM)
Memory
Size
Memory
Bandwidth
(ECC off)
PCIe GenSystem
Solution
CFD, BioChemistry, Neural
Networks, High Energy Physiscs,
Graph analytics, Material
Science, BioInformatics, M&E
K80 5.6 TF 1.87 TF 24 GB 480 GB/s Gen 3 Server
CFD, BioChemistry, Neural
Networks, High Energy Physiscs,
Graph analytics, Material
Science, BioInformatics, M&E
K404.29 TF
(3.22TF)
1.43 TF
(1.33 TF)
12 GB 288 GB/sGen 3
Server +
Workstation
M6000 K6000 K5200 K4200 K2200 K620 K420# CUDA Cores 3072 2880 2304 1344 640 384 192
CC 5.2 3.5 3.5 3.0 5.0 5.0 3.0
Single Precision 6.8 TFLOPs 5.2 TFLOPs 3.1 TFLOPs 2.1 TFLOPs 1.3 TFLOPs 0.8 TFLOPs 0.3 TFLOPs
PCIe Gen 3.0 2.0
Memory Size 12GB 12 GB 8 GB 4 GB 4 GB 2 GB 1 GB
Memory BW 317 GB/s 288 GB/s 192 GB/s 173 GB/s 80 GB/s 29 GB/s 29 GB/s
Slots + Display Connectors
Max Resolution 4096 x 2160 3840 x 2160
Max Displays 4 4 4 4 4 4 4
Pro Features SDI, SYNC, STEREO, MOSAIC, NVIEW MOSAIC, NVIEW
Board Power 250W 225 W 150 W 108 W 60 W 41 W 41 W
The New Quadro Family
* DisplayPort 1.2 multi-streaming can be used to drive multiple displays from a single DP connector
4x DP + 1x DVI* 2x DP + DVI* DP + DVI*2x DP + DVI* DP + DVI*2x DP + 2x DVI*2x DP + 2x DVI*
CUDA・GPUコンピューティング
CUDA– Compute Unified Device Architecture
– Linux・Windows・MacOS X (+Android)で動作
– 現在、7.5
GPUコンピューティング– GPUによる、汎用コンピューティング
– GPU = Graphics Processing Unit
開発者は 加速的に 増加
2008 2014
4,000Academic Papers
15万CUDA Downloads
60University Courses
1億CUDA –Capable GPUs
1Supercomputer
44Supercomputers
57,000Academic Papers
770University Courses
250万CUDA Downloads
5.2億CUDA-Capable GPUs
192-core Super ChipTEGRA K1
BRIDGING THE GAP
MOBILE ARCHITECTURE
Maxwell
Kepler
Tesla
Fermi
Tegra 3
Tegra 4
Tegra K1
GEFORCE ARCHITECTURE
Advancem
ents
HD Video Processor1080p24/30 Video Decode1080p24/30 Video Encode
H.264 | MPEG4 | VC1 | MPEG2VP8
Kepler GeForce®
GPU w/CUDA
OpenGL-ES nextgen
192 Stream Processors
2D Graphics/Scaling
DAP x5(12S/TDM)
HDMIeDP/LVDS
ARM
7Audio
Pro
cess
orImage Processor
25MP Sensor SupportISP 1080p60Enhanced JPEG Engine
PCIe* G2x4 + x1
CSIx4 + x4
SATA2 x1USB 2.0 x3
SecurityEngine
Displayx2
NORFlash
UART x4I2C x5
DDR3 Ctlr64b
800+ MHz
SPI x4SDIO/MMC x4
28 nm HPM23x23mm, 0.7mm pitchHS-FCBGA
USB 3.0* x2
Quad Cortex-A15
4x Cores (1+ GHz) NEON SIMD2 MB L2 (Shared)ARM Trust Zone
Shadow LP C-A15 CPU
Tegra K1: A MAJOR LEAP FORWARD FOR MOBILE & EMBEDDED APPLICATIONS
KEPLER GPU, 192 CORES,
>300GFLOPS
CUDA
12GB/S BANDWIDTH
VIDEO IMAGE COMPOSITOR (VIC)
GPUアーキテクチャとCUDAプログラミングモデル
内容
GPUのハードウエア構造を理解する– GPU Diagram
– Compute Capability
CUDAのプログラミングモデルを理解する– Grid, Block, Warp, Thread
GPUの構造
Giga Thread Engine処理を、SMに割り振る
SM「並列」プロセッサ
L2 CacheR/W可能な二次キャッシュ
DRAMすべてのSMとPCI Expressからアクセス可能なメモリ
PCI ExpressPC(ホスト)との接続インターフェース
GPU
SM
DRAM
SM SM SM …
L2 Cache
Giga Thread Engine
PC
I Expre
ss
Kepler GK110 ブロックダイアグラム
アーキテクチャ 最大 15 SMX ユニット
SMX = KeplerのSM
71億トランジスタ
1 TFLOP以上の倍精度演算性能
1.5 MB L2 Cache
384-bit GDDR5
SM = Streaming Multiprocessor
GPU内部の並列プロセッサSMの単位で処理を実行。
CUDA coreは、単体で動作しない。
Kepler
192 CUDA cores / SMX
Compute Capability
GPUコアアーキテクチャのバージョンCUDA GPUs : https://developer.nvidia.com/cuda-gpus
アーキテクチャは進化する– 高効率の命令実行
– 省消費電力
SM Architecture vs Compute Capability
Kepler
CC 3.5 : 192 cores / SMX
Maxwell
CC 5.0 : 128 cores / SMM
Register File
Scheduler
Dispatch
Scheduler
Dispatch
Load/Store Units x 16
Special Func Units x 4
Interconnect Network
64K Configurable
Cache/Shared Mem
Uniform 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
Instruction Cache
Fermi
CC 2.0 : 32 cores / SM
Compute Capability
ArchitectureComputeCapability
特徴・機能 発表
Kepler
3.0 192 cores/SMX, 1536 cores (Max)Single / Double = 24 : 1
2012/3
3.2 Tegra K1 2013/1
3.5192 cores/SMX, 2880 cores (Max)Single / Double = 3 : 1Hyper-Q, Dynamic Parallelism
2012/11
3.7 Tesla K80 2014/11
Maxwell
5.0 128 cores/SMMSingle / Double =32 : 1
2014/2 (5.0)
5.2 96 KB shared memory 2014/9 (5.2)
5.3 Tegra X1, FP16 support 2015/1
Kepler・Maxwell GPUs (Tesla)
デバイス名 コア数ピーク演算性能 *
単精度/倍精度(FLOPS)メモリバンド幅
GB/sec消費電力
W
Compute Capability 3.0
Tesla K8 1536 2.13 T / 89 G 173 100
Compute Capability 3.5
Tesla K40 2880 4.29 T / 1.43 T 288 235
Compute Capability 3.7
Tesla K80 2496 x 2 5.6 T / 1.87 T* 480 300
M6000 K6000 K5200 K4200 K2200 K620 K420# CUDA Cores 3072 2880 2304 1344 640 384 192
CC 5.2 3.5 3.5 3.0 5.0 5.0 3.0
Single Precision 6.8 TFLOPs 5.2 TFLOPs 3.1 TFLOPs 2.1 TFLOPs 1.3 TFLOPs 0.8 TFLOPs 0.3 TFLOPs
PCIe Gen 3.0 2.0
Memory Size 12GB 12 GB 8 GB 4 GB 4 GB 2 GB 1 GB
Memory BW 317 GB/s 288 GB/s 192 GB/s 173 GB/s 80 GB/s 29 GB/s 29 GB/s
Slots + Display Connectors
Max Resolution 4096 x 2160 3840 x 2160
Max Displays 4 4 4 4 4 4 4
Pro Features SDI, SYNC, STEREO, MOSAIC, NVIEW MOSAIC, NVIEW
Board Power 250W 225 W 150 W 108 W 60 W 41 W 41 W
Quadro GPUs (Compute Capability)
* DisplayPort 1.2 multi-streaming can be used to drive multiple displays from a single DP connector
4x DP + 1x DVI* 2x DP + DVI* DP + DVI*2x DP + DVI* DP + DVI*2x DP + 2x DVI*2x DP + 2x DVI*
CUDAプログラミングモデル
SMアーキテクチャが異なっても、同じプログラムが動作する– GPUハードウェアとソフトウェアの対応
並列処理のみ実行可能– 100万スレッド以上での並列動作
– Massively Parallel
GPUは並列処理部分を担当
アプリケーションGPU CPU
逐次実行部分
並列化可能な
ボトルネック
典型的な装置構成
CPU
(数コア)
PC
ホスト側DRAM
GPU
SM
DRAM
PCIe
SM SM SM …
L2 Cache
Giga Thread Engine
転送
制御
CPUにつながった外部演算装置
典型的な実行例
GPUはCPUからの制御で動作する
入力データはCPU→GPUへと転送
結果は、GPU→CPUと転送
GPU上に常駐するプログラムはない
CPU
GPU
CUDAカーネル実行
GPUでの演算
データ転送
完了待ち
データ転送
プログラム開始
カーネル実行の階層
Grid
CPUから呼び出される。Blockにより構成される。
Block
Threadにより構成される。Thread数は、Grid内部で一定
Thread
最小の実行単位
CPU GPU
CUDAカーネル実行依頼
データ転送
Grid
Block0
Block1
Block2
Block n
…
ThreadThreadThreadThread
ThreadThreadThreadThread
ThreadThreadThreadThread
…
ThreadThreadThreadThread
Block は SM上で実行
※ Blockの実行順序は保証されない。特定のSMへのBlock割り当てはできない
SMSM SM SM
プログラミングモデル
…Grid
Block0 Block1 Block2 Block3 Block4 Block5 Block6 Block N
GPU
Block は SM上で実行
Block ⇒ 1 SM
– 複数のSMにまたがらない(SM中では、複数Blockが実行される場合もある)
– Block内部では、SMのリソースを活用可能
各々のBlockは、独立に、非同期に処理を実行する– 実行順序の保証はない
– Block間の通信・同期は行わない
Streaming Multiprocessor on Kepler
192 Cores/SMX
Compute Capability 3.5
SFUSpecial Function Unit
LD/STLoad/Store
DP倍精度演算ユニット
SMX (簡略化しています)
レジスタファイルレジスタ 64 K個 (256 KB)
Shared Mem.
L1 Cache64 KB
テクスチャキャッシュ48 KB
SM数によるスケーリング
CUDAプログラム
Block0 Block1 Block2 Block3
Block4 Block5 Block6 Block7
SMSM SM SM
GPU 1 (4 SM)
SM SM
GPU 2 (2 SM)
Block0 Block1 Block2 Block3
Block4 Block5 Block6 Block7
Block0 Block1
Block2 Block3
Block4 Block5
Block6 Block7
Warp : 並列実行の最小単位
Warp : 32 GPU スレッド– 1命令を Warp (32スレッド)が、並列に処理
– SIMT (Single Instruction Multiple Thread)B
lock Thread
Thread
Thread
Thread
War
pW
arp
War
p…
Thread
Thread …
32
GP
U T
hre
ad
CoreCore
CoreCore
Core
SW SM
1命令を32並列実行
CU
DA
core
s
Warp内部でのみ使える命令
例) SHFL (シャッフル命令)
同一Warpに属するスレッド間でのデータ交換。
Shared memoryを使用しない。
32-bit値の交換
4 バリエーション:
h d f e a c c b - - a b c d e f c d e f g h - - c d a b g h e f
a b c d e f g h
Indexed
any-to-any
Shift right to nth
neighbour
Shift left to nth
neighbour
Butterfly (XOR)
exchange
__shfl() __shfl_up() __shfl_down() __shfl_xor()
Grid・Block・Warp・Thread
説明
Grid カーネル全体。Blockの集合。
Block SM内部で、実行される。SM内部のリソースを活用可能。Blockのサイズは、Grid内で、一定。実行個数で、Gridのサイズを指定。
Warp SM内部で、一つの命令を、32 並列で実行。HWに密接に関連。最適化時に重要。
Thread 個々のGPUスレッドソースコードは、スレッド単位の視点
SM
CUDAプログラム実行の概要
GridCPUからの呼び出し単位
Blockで構成
BlockSM上の実行単位
一つのGrid内で、スレッド数固定。
Warp 一命令を32並列で実行
SM GPUの並列プロセッサ
CPU Grid
Block
Block
Block
Warp (32 Thread)
Warp (32 Thread)
Warp (32 Thread)
CUDAプログラミングの基礎
CUDAプログラミングの基礎
ホストプログラミング– メモリ転送、カーネルの実行
カーネルプログラミング– GPU上の関数の実装
デバイス・メモリ構成
CPU側 ホスト ホストメモリ
GPU側 デバイス グローバルメモリ
CPU
ホスト
ホストメモリ
GPU (デバイス)
SM(X)
デバイスメモリ(グローバルメモリ)
CUDA ホストプログラミング
メモリのアロケーション、解放– cudaMalloc()/cudaFree()
メモリコピー– cudaMemcpy()
カーネルの呼び出し– 特殊な構文
同期– cudaDeviceSynchronize()
終了処理– cudaDeviceReset()
cudaMalloc() / cudaFree()
cudaError_t cudaMalloc(void ∗∗ devPtr, size_t size)
cudaError_t cudaFree(void *);
例:
float *dptr;
/* float型、1024個の要素分のデバイスメモリをアロケート */
cudaMalloc((void**)&dptr, sizeof(float) * 1024);
/* 解放 */
cudaFree(dptr);
cudaMemcpy()
cudaError_t
cudaMemcpy (void ∗ dst, const void ∗ src, size_t count,
enum cudaMemcpyKind kind)
例:float src[1024] = {…..}
float *ddst;
cudaMalloc((void**)&ddst, sizeof(float) * 1024);
cudaMemcpy(ddst, src, sizeof(float) * 1024,
cudaMemcpyHostToDevice);
srcから ddstに、float型、1024個の要素をコピーする。
cudaMemcpy()
メモリは、「ホスト」「デバイス」の二種類
enum cudaMemcpyKind
cudaMemcpyHostToDevice
cudaMemcpyDeviceToHost
cudaMemcpyDeviceToDevice
cudaMemcpyHostToHost
(cudaMemcpyDefault : UVA)
カーネル呼び出し
カーネル呼び出しの構文
kernelName<<<GridDim, BlockDim>>>(引数);
GridDim : グリッド中のブロック数
BlockDim : ブロックあたりのスレッド数
引数は、複数個指定可能
例:
sample<<<1, 256>>>(x, y, z);
cudaDeviceSynchronize()
cudaError_t cudaDeviceSynchronize (void)
例:
someKernel<<<xxx, yyy>>>(a, b, c);
cudaDeviceSynchronize();
カーネルが終了するまで待つ。
cudaDeviceReset()
cudaError_t cudaDeviceReset (void)
アプリケーションの最後に呼び出す。お作法と思って、いつも入れてあげてください。
役割– 使用したリソースの解放
– プロファイリングデータの回収
– cuda-memcheckを用いた、デバイスメモリのリークチェック
cudaError_t
エラーチェック– 成功時は、cudaSuccessを返す。
エラーの場合、値を確認。const char∗ cudaGetErrorString (cudaError_t error)
エラーを説明する文字列を返す。
CUDAカーネル
__global__
void myKernel(int a, float *pb, …) {
/* device code */
}
ホストから呼び出し可能なデバイス側の関数– __global__を修飾子として持つ– 戻り値は、voidでなければならない。
通常のC/C++の構文が使用可能。
CUDA開発環境の構築
OS– Windows 7 / 8.1 / 10
IDE– Visual Studio 2010 / 2012 / 2013
CUDA Toolkit– CUDA 7.5
NVIDIA Driver– 今回はCUDA 7.5付属のものを利用
CUDAプログラム作成デモ
CUDAを用いた画像処理
画像処理をCUDAで並列化– 基本的な並列化の考え方
– 目標 : 妥当なNaïveコードが書ける
RGB → Y(輝度) 変換
カラー画像から、グレイスケールへの変換– Y = 0.299 × R + 0.587 × G + 0.114 × B
CUDAにおける画像処理の基礎
2次元メモリ確保API
– Pitchを考慮
– cudaMallocPitch()、cudaMemcpy2D()
並列化– CUDAの並列度 : 数万以上欲しい…
Keplerでの目安 : CUDA Core数 x 10 程度 (最低限)
Pitchを考慮したメモリレイアウト
RGBA(8 bit, uchar4)の配列
index = x + y * pitchInPixel
width
pitchInPixel = pitchInByte / sizeof(uchar4)
(x, y)
実装のポイント1: 2次元メモリ 確保・転送
cudaError_t cudaMallocPitch ( void** devPtr, size_t* pitch,
size_t width, size_t height ) – widthバイトのメモリを、height行分、取得する。
– 行は、pitchバイトで整列する。
cudaError_t cudaMemcpy2D ( void* dst, size_t dpitch,
const void* src, size_t spitch, size_t width, size_t height,
cudaMemcpyKind kind )– dstで示されるメモリ (dpitchバイトで整列)に、srcで示されるメモリ (spitchバイトで整列) を、width
(バイト) x height (行)、コピーする。
サンプルコード
uchar4 *src, *dImage;
size_t spitch, dPitch, dPitchInPixel;
// ピッチつきで、メモリをアロケート
cudaMallocPitch(&dImage, &dPitch, width * sizeof(uchar4), height);
dPitchInPixel = dPitch / sizeof(uchar4);
// ピッチを変換しつつ、ホスト→デバイスへと、メモリ転送
cudaMemcpy2D(dImage, dPitch, src, sPitch, width * sizeof(uchar4), height,
cudaMemcpyHostToDevice);
実装のポイント2 : 画像処理における並列化
基本 : 1 ピクセルに対して、 1スレッドを対応させる– ピクセル数分、スレッドが走る。例 : 262,144 (= 512 x 512) スレッド
スレッドは、処理対象のピクセルを持つ。– 自分の位置 (x, y) を知ることが必要
2DでのBlock・Threadの割り当て
Thread : 「2次元」でピクセルに対応。
Block : 「2次元」で定義。一定のサイズのタイル。
Grid : 必要数のBlockを「2次元」に敷き詰める。
1 Block
1 Pixel = 1 Thread
(x, y) =
(Global ID X, Global ID Y)
Global ID : GPUスレッドの通し番号
Global ID、Grid内で一意– blockDim.x * blockIdx.x + threadIdx.x
threadIdx.x– Thread番号、Block内で一意
blockIdx.x– Block番号、Grid内で一意
blockDim.x– Block内のスレッド数
0
1
2
3
Global ID
4
5
6
7
threadIdx
0 Thread
1 Thread
2 Thread
3 Thread
0
blockIdx
threadIdx
0 Thread
1 Thread
2 Thread
3 Thread
1
blockIdx
2DでのBlock・Threadの割り当て
GlobalID は、(x, y, z)方向に計算できる– GlobalID(x) = blockDim.x * blockIdx.x + threadIdx.x
– GlobalID(y) = blockDim.y * blockIdx.y + threadIdx.y
– GlobalID(z) = blockDim.z * blockIdx.z + threadIdx.z
blockDim.x * blockIdx.xthreadIdx.x
blockDim.y * blockIdx.y
threadIdx.y
RGB → Y 変換 カーネル
__global__
void RGBToYKernel(uchar4 *dDst, const uchar4 *dSrc, int width, int height, int pitch){
int gidx = blockDim.x * blockIdx.x + threadIdx.x;
int gidy = blockDim.y * blockIdx.y + threadIdx.y;
if ((gidx < width) && (gidy < height)) {
int pos = gidx + gidy * pitch;
// Y = 0.299 R + 0.587 G + 0.114 B
uchar4 value = dSrc[pos];
float Y = 0.299f * value.x + 0.587f * value.y + 0.114f * value.z;
unsigned char y = (unsigned char)min(255, (int)Y);
dDst[pos] = make_uchar4(y, y, y, 0);
}
}
カーネル呼び出し (Gridサイズ指定)
/* value、radixで割って、切り上げる */
int divRoundUp(int value, int radix) {
return (value + radix – 1) / radix;
}
/* gridDim, blockDimを、2次元(x, y方向)に初期化 */
dim3 blockDim(64, 2);
/* divRoundUp()は、切り上げの割り算 */
dim3 gridDim(divRoundUp(width, blockDim.x), divRoundUp(height, blockDim.y));
RGBToYKernel<<<gridDim, blockDim>>>(dDst, dSrc, …);
RGB → Y(輝度) 変換 デモ
CUDAでプログラムを書くために
2つの概念を自分の物にしてください
1. 並列化の階層 (HW・SW)
– Grid・Block・Warp・Thread
2. Massively Parallel (SW)
– 100万単位でスレッドが動作するのは普通
– スレッドあたりの処理単位が非常に小さい
関連書籍
CUDA C プロフェッショナルプログラミング
9/24発売、¥5400
Professional CUDA C Programmingの翻訳書
CUDAプログラミングモデルから各種メモリの特徴、ストリームの機能やその使い方までを網羅
NVIDIAソリューション
SHIELD
TeslaQuadro
Jetson
Quadro VCA
Tegra
Tegra K1 モジュール
108 mm
150 mm
68 mm
68 mm
70 mm
50 mm
この後のCUDAセッション
GPUコンピューティング最新情報 ~ CUDA 7.5とMaxwellアーキテクチャ ~– 13:10 – 13:35
– CUDA 7.5の新機能とMaxwellアーキテクチャの特徴、Keplerとの違い
アプリケーション開発を加速するCUDAライブラリ– 13:45 – 14:45
– 様々なCUDAライブラリの紹介
OpenACC プログラミング入門– 14:55 – 15:20
– ディレクティブベースのGPUコンピューティング
CUDAデバッグ・プロファイリング入門– 16:55 – 17:55
– Nsight、Visual Profilerを用いたデバッグ・プロファイリング etc…
Thank you