• 検索結果がありません。

1. GPU コンピューティング GPU コンピューティング GPUによる 汎用コンピューティング GPU = Graphics Processing Unit CUDA Compute Unified Device Architecture NVIDIA の GPU コンピューティング環境 Lin

N/A
N/A
Protected

Academic year: 2021

シェア "1. GPU コンピューティング GPU コンピューティング GPUによる 汎用コンピューティング GPU = Graphics Processing Unit CUDA Compute Unified Device Architecture NVIDIA の GPU コンピューティング環境 Lin"

Copied!
36
0
0

読み込み中.... (全文を見る)

全文

(1)

GTC 2013 チュートリアル エヌビディアジャパン

CUDAエンジニア 森野慎也

(2)

1. GPUコンピューティング

 GPUコンピューティング

— GPUによる、汎用コンピューティング — GPU = Graphics Processing Unit

 CUDA

— Compute Unified Device Architecture

— NVIDIAのGPUコンピューティング環境 Linux・Windows・MacOS Xにて動作

(3)

Compute Capability

 ハードウエアアーキテクチャのバージョン

— 「Fermi」(2.0以降) がターゲットです

機能 対応するデバイス 発表

1.0 初期バージョン 2006/11

1.1 globalメモリ上の32-bit atomic演算 GeForce 9XXX系 2007/10 1.2 メモリアクセスパターンの改善 実行スレッド数の増加、など。 GeForce GT240など 1.3 倍精度演算 GTX285, Tesla C1060など 2008/6 2.0 32 cores/SM、L1キャッシュなど GTX580、Tesla C2070など 2009/10 2.1 48 cores/SM GTX460、GTX560Ti など 3.0 192 cores/SMX GTX680, Tesla K10 2012/3 3.5 Dynamic Parallelism, 64 DP/SMX Tesla K20(X) 2012/11

(4)

最近のCUDAデバイス

デバイス名 コア数 ピーク演算性能 単精度/倍精度(FLOPS) メモリバンド幅 GB/sec Compute Capability 3.0 Quadro K5000 1536 2.1 T / 90 G 173 Tesla K10 1536 x 2 4.58 T / 0.19 T 320 GeForce GTX770 1536 3.21 T / 134 G 224.3 Compute Capability 3.5 Tesla K20X 2688 3.95 T / 1.31 T 250 Tesla K20 2496 3.52 T / 1.17 T 208 GeForce GTX Titan 2688 4.50 T / 1.31 T 288.4

(5)

1. Nsight Visual Studio Edition

 Visual StudioでのCUDA開発

— ビルド・デバッグ・プロファイル — CUDA Toolkitに含まれる。 (CUDA 5.5から)

 開発者登録が

不要になりました。

(6)

1. 装置構成

CPU (数コア) マザーボード DRAM チップ セット

GPU

GPU: CPUにつながった

外部演算装置

プロセッサ(~数千コア) DRAM

PCIe

(7)

1. 典型的な実行例

 GPUはCPUから

の制御で動作す

る。

 入力データは

CPU→GPUへと

転送。

 結果は、

GPU→CPUと転

CPU

GPU

GPU

プログラム

実行依頼

GPUでの演算

データ

転送

完了

待ち

データ

転送

プログラム

開始

(8)

1. CUDAカーネル

 カーネル = GPU上のプログラム

— GPU向け言語(C++ベース)にて記述される。 — 特別なコンパイラ(NVCC)でコンパイル

 100万スレッドオーダーでの並列動作

— Massively parallel

 並列度の階層構造

— GPUのアーキテクチャに密接に関係

(9)

1. カーネル実行の階層

Grid CPUからの呼び出し単 位。 Blockに分解される。 Block 一定数のThread を持つ。 GPU上の並列プロセッ サ(SMX) 内部でで実行 される。 Thread 最小の実行単位

CPU

GPU

GPU

プログラム

実行依頼

データ

転送

Grid Block0 Block1 Block2 Block n

Thread Thread Thread Thread Thread Thread Thread

Thread Thread Thread Thread

Thread

Thread Thread Thread Thread

(10)

1. Warp

 Warp

— 32 GPU-threads — HW上の実行単位 Block

Thread Thread Thread Thread Thread Thread Thread

Thread Thread Thread Thread

Thread

Thread Thread Thread Thread Warp0

Warp1 Warp2

(11)

1. Streaming Multiprocessor eXtreme

 192 Cores/SMX Compute Capability 3.5  SFU Special Function Unit  LD/ST Load/Store  DP 倍精度演算ユニ ット SMX (簡略化しています) レジスタ 64 K個 (256 KB) 共有メモリ L1 Cache 64 KB テクスチャ キャッシュ 48 KB Core 3 Core 2 Core 1 Core 0 Core 15 Core 3 Core 2 Core 1 Core 0 Core 15 Core 3 Core 2 Core 1 Core 0 Core 15 Core 3 Core 2 Core 1 SFU 0 SFU 15 Core 3 Core 2 Core 1 LD/ST 0 LD/ST 15 Core 3 Core 2 Core 1 DP 0 DP 15

