2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

35
15GPGPU開発環境 OpenCL長岡技術科学大学 電気電子情報工学専攻 出川智啓

Transcript of 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

Page 1: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

第15回 GPGPU開発環境(OpenCL)

長岡技術科学大学 電気電子情報工学専攻 出川智啓

Page 2: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

計算機名称 アクセラレータ GFLOPS/W 消費電力[kW]

1 Shoubu PEZY‐SC 7.03 50.322 TSUBAME‐KFC NVIDIA Tesla K80 5.33 51.133 ASUS ESC4000  AMD FirePro S9150 5.27 57.154 Sugon Cluster  NVIDIA Tesla K80 4.78 65.005 Xstream NVIDIA Tesla K80 4.11 190.06 Inspur TS10000 NVIDIA Tesla K40 3.86 58.007 Inspur TS10000 NVIDIA Tesla K40 3.78 110.08 Inspur TS10000 NVIDIA Tesla K40 3.78 110.09 Inspur TS10000 NVIDIA Tesla K40 3.78 110.010 Inspur TS10000 NVIDIA Tesla K40 3.78 110.0

Green500(2015, Nov.) TOP3の計算機がそれぞれ異なるアクセラレータを搭載

インターネットのサービス提供に利用されてる(と思われる)計算機が大量にランクイン

GPGPU実践基礎工学2 2015/12/16

http://www.green500.org/lists/green201511

Page 3: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

今回の内容

GPGPU実践基礎工学

OpenCL 背景

OpenCLの仕様

grouseで利用できるOpenCL環境の確認

grouseのOpenCL環境から利用できるデバイスの確認

サンプルプログラム

3 2015/12/16

Page 4: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLとは

Open Computing Language 不均一な並列環境向けの標準化フレームワーク

ロイヤリティ不要のオープンスタンダード

処理するハードウェアに依存しない

CPU, GPU, Cell等のプロセッサで動作

統一されたAPIによる制御が可能

OpenCL Working Groupによって策定

Appleにより提案

AMDが自社GPUの標準開発環境として採用

GPGPU実践基礎工学4 2015/12/16

Page 5: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLが登場した背景

GPGPU実践基礎工学

均一な計算機環境から不均一な計算機環境への移行 マルチコアCPU CPU+GPU Cell/B.E.

計算機環境の多様化 ソフトウェアの移植が困難

ハードウェア構造,命令構文の違い

ソフトウェア・ハードウェアの変更と移植性の両立 ソフトウェアの移植性を維持

ハードウェアの変更への対応

プロセッサの種類に依存しない開発環境

5 2015/12/16

Page 6: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLの仕様

GPGPU実践基礎工学

ハードウェアの抽象化

制御用プロセッサ+演算用プロセッサ

CPU(1コア)+CPU(その他のコア)

CPU+GPU PPE+SPE (Cell/B.E.) PowerPC Processor Element(PPE)+Synergistic Processor Element(SPE) 

不均一な計算環境を想定

演算用プロセッサ上でOSが動作していないと想定

制御用プロセッサから演算プログラムを起動

演算用プログラムをOpenCL,制御用プログラムをC言語で作成

6 2015/12/16

Page 7: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLの仕様

GPGPU実践基礎工学

二つの仕様を標準化

OpenCL C言語仕様

演算用プロセッサで動作するプログラムの記述方法

C言語の拡張

OpenCLランタイムAPI仕様

制御用プロセッサが利用するAPI(C言語からの関数呼出)

OpenCL C言語で作成されたプログラムを呼び出し,演算用プロセッサで並列実行

7 2015/12/16

Page 8: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLプログラムの構成

GPGPU実践基礎工学

ホストプログラム(拡張子は.cpp) OpenCLランタイムAPIを利用してC/C++言語で記述

カーネル(拡張子は.cl) OpenCLデバイスで動作するプログラム

OpenCL C言語で記述

OpenCLデバイス ホスト

CPU

メモリ

CUDA Core

メモリ

ホストプログラムカーネル 呼出

8 2015/12/16

Page 9: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLプログラムの構成

GPGPU実践基礎工学

ホストプログラムからカーネルを読み込んで実行

オンラインコンパイル方式を採用

プログラム実行時にOpenCLランタイムライブラリがカーネルをコンパイル,実行(Just in Timeコンパイル)

デバイスに依存せずにプログラムを配布可能

ホストプログラム カーネル

OpenCLランタイムライブラリ

ホスト OpenCLデバイス

コンパイル

カーネル読込

実行

9 2015/12/16

実行

Page 10: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCL環境の確認

使用(ログイン)している計算機環境でOpenCLが有効になっているかの確認

grouseにはNVIDIA社が提供するOpenCL環境が存在

コンパイル

nvcc ‐lOpenCL ソースファイル名.cpp ソースファイルの拡張子は.cuではなく.cpp

2015/12/16GPGPU実践基礎工学10

$ ls /etc/OpenCL/vendorsnvidia.icd

Page 11: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLから利用できるデバイスの確認

GPGPU実践基礎工学11

プラットフォーム

複数の会社がOpenCL(プラットフォーム)を提供

AMD, Apple, IBM, Intel, NVIDIAなど(約10社が提供)

複数のプラットフォームをインストール可能

利用している計算機に複数のプラットフォームがあれば,その中から一つを指定

デバイス

プラットフォームで利用するデバイスを指定

指定したプラットフォームから利用できるデバイスと利用できないデバイスがある

grouseで利用するNVIDIAのOpenCLプラットフォームではCPUが利用できない

2015/12/16

Page 12: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLから利用できるデバイスの確認

2015/12/16GPGPU実践基礎工学12

#include<stdio.h>#include<CL/cl.h>#define MAX_PLATFORMS (1)#define MAX_DEVICES (4)#define INFO_SIZE (4096)int main(){

cl_uint num_platform, num_device;cl_platform_id platform_ids[MAX_PLATFORMS];cl_device_id device_ids[MAX_DEVICES];char  device_info[INFO_SIZE];

clGetPlatformIDs(MAX_PLATFORMS, platform_ids, &num_platform);printf("number of platforms : %d ¥n", (int)num_platform);for(int pID=0; pID<(int)num_platform; pID++){

printf("platform id : %d¥n", pID);

clGetDeviceIDs(platform_ids[pID], CL_DEVICE_TYPE_ALL, MAX_DEVICES, device_ids, &num_device);printf("device type all¥t : %d ¥n", num_device);for(int dID=0; dID<(int)num_device; dID++){

printf("device id : %d¥n", dID);

clGetDeviceInfo(device_ids[dID], CL_DEVICE_NAME, INFO_SIZE, device_info, NULL);printf("device name¥t : %s ¥n", device_info);clGetDeviceInfo(device_ids[dID], CL_DEVICE_VENDOR, INFO_SIZE, device_info, NULL);printf("device vendor¥t : %s ¥n", device_info);

}}return 0;

} opencl_device.cpp

Page 13: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLから利用できるデバイスの確認

GPGPU実践基礎工学13

clGetPlatformIDs 利用できるOpenCLのプラットフォーム(環境)数を取得

clGetPlatformIDs(取得するプラットフォームの上限,プラットフォーム情報,プラットフォーム数);

clGetDeviceIDs 指定のOpenCLプラットフォームから利用できるデバイスの数を取得

clGetDeviceIDs(プラットフォームID, デバイスの種類,取得するデバイスの上限,デバイス情報,デバイス数);

clGetDeviceInfo プラットフォームから利用できるデバイス数の詳細情報を取得

clGetDeviceInfo(デバイスID, 取得する情報,保存先のchar型配列のサイズ,保存先のchar型配列, 取得した文字数);

2015/12/16

Page 14: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLから利用できるデバイスの確認

GPGPU実践基礎工学14

実行結果number of platforms : 1platform id : 0device type all  : 4device id : 0device name      : Tesla M2050device vendor    : NVIDIA Corporationdevice id : 1device name      : Tesla M2050device vendor    : NVIDIA Corporationdevice id : 2device name      : Tesla M2050device vendor    : NVIDIA Corporationdevice id : 3device name      : Tesla M2050device vendor    : NVIDIA Corporation

←利用できるプラットフォームは1個

←プラットフォームID0から利用できるデバイスは4個

2015/12/16

プラットフォームID0から利用できるデバイスの情報(名前とメーカー)

Page 15: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLプログラムの決まり事

GPGPU実践基礎工学15

OpenCLのヘッダをインクルードする

#include<CL/cl.h>

OpenCLで利用する変数の型や関数はclで始まる