(12)

1. Streaming Multiprocessor eXtreme

 GPU内部の「並列プロセッサ」

— 本質的に並列 (しか実行できない)

 Blockは、SMX内部で動作

— GPUは、SMXの個数でスケールする。 高性能なGPU ⇒ 数多くのSMXを搭載

 旧世代(Fermi以前):

Streaming Multiprocessor (SM)と呼びます

(13)

1. Grid・Block・Warp・Thread

 Grid

— カーネル全体、全てのBlockを含む

 Block

— 「カーネル設計」時に、重要な粒度 — Blockのサイズはカーネル内で一定。実行個数は、変更可能

 Warp

— 「高速なプログラムを書く」時に重要な粒度 — HWに密接に関連。分岐処理、メモリアクセスの粒度

 Thread

— 個々のGPUスレッド — カーネルは、スレッド単位の視点で書く

(14)

SM(X)

1. CUDAプログラム実行の概要

Grid CPUからの呼び出し単位 Blockに分解 Block SM上の実行単位 Warpに分解 SM・共有メモリのスコープ

Warp CUDA固有の並列単位 32 GPU threads・条件分岐の粒度

SM(X) ハードウエア上の並列プロセッサ

CPU

Grid

Block

Block

Block

Warp

Warp

Warp

(15)

2. プログラミングの基礎

 ホストプログラミング

— メモリ転送、カーネルの実行

 カーネルプログラミング

(16)

2.1 CUDA ホストプログラミング

 メモリのアロケーション、解放

— cudaMalloc()/cudaFree()

 メモリコピー

— cudaMemcpy()

 カーネルの呼び出し

— 特殊な構文

 同期

— cudaDeviceSynchronize()

(17)

2.1 cudaMalloc() / cudaFree()

cudaError_t cudaMalloc(void ∗∗ devPtr, size_t size)

cudaError_t cudaFree(void *);

例:

float *devptr;

/* float型、1024個の要素分のデバイスメモリをアロケート */

cudaMalloc((void**)&devptr, sizeof(float) * 1024);

/* 解放 */

cudaFree(devptr);

(18)

2.1 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個の要素をコピーする。

(19)

2.1 cudaMemcpy()

 メモリは、「ホスト」「デバイス」の二種類

enum cudaMemcpyKind cudaMemcpyHostToDevice cudaMemcpyDeviceToHost cudaMemcpyDeviceToDevice cudaMemcpyHostToHost (cudaMemcpyDefault : GPUdirect)

(20)

2.1 カーネル呼び出し

カーネル呼び出しの構文

kernelName<<<GridDim, BlockDim>>>(引数);

GridDim : グリッド中のブロック数

BlockDim : ブロックあたりのスレッド数

引数は、複数個指定可能

例:

sample<<<1, 256>>>(x, y, z);

(21)

2.1 cudaDeviceSynchronize()

cudaError_t cudaDeviceSynchronize (void)

例:

someKernel<<<xxx, yyy>>>(a, b, c);

cudaDeviceSynchronize();

(22)

2.1 cudaError_t

 エラーチェック

— 成功時は、cudaSuccessを返す。

 エラーの場合、値を確認。

const char∗ cudaGetErrorString (cudaError_t error)

(23)

2.1 CUDAカーネル

__global__

void myKernel(int a, float *pb, …) { /* device code */ }

 ホストから呼び出し可能なデバイス側の関数

— __global__を修飾子として持つ — 戻り値は、voidでなければならない。

 通常のC/C++の構文が使用可能。

(24)

2.2 プログラム例

 配列の和

c[i] = a[i] + b[i]

メモリの取り扱い

(25)

2.2 デバイス・メモリ構成

 CPU側 ホスト ホストメモリ

 GPU側 デバイス グローバルメモリ

CPU

ホスト

ホストメモリ

GPU

SM(X) デバイスメモリ (グローバルメモリ)

PCIe

(26)

2.2 配列の和:メモリの扱い

float *a, *b, *c をアロケート

ホスト

GPU

カーネル

dc[i] = da[i] + db[i] *a, *bに値を設定 ホスト->デバイス転送 a-> da, b->db ホスト <- デバイス転送 c <- dc float *da, *db, *dc をアロケート (デバイスメモリ) 結果表示・検証 float *da, *db, *dc を開放 (デバイスメモリ) float *a, *b, *c を開放 カーネル実行依頼

(27)

2.2 配列の和 : ホストコード