cl_uint型 clGetPlatformIDs()

コンパイル時にはOpenCLのライブラリへリンクする

‐lOpenCLオプションを付与

2015/12/16

Page 16: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

ハードウェアモデル

GPGPU実践基礎工学16

OpenCLデバイスは複数の演算ユニットから構成

演算ユニットは複数のプロセッシングエレメント(PE)から構成

GPUとの対応

OpenCLデバイス = GPU 演算ユニット = SM PE = CUDA Core

OpenCLデバイス

PE PE PEPE

・・・

PE PE PEPE

演算ユニット

PE PE PEPE

PE PE PEPE

演算ユニット

2015/12/16

Page 17: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

並列プログラミングモデル

GPGPU実践基礎工学17

データ並列プログラミング

タスク並列プログラミングモデル

ホストプログラム コマンドキュー

処理

OpenCLデバイス

演算ユニット

演算ユニット

演算ユニット

処理

処理

処理

インデックス空間

1

2

3

データ並列実行指示

データ並列実行

ホストプログラム コマンドキュー

OpenCLデバイス

演算ユニット

演算ユニット

演算ユニット

処理

処理

処理

タスク並列実行指示

タスク並列実行

処理

処理

処理

インデックス空間1

インデックス空間1

インデックス空間1

2015/12/16

Page 18: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

並列プログラミングモデル

GPGPU実践基礎工学18

データ並列実行時に演算ユニットとPEに固有のIDを付与

インデックス空間の展開

演算ユニットで実行する単位

ワークグループ

PEで実行する単位

ワークアイテム

OpenCLデバイス

PE

PE

PE演算ユニット

ワークアイテムID 0

ワークアイテムID 1

ワークアイテムID 2

ワークグル

ープID 0

PE

PE

PE演算ユニット

ワークアイテムID 0

ワークアイテムID 1

ワークアイテムID 2

ワークグル

ープID 1

グローバルアイテム数 6ローカルアイテム数 3

2015/12/16

Page 19: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

メモリモデル

GPGPU実践基礎工学19

グローバルメモリ

全てのワークアイテムから読み書きできるメモリ

コンスタントメモリ

全てのワークアイテムから読み込みだけができるメモリ

ローカルメモリ

ワークグループ内のワークアイテムが共有できるメモリ

プライベートメモリ

ワークアイテム専用のメモリ

2015/12/16

Page 20: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

メモリモデル

GPUとの対応

グローバルメモリ=グローバルメモリ

コンスタントメモリ=コンスタントメモリ

ローカルメモリ=共有メモリ

プライベートメモリ=レジスタ

GPGPU実践基礎工学20

全てのワークアイテムがデータを共有

ワークグループ内でデータを共有

コンスタントメモリ

OpenCLデバイス

P P P P

PE PE PE PE

ローカルメモリ

演算ユニット

P P P P

PE PE PE PE

ローカルメモリ

演算ユニット

グローバルメモリ

各ワークアイテムが個別のデータを保有

2015/12/16

プライベートメモリ

プロセッシングエレメント

Page 21: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

カーネルの作成

GPGPU実践基礎工学21

関数に修飾子__kernelを付加

引数となる変数にアドレス修飾子を付加

グローバルメモリに存在する場合 __global コンスタントメモリに存在する場合 __constant ローカルメモリに存在する場合 __local プライベートメモリに存在する場合 __private

一つのワークアイテムが実行する内容を記述

ワークアイテムのIDを取得

IDを基に並列処理を実行

2015/12/16

Page 22: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

ホストコード

2015/12/16GPGPU実践基礎工学22

カーネルを実行するために大量の下準備が必要

1.実行するプラットフォームの特定

2.利用するデバイスの決定*

3.コンテキストの作成

4.コマンドキューの作成

5.メモリオブジェクトの作成*

6.カーネルの読み込み

7.プログラムオブジェクトの作成

8. カーネルのコンパイル

9. カーネルオブジェクトの作成

10. カーネル引数の設定

11. コマンドキューへの投入(カーネルの実行*)

12. メモリオブジェクトから結果を読み出し*

13. オブジェクトの解放*

*GPUと共通

Page 23: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

ベクトル和C=A+Bの計算

配列A, B, Cで参照する配列要素番号iが同じ

各スレッドがある配列添字iを処理

1スレッドが1要素の計算を実行

GPGPU実践基礎工学23 2015/12/16

・・・

・・・

・・・c[i]

a[i]

b[i]

+ + + + + +

スレッド0 スレッド2スレッド1 スレッド3

Page 24: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

CUDAの並列化階層と情報の参照

N=8, <<<2, 4>>>で実行

c[i]

a[i]

b[i]

+ + + + + + + +

gridDim.x=2

blockIdx.x=0 blockIdx.x=1

blockDim.x=4blockDim.x=4threadIdx.x=

0    1   2    3 0    1   2    3

threadIdx.x=

2015/12/16GPGPU実践基礎工学24

i=   0    1   2    3   4    5   6    7=  blockIdx.x*blockDim.x + threadIdx.x

Page 25: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

CUDA Cと同じ条件で並列実行

c[i]

a[i]

b[i]

+ + + + + + + +

get_num_groups()

get_group_id() get_group_id()

get_local_size()get_local_size()get_local_id()

0    1   2    3 0    1   2    3

get_local_id()

2015/12/16GPGPU実践基礎工学25

i=   0    1   2    3   4    5   6    7=  get_global_id()

OpenCLの並列化階層と情報の参照

Page 26: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

逐次プログラム

2015/12/16GPGPU実践基礎工学26

#include<stdlib.h>#define N (1024*1024)#define Nbytes (N*sizeof(float))

void init(float *a, float *b, float *c){

int i;

for(i=0; i<N; i++){a[i] = 1.0;b[i] = 2.0;c[i] = 0.0;

}}

void add(float *a, float *b, float *c){

int i;

for(i=0; i<N; i++)c[i] = a[i] + b[i];

}

int main(void){float *a,*b,*c;

a = (float *)malloc(Nbytes);b = (float *)malloc(Nbytes);c = (float *)malloc(Nbytes);

init(a,b,c);add(a,b,c);

free(a);free(b);free(c);return 0;

}

Page 27: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

CUDA Cによる並列実行プログラム

2015/12/16GPGPU実践基礎工学27

#define N (1024*1024)#define Nbytes (N*sizeof(float))

__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<<< N/256, 256>>>(a,b,c);add<<< N/256, 256>>>(a,b,c);

cudaFree(a);cudaFree(b);cudaFree(c);return 0;

}

Page 28: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

CUDA CのKernel

2015/12/16GPGPU実践基礎工学28

__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];

}

Page 29: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLのカーネルコード

2015/12/16GPGPU実践基礎工学29

__kernel void init(__global float *a, __global float *b, __global float *c){int i = get_global_id(0);

a[i] = 1.0;b[i] = 2.0;c[i] = 0.0;

}

__kernel void add(__global float *a, __global float *b, __global float *c){int i = get_global_id(0);

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

}

clvectoradd.cl

Page 30: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLのホストプログラム

2015/12/16GPGPU実践基礎工学30

#include<stdio.h>#include<stdlib.h>#include<CL/cl.h>

#define N (1024*1024)#define NBytes (N*sizeof(float))#define MAX_SOURCE_SIZE (0x100000)

int main(){

cl_device_id device_id = NULL;cl_platform_id platform_id = NULL;cl_context context            = NULL;cl_command_queue command_queue = NULL;cl_uint num_platform;cl_uint num_device;cl_int stat;

cl_program program  = NULL;cl_kernel kernel[2] = {NULL,NULL};

cl_mem a = NULL;cl_mem b = NULL;cl_mem c = NULL;

float *host_c=(float *)malloc(Bytes);

FILE  *fp;char  *filename = "./add.cl";char  *source_str;size_t source_size;

//6.カーネルのソースコードを読み込みif( (fp = fopen(filename,"r"))==NULL ){

printf("error¥n");return 1;

}source_str = (char *)malloc

(MAX_SOURCE_SIZE);source_size = fread(source_str,1, 

MAX_SOURCE_SIZE, fp);fclose(fp);

clvectoradd.cpp

Page 31: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLのホストプログラム

2015/12/16GPGPU実践基礎工学31

//1.実行するプラットフォームの決定clGetPlatformIDs(1, &platform_id,

&num_platform);

//2.実行するデバイスの決定clGetDeviceIDs(platform_id,

CL_DEVICE_TYPE_DEFAULT, 1, &device_id, &num_device);