int main() {

static const int size= 256 * 100; int memSize = sizeof(float) * size;

float *a, *b, *c, *da, *db, *dc; /* ホストもデバイスもメモリは同じポインタ型 */ /* ホスト側メモリの確保と値の初期化(略)*/

/* GPU側メモリをアロケート */

cudaMalloc(&da, memSize); cudaMalloc(&db,memSize); cudaMalloc(&dc, memSize);

cudaMemcpy(da, a, memSize, cudaMemcpyHostToDevice); /* メモリ転送(Host→Device) */ cudaMemcpy(db, b, memSize, cudaMemcpyHostToDevice);

/* カーネル(addArrayKernel)をここで呼ぶ */

cudaMemcpy(c, dc, memSize, cudaMemcpyDeviceToHost); /* メモリ転送(Host←Device) */ /* 表示などの処理 (略) */

cudaFree(da); cudaFree(db); cudaFree(dc); free(a); free(b); free(c);

(28)

2.2 並列化(カーネル設計)

 複数のブロックに配分して、和をとる。

— 図は、1 ブロックあたり、4スレッドとした場合

a[i]

b[i]

c[i]

Block[0]

0 1 2 3

+ + + +

15 14 13 12

Block[1]

4 5 6 7

+ + + +

11 10 9 8

Block[2]

8 9 10 11

+ + + +

7 6 5 4

Block[3]

12 13 14 15

+ + + +

3 2 1 0

(29)

2.2 Global ID / Local ID / Block ID

 Global ID、Grid内で一意

blockDim.x * blockIdx.x + threadIdx.x

 Local ID、Block内で一意

threadIdx.x

 Block ID

blockIdx.x

(OpenCLから概念を拝借)

0 1 2 3 Global ID 4 5 6 7 Local ID (threadIdx) 0 Thread 1 Thread 2 Thread 3 Thread 0 Block ID (blockIdx) Local ID 0 Thread 1 Thread 2 Thread 3 Thread 1 Block ID

(30)

2.2 カーネル実装

__global__

void addArrayKernel(float *dc, const float *da, const float *db, int size) { /* Global IDを算出 */

int globalID = blockDim.x * blockIdx.x + threadIdx.x; if (globalID < size) { /* 範囲チェック */

/* 自スレッド担当の要素のみ、処理 */

dc[globalID] = da[globalID] + db[globalID]; }

(31)

2.2 ブロック数の指定

 カーネルはブロック数でスケールする

— ブロックごとのスレッド数は一定

/* gridDim * blockDim個のスレッドを起動する */ int blockDim = 256;

int gridDim = (size + blockDim – 1) / blockDim;

(32)

2.2 配列の和 : ホストコード

int main() {

static const int size= 256 * 100; int memSize = sizeof(float) * size;

float *a, *b, *c, *da, *db, *dc; /* ホストもデバイスもメモリは同じポインタ型 */ /* ホスト側メモリの確保と値の初期化(略)*/

/* GPU側メモリをアロケート */

cudaMalloc(&da, memSize); cudaMalloc(&db,memSize); cudaMalloc(&dc, memSize);

cudaMemcpy(da, a, memSize, cudaMemcpyHostToDevice); /* メモリ転送(Host→Device) */ cudaMemcpy(db, b, memSize, cudaMemcpyHostToDevice);

int blockDim = 256; int gridDim = (size + blockDim – 1) / blockDim;

addArrayKernel<<<gridDim, blockDim>>>(dc, da, db, size);

// cudaDeviceSynchronize(); /* 同期。今回は、必須ではない。 */

cudaMemcpy(c, dc, memSize, cudaMemcpyDeviceToHost); /* メモリ転送(Host←Device) */ /* 表示などの処理 (略) */

cudaFree(da); cudaFree(db); cudaFree(dc); free(a); free(b); free(c);

(33)

3. Visual Studio 2010 によるビルド

 ビルドルールの追加

(34)

3. Visual Studio 2010 によるビルド

 Compute Capability の設定

(35)

3. Visual Studio 2010 によるビルド

 ライブラリ指定

(36)

NVIDIA Japan CUDA Monthly Seminar

 NVIDIA Japanでは、毎月、

CUDAの無償セミナーを実施しています。

是非、ご参加ください。

— 申し込み : http://www.nvidia.co.jp/object/event-calendar-jp.html — 場所 : NVIDIA Japan 赤坂オフィス

参照

関連したドキュメント

図一1 に示す ような,縦 お よび横 補剛材 で補 剛 された 板要素か らなる断面部材 の全 体剛性 行列 お よび安定係数 行列は局所 座標 系で求 め られた横補 剛材

この説明から,数学的活動の二つの特徴が留意される.一つは,数学の世界と現実の

これらの先行研究はアイデアスケッチを実施 する際の思考について着目しており,アイデア

血は約60cmの落差により貯血槽に吸引される.数

ImproV allows the users to mix multiple videos and to combine multiple video effects on VJing arbitrary by data flow editor. We employ a unified data type, we call, Video Type which

LLVM から Haskell への変換は、各 LLVM 命令をそれと 同等な処理を行う Haskell のプログラムに変換することに より、実現される。

1 つの Cin に接続できるタイルの数は、 Cin − Cdrv 間 静電量の,計~によって決9されます。1つのCin に許される Cdrv への静電量は最”で 8 pF

小学校における環境教育の中で、子供たちに家庭 における省エネなど環境に配慮した行動の実践を させることにより、CO 2