//3.OpenCLコンテキストの作成context = clCreateContext(NULL, 1, 

&device_id, NULL, NULL, &stat);

//4.コマンドキューの作成command_queue = clCreateCommandQueue

(context, device_id, 0, &stat);

//5.メモリバッファオブジェクトの作成a = clCreateBuffer(context, CL_MEM_READ_WRITE, NBytes, NULL, &stat);

b = clCreateBuffer(context, CL_MEM_READ_WRITE, NBytes, NULL, &stat);

c = clCreateBuffer(context, CL_MEM_READ_WRITE, NBytes, NULL, &stat);

//7.プログラムオブジェクトの作成program = clCreateProgramWithSource(context, 1, (const char **)&source_str, 

(const size_t *)&source_size, &stat);

//8.カーネルのコンパイルclBuildProgram(program,1, &device_id,

NULL, NULL, NULL);

//9.カーネルオブジェクトの作成kernel[0] = clCreateKernel(program, 

"init", &stat);kernel[1] = clCreateKernel(program, 

"add", &stat);

clvectoradd.cpp

Page 32: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLのホストプログラム

2015/12/16GPGPU実践基礎工学32

//10.カーネル引数の設定clSetKernelArg(kernel[0], 0, 

sizeof(cl_mem), (void *)&a);clSetKernelArg(kernel[0], 1, 

sizeof(cl_mem), (void *)&b);clSetKernelArg(kernel[0], 2, 

sizeof(cl_mem), (void *)&c);clSetKernelArg(kernel[1], 0, 

sizeof(cl_mem), (void *)&a);clSetKernelArg(kernel[1], 1, 

sizeof(cl_mem), (void *)&b);clSetKernelArg(kernel[1], 2, 

sizeof(cl_mem), (void *)&c);

//アイテムの数(並列度)の設定size_t global_item_size = N;size_t local_item_size = 256;

//11.カーネルの実行clEnqueueNDRangeKernel(command_queue, 

kernel[0], 1, NULL, &global_item_size, &local_item_size, 0, NULL, NULL);

clEnqueueNDRangeKernel(command_queue, kernel[1], 1, NULL, &global_item_size, 

&local_item_size, 0, NULL, NULL);

//12.メモリオブジェクトから結果を読み出しclEnqueueReadBuffer(command_queue, c, 

CL_TRUE,0,NBytes,host_c,0,NULL,NULL);

//結果の表示for(int i=0; i<N; i++)

printf("%d, %f¥n",i,host_c[i]);

clvectoradd.cpp

Page 33: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

OpenCLのホストプログラム

2015/12/16GPGPU実践基礎工学33

//13.オブジェクトの解放clFlush (command_queue);clFinish(command_queue);clReleaseKernel(kernel[1]);clReleaseKernel(kernel[0]);clReleaseProgram(program);clReleaseMemObject(a);clReleaseMemObject(b);clReleaseMemObject(c);clReleaseCommandQueue(command_queue);clReleaseContext(context);

free(host_c);free(source_str);

return 0;

}

clvectoradd.cpp

Page 34: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

性能比較

2015/12/16GPGPU実践基礎工学34

配列の要素数220

CUDA CとOpenCLで同じ傾向

1ブロックあたりのスレッド数が増加すると性能が向上

スレッド数を多くしすぎると性能が低下

OpenCLはCUDAより実行効率の悪い実行ファイルを生成?

Number of Threads/Block

Processing time [ms]CUDA C OpenCL

32 0.276 0.43164 0.169 0.301128 0.128 0.268256 0.119 0.257512 0.120 0.2581024 0.151 0.279

Page 35: 2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)

GPU/CUDAとOpenCLの対応

GPU

SM

CUDA Core

GPU

GPGPU実践基礎工学35

CUDA

Grid

Block

Thread

OpenCL

OpenCLデバイス

ワークグループ

ワークアイテム

OpenCL

グローバルメモリコンスタントメモリ

ローカルメモリ

プライベートメモリ

OpenCL

OpenCLデバイス

演算ユニット

プロセッシングエレメント

GPU/CUDA

グローバルメモリコンスタントメモリ

共有メモリ

レジスタ

ハードウェア構成 並列化階層 メモリ階層

ワークグループID

ワークアイテムID(ローカルID)

blockIdx

threadIdx

2015/12/16