SlideShare a Scribd company logo
1 of 55
Download to read offline
Introduction to OpenCL
TAKAHIRO HARADA
JUNE 2013
2INTRODUCTION TO OPENCL | JUNE, 2013
AGENDA
} Introduction
–  GPU Architecture
} OpenCL Example
–  Vector Add
–  Reduction
} Performance Tips
} APU Specific Optimization
INTRODUCTION
4INTRODUCTION TO OPENCL | JUNE, 2013
GPUの活用
} グラフィックスのタスク用のプロセッサ
} 並列度の高い汎用計算にも向いている
} CPUとは異なる設計
–  CPU:逐次処理
–  GPU:並列処理
} プログラミング言語
–  OpenGL, GLSL
•  ラスターグラフィックスのAPI
•  汎用計算用ではない
–  グラフィックスAPIをハックしなければならない
•  クロスプラットフォーム
–  DirectX, HLSL
•  ラスターグラフィックスAPI
•  汎用計算にはDirect Compute (DX11)
•  DirectX11をサポートしたプラットフォームが必要 (Windows 7)
•  Windows OSのみ
–  OpenCL
CPU GPU
work
work work work work work work work work
work
work
work
5INTRODUCTION TO OPENCL | JUNE, 2013
OPENCL
} GPUを含めた並列プロセッサ用のOpen Compute Language (OpenCL)
} OpenCL 1.0の仕様は 2008年にリリース
} 現在はv1.2
} 言語はISO C99に拡張と制約を加えたもの
} ソフトウェアのポータビリティ
–  クロスプラットフォームのサポート
•  Windows, Mac, Linux
–  マルチデバイスのサポート
•  GPU
–  AMD, NVIDIA, Intel
•  CPU
•  etc
–  一度書けばサポートされているデバイス上ならどこでも実行可能
GPU ARCHITECTURE
7INTRODUCTION TO OPENCL | JUNE, 2013
演算ユニット
} AMD Radeon HD 7970 (GCNアーキテクチャ)
–  3.8 TFLOPS (S)
–  974 GFLOPS (D)
–  264 GB/s
} 高い演算能力
–  演算を並列で行うため
–  128 SIMDエンジン (コア)
•  64 wide SIMD
SIMDs (Cores) SIMD width
Radeon HD
7970 (GPU)
128 64
FX 8350 (CPU) 8 8 (AVX)
AMD Radeon HD 7970
8INTRODUCTION TO OPENCL | JUNE, 2013
メモリ
} CPU
–  レジスタ
–  キャッシュ
–  メモリ (Host memory)
} GPU
–  レジスタ
–  キャッシュ
–  ローカルメモリ (Local Data Share)
–  メモリ (Global memory)
Reg Reg Reg Reg Reg Reg Reg Reg
Reg Reg Reg Reg Reg Reg Reg Reg
L1 Cache
Local Data Share
L2 Cache
Reg Reg Reg Reg Reg Reg Reg Reg
Reg Reg Reg Reg Reg Reg Reg Reg
L1 Cache
Local Data Share
Device (Global) Memory
Reg Reg Reg Reg
L1 Cache
Reg Reg Reg Reg
L1 Cache
Reg Reg Reg Reg
L1 Cache
Reg Reg Reg Reg
L1 Cache
L2 Cache
Host Memory PCIe
x128
9INTRODUCTION TO OPENCL | JUNE, 2013
GPUプログラムの実行
} GPUはホストのメモリに直接アクセスできない
–  デバイスメモリのみアクセス可能
} GPUでの計算手順
–  データをPCIeバスを通してデバイスメモリに移動
–  GPUでの演算
–  結果をホストメモリに読み戻し
Reg Reg Reg Reg Reg Reg Reg Reg
Reg Reg Reg Reg Reg Reg Reg Reg
L1 Cache
Local Data Share
L2 Cache
Reg Reg Reg Reg Reg Reg Reg Reg
Reg Reg Reg Reg Reg Reg Reg Reg
L1 Cache
Local Data Share
Device (Global) Memory
Reg Reg Reg Reg
L1 Cache
Reg Reg Reg Reg
L1 Cache
Reg Reg Reg Reg
L1 Cache
Reg Reg Reg Reg
L1 Cache
L2 Cache
Host Memory PCIe
x128
10INTRODUCTION TO OPENCL | JUNE, 2013
OPENCLのアプリケーションの例
} 物理シミュレーション
–  流体シミュレーション
–  剛体シミュレーション
} グラフィックス
–  ポストプロセス
–  レイトレーシング
OPENCL EXAMPLE:
VECTOR ADD
12INTRODUCTION TO OPENCL | JUNE, 2013
CPU VECTOR ADD
} CPUコードは簡単
float* a = new float[n];
float* b = new float[n];
float* c = new float[n];
for(int i=0; i<n; i++)
{
b[i] = i;
c[i] = n;
}
for(int i=0; i<n; i++)
{
a[i] = b[i] + c[i];
}
delete [] a;
delete [] b;
delete [] c;
Memory allocation
Initialization
Computation
Memory deallocation
13INTRODUCTION TO OPENCL | JUNE, 2013
OPENCL上で実装するために
} 3つのことを行わなければならない
1.  OpenCLメモリの確保、解放 (アロケーション、デアロケーション)
2.  計算ロジックをOpenCLカーネルとして実装
3.  OpenCLカーネルをOpenCL APIを用いて実行
14INTRODUCTION TO OPENCL | JUNE, 2013
メモリのアロケーション、デアロケーション
} CPU
–  アロケーション
–  デアロケーション
} OpenCL
–  アロケーション
–  デアロケーション
float* a = new float[n];
delete [] a;
cl_mem a = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e );
clReleaseMemObject( a );
Memory size in byte
15INTRODUCTION TO OPENCL | JUNE, 2013
計算ロジックのOPENCLカーネルへの実装
} CPU
–  n個の演算が逐次的に行われる
} OpenCL
–  n個の演算が並列で行われる
–  ワークアイテムが一要素の計算を行う
•  ワークアイテム(WI) == 演算の単位
–  それぞれの要素の処理の関数をOpenCLカーネルとして書く
–  ホストのCコードの中ではなく別ファイル(.cl)に
for(int i=0; i<n; i++)
{
a[i] = b[i] + c[i];
}
__kernel
void addKernel( __global float* a,
__global float* b,
__global float* c )
{
int i = get_global_id(0);
a[i] = b[i] + c[i];
}
__global : for a memory allocated in global memory
__local : for a memory allocated in local memory
計算のパターンが完全に並列ならばコードをそのまま
使うことができる
16INTRODUCTION TO OPENCL | JUNE, 2013
OPENCLカーネルのOPENCL APIを用いた実行
} OpenCLのメモリを引数にセットする
–  引数の番号をそれぞれ指定する
} カーネルの実行
clSetKernelArg(kernel1, 0, sizeof(cl_mem), (void*)&a);
clSetKernelArg(kernel1, 1, sizeof(cl_mem), (void*)&b);
clSetKernelArg(kernel1, 2, sizeof(cl_mem), (void*)&c);
clEnqueueNDRangeKernel( queue, kernel1, 1, 0, gSize, lSize, 0, 0, 0 );
__kernel
void addKernel( __global float* a,
__global float* b,
__global float* c )
{
int i = get_global_id(0);
a[i] = b[i] + c[i];
}
Order of an argument
Work group size [64, 1, 1]
Global work size [n,1,1]
17INTRODUCTION TO OPENCL | JUNE, 2013
OPENCLでのVECTOR ADD
__kernel
void initKernel( __global float* b,
__global float* c )
{
int i = get_global_id(0);
b[i] = i;
c[i] = n;
}
__kernel
void addKernel( __global float* a,
__global float* b,
__global float* c )
{
int i = get_global_id(0);
a[i] = b[i] + c[i];
}
cl_mem a = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e );
cl_mem b = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e );
cl_mem c = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e );
clSetKernelArg(kernel0, 0, sizeof(cl_mem), (void*)&b);
clSetKernelArg(kernel0, 1, sizeof(cl_mem), (void*)&c);
clEnqueueNDRangeKernel( queue, kernel0, 1, 0, gSize, lSize, 0, 0, 0 );
clSetKernelArg(kernel1, 0, sizeof(cl_mem), (void*)&a);
clSetKernelArg(kernel1, 1, sizeof(cl_mem), (void*)&b);
clSetKernelArg(kernel1, 2, sizeof(cl_mem), (void*)&c);
clEnqueueNDRangeKernel( queue, kernel1, 1, 0, gSize, lSize, 0, 0, 0 );
clReleaseMemObject( a );
clReleaseMemObject( b );
clReleaseMemObject( c );
Memory allocation
Initialization
Computation
Memory deallocation
18INTRODUCTION TO OPENCL | JUNE, 2013
コードの比較
CPU OpenCL
float* a = new float[n];
float* b = new float[n];
float* c = new float[n];
for(int i=0; i<n; i++)
{
b[i] = i;
c[i] = n;
}
for(int i=0; i<n; i++)
{
a[i] = b[i] + c[i];
}
delete [] a;
delete [] b;
delete [] c;
cl_mem a = clCreateBuffer( context, CL_MEM_READ_WRITE, siz
cl_mem b = clCreateBuffer( context, CL_MEM_READ_WRITE, siz
cl_mem c = clCreateBuffer( context, CL_MEM_READ_WRITE, siz
clSetKernelArg(kernel0, 0, sizeof(cl_mem), (void*)&b);
clSetKernelArg(kernel0, 1, sizeof(cl_mem), (void*)&c);
clEnqueueNDRangeKernel( queue, kernel0, 1, 0, gSize, lSize
clSetKernelArg(kernel1, 0, sizeof(cl_mem), (void*)&a);
clSetKernelArg(kernel1, 1, sizeof(cl_mem), (void*)&b);
clSetKernelArg(kernel1, 2, sizeof(cl_mem), (void*)&c);
clEnqueueNDRangeKernel( queue, kernel1, 1, 0, gSize, lSize
clReleaseMemObject( a );
clReleaseMemObject( b );
clReleaseMemObject( c );
Memory allocation
Initialization
Computation
Memory deallocation
19INTRODUCTION TO OPENCL | JUNE, 2013
OPENCL上で実装するために
} 3つのことを行わなければならない
1.  OpenCLメモリの確保、解放 (アロケーション、デアロケーション)
2.  計算ロジックをOpenCLカーネルとして実装
3.  OpenCLカーネルをOpenCL APIを用いて実行
} 本当はもう少し必要
1.  OpenCLの初期化と解放 (Context, queue, device ID)
2.  OpenCLカーネルのコンパイル	
3.  OpenCLメモリへのデータのコピー
cl_mem a = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e );
clEnqueueNDRangeKernel( queue, kernel0, 1, 0, gSize, lSize, 0, 0, 0 );
20INTRODUCTION TO OPENCL | JUNE, 2013
OPENCLの初期化と解放
} OpenCLコンテクスト、キュー、デバイスIDの生成
} OpenCLコンテクスト、キューの解放
clReleaseCommandQueue( queue );
clReleaseContext( context );
cl_context context;
cl_command_queue queue;
cl_device_id device;
cl_platform_id platform;
cl_uint nPlatforms;
clGetPlatformIDs( 0, 0, &nPlatforms );
clGetPlatformIDs( 1, &platform, 0 );
clGetDeviceIDs( platform, CL_DEVICE_TYPE_GPU, 1, &device, 0 );
context = clCreateContext( 0, 1, &device, 0, 0, &e );
queue = clCreateCommandQueue( context, device, 0, &e );
21INTRODUCTION TO OPENCL | JUNE, 2013
OPENCLカーネルのコンパイル
} OpenCLカーネルをchar配列として読み込み (s_kernel)
–  プログラムの生成 (Create Program)
–  ビルド (Build Program)
–  カーネルの生成 (Create Kernel)
cl_kernel kernel1;!
cl_program program = clCreateProgramWithSource( context, 1, &s_kernel, &length, &e );!
clBuildProgram( program, 1, &device, 0, 0, 0 );!
kernel1 = clCreateKernel( program, "addKernel", &e );
22INTRODUCTION TO OPENCL | JUNE, 2013
OPENCLのメモリへのアクセス
} 直接アクセスすることはできない
} 明示的なコピーが必要
} Map, Unmap
float* host = new float[n];
cl_mem device = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e );
clEnqueueWriteBuffer( queue, device, CL_FALSE, 0, sizeof(float)*n, host, 0, 0, 0 );
clFinish( queue );
clEnqueueReadBuffer( queue, device, CL_FALSE, 0, sizeof(float)*n, host, 0, 0, 0 );
clFinish( queue );
delete [] host;
clReleaseMemObject( device );
clEnqueueMapBuffer(), clEnqueueUnmapMemObject()
23INTRODUCTION TO OPENCL | JUNE, 2013
ホストコード
// memory allocation and execution
cl_mem a = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e );
cl_mem b = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e );
cl_mem c = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e );
clSetKernelArg(kernel0, 0, sizeof(cl_mem), (void*)&b);
clSetKernelArg(kernel0, 1, sizeof(cl_mem), (void*)&c);
clEnqueueNDRangeKernel( queue, kernel0, 1, 0, gSize, lSize, 0, 0, 0 );
clSetKernelArg(kernel1, 0, sizeof(cl_mem), (void*)&a);
clSetKernelArg(kernel1, 1, sizeof(cl_mem), (void*)&b);
clSetKernelArg(kernel1, 2, sizeof(cl_mem), (void*)&c);
clEnqueueNDRangeKernel( queue, kernel1, 1, 0, gSize, lSize, 0, 0, 0 );
clReleaseMemObject( a );
clReleaseMemObject( b );
clReleaseMemObject( c );
// initialization
cl_context context;
cl_command_queue queue;
cl_device_id device;
cl_platform_id platform;
cl_uint nPlatforms;
clGetPlatformIDs( 0, 0, &nPlatforms );
clGetPlatformIDs( 1, &platform, 0 );
clGetDeviceIDs( platform, CL_DEVICE_TYPE_GPU, 1, &device, 0 );
context = clCreateContext( 0, 1, &device, 0, 0, &e );
queue = clCreateCommandQueue( context, device, 0, &e );
// kernel creation
cl_program program = clCreateProgramWithSource( context, 1,
(const char **)&s_kernel0, &kernelLength0, &e );
clBuildProgram( program, 1, &device, 0, 0, 0 );
cl_kernel kernel0 = clCreateKernel(program, ”initKernel", &e);
cl_program program1 = clCreateProgramWithSource( context, 1,
(const char **)&s_kernel1, &kernelLength1, &e );
clBuildProgram( program1, 1, &device, 0, 0, 0 );
cl_kernel kernel1 = clCreateKernel(program1, "addKernel", &e);
// release
clReleaseKernel( kernel0 );
clReleaseKernel( kernel1 );
clReleaseCommandQueue( queue );
clReleaseContext( context );
24INTRODUCTION TO OPENCL | JUNE, 2013
TIPS
} OpenCLの実行は非同期
–  clEnqueueReadBuffer()が呼ばれても、メモリがホストメモリにコピーされるとは限らない
•  コマンドをDevice(GPU)に送るだけ
–  clEnqueueNDRangeKernel()もDeviceにコマンドを送るだけ
–  確実に実行するためにはclFinish()を使う
•  DeviceプログラムとHostプログラムの同期
•  それまでに発行されたコマンドが実行されるのを待つ
} APIの実行のエラーのステータスの確認
–  CL_SUCCESSならばOK
–  それ以外ならば何かが正しくない
•  引数の確認
} OpenCL printf
–  デバッグに有用
–  パフォーマンスに影響
–  #pragma OPENCL EXTENSION cl_amd_printf : enable
25INTRODUCTION TO OPENCL | JUNE, 2013
OPENCL C言語拡張(OPENCLカーネル内)
} ベクタータイプ
–  float4 (x,y,z,w)
–  int4 (x,y,z,w)
} ワークアイテム、ワークグループの情報を取り出す関数
–  get_global_id()
–  get_local_id()
} 同期
–  barrier()
} メモリ空間の指定
–  __kernel
•  ホストから呼び出すことができるカーネル関数
–  __global
•  グローバルメモリ
–  __local
•  ローカルメモリ
__kernel
void add4Kernel( __global float4* a,
__global float4* b,
__global float4* c )
{
int i = get_global_id(0);
a[i] = b[i] + c[i];
}
WORK GROUP, WORK ITEM
27INTRODUCTION TO OPENCL | JUNE, 2013
ワークアイテム
} 計算の単位
} カーネルを一度実行
} Vector Addではカーネルをn回実行した
–  n個のワークアイテムを実行
–  どのように実行?
28INTRODUCTION TO OPENCL | JUNE, 2013
実行の次元 (WORK DIMENSIONS)
} 処理データの次元にあわせるのが一般的
} 1, 2, 3次元
2 dimensional execution
二次元配列の処理(画像)
clEnqueueNDRangeKernel( q, k, 1, 0,
[n,1,1], l, 0, 0, 0 );
1 dimensional execution
一次元配列の処理
for(int i=0; i<n; i++)
{
a[i] = b[i] + c[i];
}
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
{
a[i][j] = b[i][j] + c[i][j];
}
n
n
n
clEnqueueNDRangeKernel( q, k, 2, 0,
[n,n,1], l, 0, 0, 0 );
29INTRODUCTION TO OPENCL | JUNE, 2013
ワークグループ
Work dim: 2
Global dim: 32x32
Local dim : 16x16
Using 4 SIMDs
clEnqueueNDRangeKernel( q, k, 2, 0,
[32,32,1], [16,16,1], 0, 0, 0 );
(0,0) (1,0) (2,0) (3,0)
(0,1)
(0,2)
(0,3)
Work dim: 2
Global dim: 32x32
Local dim : 8x8
Using 16 SIMDs
clEnqueueNDRangeKernel( q, k, 2, 0,
[32,32,1], [8,8,1], 0, 0, 0 );
(0,0) (1,0)
(0,1) (1,1)
get_group_id(0) == 2
get_group_id(1) == 0
30INTRODUCTION TO OPENCL | JUNE, 2013
ワークアイテムの識別
(0,0) (1,0) (2,0) (3,0)
(0,1)
(0,2)
(0,3)
get_local_id(0) == 5
get_local_id(1) == 2
get_global_id(0) == 8x2+5
get_global_id(1) == 8x0+2
Work dim: 2
Global dim: 32x32
clEnqueueNDRangeKernel( q, k, 2, 0,
[32,32,1], [8,8,1], 0, 0, 0 );
Local dim: 8x8
Workgroup id: (2,0)
__kernel
void addKernel( __global float* a,
__global float* b,
__global float* c )
{
int i = get_global_id(0);
a[i] = b[i] + c[i];
}
31INTRODUCTION TO OPENCL | JUNE, 2013
まとめ
(0,0) (1,0) (2,0) (3,0)
(0,1)
(0,2)
(0,3)
Work dimensions
clEnqueueNDRangeKernel( q, k, 2, 0,
[32,32,1], [8,8,1], 0, 0, 0 );
Global dimensions
Local dimensions
OPENCL EXAMPLE:
REDUCTION
33INTRODUCTION TO OPENCL | JUNE, 2013
REDUCTION (MAX)
} 最大値を探す
} Vector Addの例のような単純な並列処理ではない
} 全ての要素をチェック
} この例で学ぶのは
–  OpenCLの拡張機能の使用
–  ワークグループの概念
–  LDS
Reg Reg Reg Reg Reg Reg Reg Reg
Reg Reg Reg Reg Reg Reg Reg Reg
L1 Cache
Local Data Share
L2 Cache
Reg Reg Reg Reg Reg Reg Reg Reg
Reg Reg Reg Reg Reg Reg Reg Reg
L1 Cache
Local Data Share
Device (Global) Memory
x128
34INTRODUCTION TO OPENCL | JUNE, 2013
REDUCTION (MAX)
CPU
} maxValueと順番に比較していく
OpenCL
} メモリ書き込みの競合が起こる
int* a = new int[n];
// initialize a[]
float maxValue = 0;
for(int i=0; i<n; i++)
{
maxValue = max( maxValue, a[i] );
}
delete [] a;
__kernel
void reductionKernel( __global int* a,
__global int* maxValue )
{
int i = get_global_id(0);
maxValue[0] = max( maxValue[0], a[i] );
}
35INTRODUCTION TO OPENCL | JUNE, 2013
REDUCTION (MAX)
CPU
} maxValueと順番に比較していく
OpenCL
} アトミックオペレーションを用いることで並列化可能
} アトミクスは拡張機能なので有効化する必要あり
int* a = new int[n];
// initialize a[]
float maxValue = 0;
for(int i=0; i<n; i++)
{
maxValue = max( maxValue, a[i] );
}
delete [] a;
#pragma OPENCL EXTENSION
cl_khr_global_int32_extended_atomics : enable
__kernel
void reductionKernel( __global int* a,
__global int* maxValue )
{
int i = get_global_id(0);
atomic_max( &maxValue[0], a[i] );
}
36INTRODUCTION TO OPENCL | JUNE, 2013
この実装の問題点
} 全てのワークアイテムがアトミックオペレーションを同じメモリに対して行う
–  メモリ処理が逐次化される可能性もある
–  GPUのパフォーマンスを引き出せない
} 解決法
–  ワークグループを活用
a[N]
maxValue
37INTRODUCTION TO OPENCL | JUNE, 2013
ワークグループ
} ワークグループは複数のワークアイテムをまとめたもの
} 一つのワークグループは一つのSIMDエンジンが実行
–  SIMDエンジンはLDSを持つ
} ローカルデータシェア (LDS)
–  レジスタはそれぞれのワークアイテムのみがアクセスできるメモリ
–  LDSはワークグループ内のワークアイテムが共有できるもの
–  LDSにアクセスするレイテンシ < グローバルメモリにアクセスするレイテンシ
} ワークグループ内のワークアイテムは同期可能
Reg Reg Reg Reg Reg Reg Reg Reg
Reg Reg Reg Reg Reg Reg Reg Reg
L1 Cache
Local Data Share
L2 Cache
Reg Reg Reg Reg Reg Reg Reg Reg
Reg Reg Reg Reg Reg Reg Reg Reg
L1 Cache
Local Data Share
Device (Global) Memory
x128
38INTRODUCTION TO OPENCL | JUNE, 2013
演算の可視化
} 二段階のreduction
–  20ローカルアトミクス
–  4グローバルアトミクス
} 単純な実装
–  20グローバルアトミクス
Work Group0 Work Group1 Work Group2 Work Group3
Global max
Local max
39INTRODUCTION TO OPENCL | JUNE, 2013
二段階のREDUCTION KERNEL
#pragma OPENCL EXTENSION
cl_khr_global_int32_extended_atomics : enable
#pragma OPENCL EXTENSION
cl_khr_local_int32_extended_atomics : enable
__kernel
void reduction2levelKernel( __global int* a,
__global int* maxValue )
{
__local int localMax;
int i = get_global_id(0);
if( get_local_id(0) == 0 )
localMax = 0;
barrier(CLK_LOCAL_MEM_FENCE);
atomic_max( &localMax, a[i] );
barrier(CLK_LOCAL_MEM_FENCE);
if( get_local_id(0) == 0 )
atomic_max( &maxValue[0], localMax );
}
Enable Extensions
Initialize local max
Synchronization
Local reduction
Synchronization
Global reduction
PERFORMANCE TIPS
41INTRODUCTION TO OPENCL | JUNE, 2013
GPUの全てを使い切る
} GPUのハイパフォーマンスはその並列アーキテクチャに起因する
} 可能な限り多くの演算ユニットを使用する方が良い
–  逐次コードを実行するとストリームプロセッサ一個しか使わない
–  全体の1/(32*4*64) == 0.012%
42INTRODUCTION TO OPENCL | JUNE, 2013
ワークグループの大きさ : ウェーブフロントの大きさ
} ワークグループはSIMDエンジンによって実行される
} AMD GPUのSIMDエンジンは64個のワークアイテムを並列に処理
–  並列処理の単位 == ウェーブフロント
} ワークグループの大きさ (ワークアイテムの数) == 64の倍数が良い
43INTRODUCTION TO OPENCL | JUNE, 2013
ワークグループの大きさ : ウェーブフロントの大きさ
} X ワークグループサイズ == 1ワークアイテム
–  SIMDエンジンが 1サイクルで処理
–  SIMDエンジンの大半は処理待ち (63 idles, 1active)
} X ワークグループサイズ == 32ワークアイテム
–  SIMDエンジンが 1サイクルで処理
–  SIMDエンジンの半分は処理待ち
} O ワークグループサイズ == 128ワークアイテム
–  SIMDエンジンが 2サイクルで処理
–  両方のサイクルとも処理待ちなし
44INTRODUCTION TO OPENCL | JUNE, 2013
メモリーコピーを避ける
} グローバルメモリへのアクセスは遅い
–  レイテンシが高い (待ち時間が多い)
} 不要なデータは読まない
} メモリの広範囲なランダムアクセスを避ける
–  キャッシュが効果的ではなくなる
} 可能であればLDSを使う
–  LDSはユーザが管理できるキャッシュのようなもの
–  使用する前にLDSに読み込む
–  LDS内のランダムアクセスはグローバルメモリのアクセスに比べれば十分小さい
45INTRODUCTION TO OPENCL | JUNE, 2013
ローカルリソースの使用を控える
} ローカルリソースの量には限界がある
–  レジスタ
–  LDS
} あふれたレジスタはグローバルメモリに配置
–  Scratch Registersと呼ばれる
–  それらへのアクセスはとても遅い
–  GPUは実行することはできるので注意
} ローカルリソースの使用量はツールを使って確認可能
–  APP kernel analyzer
–  Code XL
} Southern Island GPU
–  256 vector registers/WI
46INTRODUCTION TO OPENCL | JUNE, 2013
ホスト、デバイス間の同期を最小限にする
} ホスト(CPU)とデバイス(GPU)の同期はGPUの実行パイプをストールさせる
–  カーネルの実行の終了を待つ
–  メモリコピーして値を読み出す
} GPUは処理待ち
} 出来るだけ多くのコマンドをキューに積む
} GPUメモリの値を読み出さない
} 同期を遅らせる
} Code XLを使ってGPUの活動を可視化できる
APU SPECIFIC OPTIMIZATION
48INTRODUCTION TO OPENCL | JUNE, 2013
APUのメモリ
} GPUとCPUは物理的に同じメモリを使用している
–  メモリアドレス空間は異なる
} PCIeバスを通るデータ転送はない
} データコピーは不要なはず
} Zero Copy Memory
–  明示的な宣言が必要
CPU + Discrete GPU
APU (CPU + Integrated GPU)
49INTRODUCTION TO OPENCL | JUNE, 2013
ゼロコピーバッファ
} ゼロコピーバッファのアロケーション
} データへのアクセス
–  APIコールの裏にはデータコピーがない
–  ホストメモリのアドレスを返すだけ
–  普通のバッファのマップはデータ転送を伴う
cl_mem buffer = clCreateBuffer( context,
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
bufferSize, 0, &status );
void* ptr = clEnqueueMapBuffer(commandQueue, buffer, false,
CL_MAP_READ | CL_MAP_WRITE, 0, bufferSize, 0, 0, 0, &status );
50INTRODUCTION TO OPENCL | JUNE, 2013
例
} 処理の粒度はまちまち
} 衝突判定
–  Large vs Large => CPU
–  Large vs Small => CPU
–  Small vs Small => GPU
} CPUとディスクリートGPUを用いると多くのデータ転
送が必要
–  パフォーマンスに響く
OpenCL Case Study: Mixed Particle Simulation, Heterogeneous Computing with OpenCL, Chapter 10
OTHERS
52INTRODUCTION TO OPENCL | JUNE, 2013
BOLT
} 並列演算プリミティブのC++ライブラリ
} オープンソース
} OpenCLのコーディングを行わずにGPUを用いることができる
–  もしアルゴリズムがサポートされているプリミティブから組み立てることができれば
} AMDハードウェアのみ
–  Using OpenCL AMD extensions
} https://github.com/HSA-Libraries/Bolt
int _tmain( int argc, _TCHAR* argv[ ] )
{
size_t length = 1024;
//Create device_vector and initialize it to 1
bolt::cl::device_vector< int > boltInput( length, 1 );
bolt::cl::device_vector< int >::iterator boltEnd = bolt::cl::inclusive_scan
( boltInput.begin( ), boltInput.end( ), boltInput.begin( ) );
//Create std vector and initialize it to 1
std::vector< int > stdInput( length, 1 );
std::vector< int >::iterator stdEnd = bolt::cl::inclusive_scan
( stdInput.begin( ), stdInput.end( ), stdInput.begin( ) );
return 0;
}
53INTRODUCTION TO OPENCL | JUNE, 2013
REFERENCES
} OpenCL
–  http://www.khronos.org/opencl/
–  http://www.khronos.org/registry/cl/specs/opencl-1.2.pdf
} Heterogeneous Computing with OpenCL
–  http://developer.amd.com/partners/university-programs/heterogeneous-computing-with-opencl/
} Introduction to OpenCL Programming
–  http://developer.amd.com/wordpress/media/2013/01/Introduction_to_OpenCL_Programming-201005.pdf
} AMD Graphics Core Next (GCN) Architecture
–  http://www.amd.com/us/Documents/GCN_Architecture_whitepaper.pdf
54INTRODUCTION TO OPENCL | JUNE, 2013
DISCLAIMER & ATTRIBUTION
The information presented in this document is for informational purposes only and may contain technical inaccuracies, omissions and typographical errors.
The information contained herein is subject to change and may be rendered inaccurate for many reasons, including but not limited to product and roadmap
changes, component and motherboard version changes, new model and/or product releases, product differences between differing manufacturers, software
changes, BIOS flashes, firmware upgrades, or the like. AMD assumes no obligation to update or otherwise correct or revise this information. However, AMD
reserves the right to revise this information and to make changes from time to time to the content hereof without obligation of AMD to notify any person of such
revisions or changes.
AMD MAKES NO REPRESENTATIONS OR WARRANTIES WITH RESPECT TO THE CONTENTS HEREOF AND ASSUMES NO RESPONSIBILITY FOR ANY
INACCURACIES, ERRORS OR OMISSIONS THAT MAY APPEAR IN THIS INFORMATION.
AMD SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT
WILL AMD BE LIABLE TO ANY PERSON FOR ANY DIRECT, INDIRECT, SPECIAL OR OTHER CONSEQUENTIAL DAMAGES ARISING FROM THE USE OF
ANY INFORMATION CONTAINED HEREIN, EVEN IF AMD IS EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
ATTRIBUTION
© 2013 Advanced Micro Devices, Inc. All rights reserved. AMD, the AMD Arrow logo and combinations thereof are trademarks of Advanced Micro Devices, Inc.
in the United States and/or other jurisdictions. SPEC is a registered trademark of the Standard Performance Evaluation Corporation (SPEC). Other names are
for informational purposes only and may be trademarks of their respective owners.
55INTRODUCTION TO OPENCL | JUNE, 2013
60MIN
} 10
–  Introduction
–  GPU Architecture
} 25
–  OpenCL Example: Vector Add
–  OpenCL Example: Reduction
} 15
–  Performance Tips
–  APU Specific Optimization

More Related Content

What's hot

FPGAを用いたEdge AIの現状
FPGAを用いたEdge AIの現状FPGAを用いたEdge AIの現状
FPGAを用いたEdge AIの現状Yukitaka Takemura
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例Fixstars Corporation
 
Deep Learningのための専用プロセッサ「MN-Core」の開発と活用(2022/10/19東大大学院「 融合情報学特別講義Ⅲ」)
Deep Learningのための専用プロセッサ「MN-Core」の開発と活用(2022/10/19東大大学院「 融合情報学特別講義Ⅲ」)Deep Learningのための専用プロセッサ「MN-Core」の開発と活用(2022/10/19東大大学院「 融合情報学特別講義Ⅲ」)
Deep Learningのための専用プロセッサ「MN-Core」の開発と活用(2022/10/19東大大学院「 融合情報学特別講義Ⅲ」)Preferred Networks
 
第6回 配信講義 計算科学技術特論A(2021)
第6回 配信講義 計算科学技術特論A(2021)第6回 配信講義 計算科学技術特論A(2021)
第6回 配信講義 計算科学技術特論A(2021)RCCSRENKEI
 
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層智啓 出川
 
第1回 配信講義 計算科学技術特論A (2021)
第1回 配信講義 計算科学技術特論A (2021)第1回 配信講義 計算科学技術特論A (2021)
第1回 配信講義 計算科学技術特論A (2021)RCCSRENKEI
 
マルチコアを用いた画像処理
マルチコアを用いた画像処理マルチコアを用いた画像処理
マルチコアを用いた画像処理Norishige Fukushima
 
AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解MITSUNARI Shigeo
 
2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層
2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層
2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層智啓 出川
 
PyData.Tokyo Meetup #21 講演資料「Optuna ハイパーパラメータ最適化フレームワーク」太田 健
PyData.Tokyo Meetup #21 講演資料「Optuna ハイパーパラメータ最適化フレームワーク」太田 健PyData.Tokyo Meetup #21 講演資料「Optuna ハイパーパラメータ最適化フレームワーク」太田 健
PyData.Tokyo Meetup #21 講演資料「Optuna ハイパーパラメータ最適化フレームワーク」太田 健Preferred Networks
 
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」ManaMurakami1
 
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介Preferred Networks
 
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正前 typoあり)」
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正前 typoあり)」「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正前 typoあり)」
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正前 typoあり)」ManaMurakami1
 
AIチップ戦国時代における深層学習モデルの推論の最適化と実用的な運用を可能にするソフトウェア技術について
AIチップ戦国時代における深層学習モデルの推論の最適化と実用的な運用を可能にするソフトウェア技術についてAIチップ戦国時代における深層学習モデルの推論の最適化と実用的な運用を可能にするソフトウェア技術について
AIチップ戦国時代における深層学習モデルの推論の最適化と実用的な運用を可能にするソフトウェア技術についてFixstars Corporation
 
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編Fixstars Corporation
 
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみようPythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみようShinya Takamaeda-Y
 
計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミングNorishige Fukushima
 

What's hot (20)

FPGAを用いたEdge AIの現状
FPGAを用いたEdge AIの現状FPGAを用いたEdge AIの現状
FPGAを用いたEdge AIの現状
 
G2o
G2oG2o
G2o
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例
 
Deep Learningのための専用プロセッサ「MN-Core」の開発と活用(2022/10/19東大大学院「 融合情報学特別講義Ⅲ」)
Deep Learningのための専用プロセッサ「MN-Core」の開発と活用(2022/10/19東大大学院「 融合情報学特別講義Ⅲ」)Deep Learningのための専用プロセッサ「MN-Core」の開発と活用(2022/10/19東大大学院「 融合情報学特別講義Ⅲ」)
Deep Learningのための専用プロセッサ「MN-Core」の開発と活用(2022/10/19東大大学院「 融合情報学特別講義Ⅲ」)
 
第6回 配信講義 計算科学技術特論A(2021)
第6回 配信講義 計算科学技術特論A(2021)第6回 配信講義 計算科学技術特論A(2021)
第6回 配信講義 計算科学技術特論A(2021)
 
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
 
第1回 配信講義 計算科学技術特論A (2021)
第1回 配信講義 計算科学技術特論A (2021)第1回 配信講義 計算科学技術特論A (2021)
第1回 配信講義 計算科学技術特論A (2021)
 
マルチコアを用いた画像処理
マルチコアを用いた画像処理マルチコアを用いた画像処理
マルチコアを用いた画像処理
 
AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解
 
2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層
2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層
2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層
 
PyData.Tokyo Meetup #21 講演資料「Optuna ハイパーパラメータ最適化フレームワーク」太田 健
PyData.Tokyo Meetup #21 講演資料「Optuna ハイパーパラメータ最適化フレームワーク」太田 健PyData.Tokyo Meetup #21 講演資料「Optuna ハイパーパラメータ最適化フレームワーク」太田 健
PyData.Tokyo Meetup #21 講演資料「Optuna ハイパーパラメータ最適化フレームワーク」太田 健
 
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」
 
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
 
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正前 typoあり)」
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正前 typoあり)」「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正前 typoあり)」
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正前 typoあり)」
 
AIチップ戦国時代における深層学習モデルの推論の最適化と実用的な運用を可能にするソフトウェア技術について
AIチップ戦国時代における深層学習モデルの推論の最適化と実用的な運用を可能にするソフトウェア技術についてAIチップ戦国時代における深層学習モデルの推論の最適化と実用的な運用を可能にするソフトウェア技術について
AIチップ戦国時代における深層学習モデルの推論の最適化と実用的な運用を可能にするソフトウェア技術について
 
Glibc malloc internal
Glibc malloc internalGlibc malloc internal
Glibc malloc internal
 
CuPy解説
CuPy解説CuPy解説
CuPy解説
 
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
 
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみようPythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
 
計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング
 

Similar to Introduction to OpenCL (Japanese, OpenCLの基礎)

C base design methodology with s dx and xilinx ml
C base design methodology with s dx and xilinx ml C base design methodology with s dx and xilinx ml
C base design methodology with s dx and xilinx ml ssuser3a4b8c
 
OpenCLに触れてみよう
OpenCLに触れてみようOpenCLに触れてみよう
OpenCLに触れてみようYou&I
 
Python で munin plugin を書いてみる
Python で munin plugin を書いてみるPython で munin plugin を書いてみる
Python で munin plugin を書いてみるftnk
 
Javaで簡単にgpgpu aparapi
Javaで簡単にgpgpu aparapiJavaで簡単にgpgpu aparapi
Javaで簡単にgpgpu aparapiKen'ichi Sakiyama
 
PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門Yosuke Onoue
 
GPU-FPGA 協調計算を記述するためのプログラミング環境に関する研究(HPC169 No.10)
GPU-FPGA 協調計算を記述するためのプログラミング環境に関する研究(HPC169 No.10)GPU-FPGA 協調計算を記述するためのプログラミング環境に関する研究(HPC169 No.10)
GPU-FPGA 協調計算を記述するためのプログラミング環境に関する研究(HPC169 No.10)Ryuuta Tsunashima
 
コンピューティングとJava~なにわTECH道
コンピューティングとJava~なにわTECH道コンピューティングとJava~なにわTECH道
コンピューティングとJava~なにわTECH道なおき きしだ
 
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編Yosuke Onoue
 
PL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database AnalyticsPL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database AnalyticsKohei KaiGai
 
PEZY-SC programming overview
PEZY-SC programming overviewPEZY-SC programming overview
PEZY-SC programming overviewRyo Sakamoto
 
CMSI計算科学技術特論B(14) OpenACC・CUDAによるGPUコンピューティング
CMSI計算科学技術特論B(14) OpenACC・CUDAによるGPUコンピューティングCMSI計算科学技術特論B(14) OpenACC・CUDAによるGPUコンピューティング
CMSI計算科学技術特論B(14) OpenACC・CUDAによるGPUコンピューティングComputational Materials Science Initiative
 
20181212 - PGconf.ASIA - LT
20181212 - PGconf.ASIA - LT20181212 - PGconf.ASIA - LT
20181212 - PGconf.ASIA - LTKohei KaiGai
 
どこでも動くゲームを作るためのベタープラクティス
どこでも動くゲームを作るためのベタープラクティスどこでも動くゲームを作るためのベタープラクティス
どこでも動くゲームを作るためのベタープラクティス5mingame2
 
NetBSD6.X (i386)が2038年問題に対応、その余波
NetBSD6.X (i386)が2038年問題に対応、その余波NetBSD6.X (i386)が2038年問題に対応、その余波
NetBSD6.X (i386)が2038年問題に対応、その余波洋史 東平
 
130710 02
130710 02130710 02
130710 02openrtm
 
ClojureでElectronアプリを作ろう
ClojureでElectronアプリを作ろうClojureでElectronアプリを作ろう
ClojureでElectronアプリを作ろうKazuhiro Hara
 
2015年度GPGPU実践プログラミング 第3回 GPGPUプログラミング環境
2015年度GPGPU実践プログラミング 第3回 GPGPUプログラミング環境2015年度GPGPU実践プログラミング 第3回 GPGPUプログラミング環境
2015年度GPGPU実践プログラミング 第3回 GPGPUプログラミング環境智啓 出川
 

Similar to Introduction to OpenCL (Japanese, OpenCLの基礎) (20)

C base design methodology with s dx and xilinx ml
C base design methodology with s dx and xilinx ml C base design methodology with s dx and xilinx ml
C base design methodology with s dx and xilinx ml
 
OpenCLに触れてみよう
OpenCLに触れてみようOpenCLに触れてみよう
OpenCLに触れてみよう
 
Python で munin plugin を書いてみる
Python で munin plugin を書いてみるPython で munin plugin を書いてみる
Python で munin plugin を書いてみる
 
Javaで簡単にgpgpu aparapi
Javaで簡単にgpgpu aparapiJavaで簡単にgpgpu aparapi
Javaで簡単にgpgpu aparapi
 
PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門
 
GPU-FPGA 協調計算を記述するためのプログラミング環境に関する研究(HPC169 No.10)
GPU-FPGA 協調計算を記述するためのプログラミング環境に関する研究(HPC169 No.10)GPU-FPGA 協調計算を記述するためのプログラミング環境に関する研究(HPC169 No.10)
GPU-FPGA 協調計算を記述するためのプログラミング環境に関する研究(HPC169 No.10)
 
PCL
PCLPCL
PCL
 
コンピューティングとJava~なにわTECH道
コンピューティングとJava~なにわTECH道コンピューティングとJava~なにわTECH道
コンピューティングとJava~なにわTECH道
 
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
 
PL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database AnalyticsPL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database Analytics
 
PEZY-SC programming overview
PEZY-SC programming overviewPEZY-SC programming overview
PEZY-SC programming overview
 
CMSI計算科学技術特論B(14) OpenACC・CUDAによるGPUコンピューティング
CMSI計算科学技術特論B(14) OpenACC・CUDAによるGPUコンピューティングCMSI計算科学技術特論B(14) OpenACC・CUDAによるGPUコンピューティング
CMSI計算科学技術特論B(14) OpenACC・CUDAによるGPUコンピューティング
 
20181212 - PGconf.ASIA - LT
20181212 - PGconf.ASIA - LT20181212 - PGconf.ASIA - LT
20181212 - PGconf.ASIA - LT
 
どこでも動くゲームを作るためのベタープラクティス
どこでも動くゲームを作るためのベタープラクティスどこでも動くゲームを作るためのベタープラクティス
どこでも動くゲームを作るためのベタープラクティス
 
N3495 inplace realloc
N3495 inplace reallocN3495 inplace realloc
N3495 inplace realloc
 
NetBSD6.X (i386)が2038年問題に対応、その余波
NetBSD6.X (i386)が2038年問題に対応、その余波NetBSD6.X (i386)が2038年問題に対応、その余波
NetBSD6.X (i386)が2038年問題に対応、その余波
 
VerilatorとSystemC
VerilatorとSystemCVerilatorとSystemC
VerilatorとSystemC
 
130710 02
130710 02130710 02
130710 02
 
ClojureでElectronアプリを作ろう
ClojureでElectronアプリを作ろうClojureでElectronアプリを作ろう
ClojureでElectronアプリを作ろう
 
2015年度GPGPU実践プログラミング 第3回 GPGPUプログラミング環境
2015年度GPGPU実践プログラミング 第3回 GPGPUプログラミング環境2015年度GPGPU実践プログラミング 第3回 GPGPUプログラミング環境
2015年度GPGPU実践プログラミング 第3回 GPGPUプログラミング環境
 

More from Takahiro Harada

201907 Radeon ProRender2.0@Siggraph2019
201907 Radeon ProRender2.0@Siggraph2019201907 Radeon ProRender2.0@Siggraph2019
201907 Radeon ProRender2.0@Siggraph2019Takahiro Harada
 
[2018 GDC] Real-Time Ray-Tracing Techniques for Integration into Existing Ren...
[2018 GDC] Real-Time Ray-Tracing Techniques for Integration into Existing Ren...[2018 GDC] Real-Time Ray-Tracing Techniques for Integration into Existing Ren...
[2018 GDC] Real-Time Ray-Tracing Techniques for Integration into Existing Ren...Takahiro Harada
 
[2017 GDC] Radeon ProRender and Radeon Rays in a Gaming Rendering Workflow
[2017 GDC] Radeon ProRender and Radeon Rays in a Gaming Rendering Workflow[2017 GDC] Radeon ProRender and Radeon Rays in a Gaming Rendering Workflow
[2017 GDC] Radeon ProRender and Radeon Rays in a Gaming Rendering WorkflowTakahiro Harada
 
確率的ライトカリング 理論と実装 (CEDEC2016)
確率的ライトカリング 理論と実装 (CEDEC2016)確率的ライトカリング 理論と実装 (CEDEC2016)
確率的ライトカリング 理論と実装 (CEDEC2016)Takahiro Harada
 
Introducing Firerender for 3DS Max
Introducing Firerender for 3DS MaxIntroducing Firerender for 3DS Max
Introducing Firerender for 3DS MaxTakahiro Harada
 
[2016 GDC] Multiplatform GPU Ray-Tracing Solutions With FireRender and FireRays
[2016 GDC] Multiplatform GPU Ray-Tracing Solutions With FireRender and FireRays[2016 GDC] Multiplatform GPU Ray-Tracing Solutions With FireRender and FireRays
[2016 GDC] Multiplatform GPU Ray-Tracing Solutions With FireRender and FireRaysTakahiro Harada
 
Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...
Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...
Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...Takahiro Harada
 
Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...
Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...
Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...Takahiro Harada
 
Foveated Ray Tracing for VR on Multiple GPUs
Foveated Ray Tracing for VR on Multiple GPUsFoveated Ray Tracing for VR on Multiple GPUs
Foveated Ray Tracing for VR on Multiple GPUsTakahiro Harada
 
Introduction to Monte Carlo Ray Tracing, OpenCL Implementation (CEDEC 2014)
Introduction to Monte Carlo Ray Tracing, OpenCL Implementation (CEDEC 2014)Introduction to Monte Carlo Ray Tracing, OpenCL Implementation (CEDEC 2014)
Introduction to Monte Carlo Ray Tracing, OpenCL Implementation (CEDEC 2014)Takahiro Harada
 
Physics Tutorial, GPU Physics (GDC2010)
Physics Tutorial, GPU Physics (GDC2010)Physics Tutorial, GPU Physics (GDC2010)
Physics Tutorial, GPU Physics (GDC2010)Takahiro Harada
 
A 2.5D Culling for Forward+ (SIGGRAPH ASIA 2012)
A 2.5D Culling for Forward+ (SIGGRAPH ASIA 2012)A 2.5D Culling for Forward+ (SIGGRAPH ASIA 2012)
A 2.5D Culling for Forward+ (SIGGRAPH ASIA 2012)Takahiro Harada
 
Using GPUs for Collision detection, Recent Advances in Real-Time Collision an...
Using GPUs for Collision detection, Recent Advances in Real-Time Collision an...Using GPUs for Collision detection, Recent Advances in Real-Time Collision an...
Using GPUs for Collision detection, Recent Advances in Real-Time Collision an...Takahiro Harada
 
Heterogeneous Particle based Simulation (SIGGRAPH ASIA 2011)
Heterogeneous Particle based Simulation (SIGGRAPH ASIA 2011)Heterogeneous Particle based Simulation (SIGGRAPH ASIA 2011)
Heterogeneous Particle based Simulation (SIGGRAPH ASIA 2011)Takahiro Harada
 
A Parallel Constraint Solver for a Rigid Body Simulation (SIGGRAPH ASIA 2011)
A Parallel Constraint Solver for a Rigid Body Simulation (SIGGRAPH ASIA 2011)A Parallel Constraint Solver for a Rigid Body Simulation (SIGGRAPH ASIA 2011)
A Parallel Constraint Solver for a Rigid Body Simulation (SIGGRAPH ASIA 2011)Takahiro Harada
 
Introduction to Monte Carlo Ray Tracing (CEDEC 2013)
Introduction to Monte Carlo Ray Tracing (CEDEC 2013)Introduction to Monte Carlo Ray Tracing (CEDEC 2013)
Introduction to Monte Carlo Ray Tracing (CEDEC 2013)Takahiro Harada
 
Forward+ (EUROGRAPHICS 2012)
Forward+ (EUROGRAPHICS 2012)Forward+ (EUROGRAPHICS 2012)
Forward+ (EUROGRAPHICS 2012)Takahiro Harada
 

More from Takahiro Harada (17)

201907 Radeon ProRender2.0@Siggraph2019
201907 Radeon ProRender2.0@Siggraph2019201907 Radeon ProRender2.0@Siggraph2019
201907 Radeon ProRender2.0@Siggraph2019
 
[2018 GDC] Real-Time Ray-Tracing Techniques for Integration into Existing Ren...
[2018 GDC] Real-Time Ray-Tracing Techniques for Integration into Existing Ren...[2018 GDC] Real-Time Ray-Tracing Techniques for Integration into Existing Ren...
[2018 GDC] Real-Time Ray-Tracing Techniques for Integration into Existing Ren...
 
[2017 GDC] Radeon ProRender and Radeon Rays in a Gaming Rendering Workflow
[2017 GDC] Radeon ProRender and Radeon Rays in a Gaming Rendering Workflow[2017 GDC] Radeon ProRender and Radeon Rays in a Gaming Rendering Workflow
[2017 GDC] Radeon ProRender and Radeon Rays in a Gaming Rendering Workflow
 
確率的ライトカリング 理論と実装 (CEDEC2016)
確率的ライトカリング 理論と実装 (CEDEC2016)確率的ライトカリング 理論と実装 (CEDEC2016)
確率的ライトカリング 理論と実装 (CEDEC2016)
 
Introducing Firerender for 3DS Max
Introducing Firerender for 3DS MaxIntroducing Firerender for 3DS Max
Introducing Firerender for 3DS Max
 
[2016 GDC] Multiplatform GPU Ray-Tracing Solutions With FireRender and FireRays
[2016 GDC] Multiplatform GPU Ray-Tracing Solutions With FireRender and FireRays[2016 GDC] Multiplatform GPU Ray-Tracing Solutions With FireRender and FireRays
[2016 GDC] Multiplatform GPU Ray-Tracing Solutions With FireRender and FireRays
 
Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...
Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...
Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...
 
Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...
Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...
Introduction to Bidirectional Path Tracing (BDPT) & Implementation using Open...
 
Foveated Ray Tracing for VR on Multiple GPUs
Foveated Ray Tracing for VR on Multiple GPUsFoveated Ray Tracing for VR on Multiple GPUs
Foveated Ray Tracing for VR on Multiple GPUs
 
Introduction to Monte Carlo Ray Tracing, OpenCL Implementation (CEDEC 2014)
Introduction to Monte Carlo Ray Tracing, OpenCL Implementation (CEDEC 2014)Introduction to Monte Carlo Ray Tracing, OpenCL Implementation (CEDEC 2014)
Introduction to Monte Carlo Ray Tracing, OpenCL Implementation (CEDEC 2014)
 
Physics Tutorial, GPU Physics (GDC2010)
Physics Tutorial, GPU Physics (GDC2010)Physics Tutorial, GPU Physics (GDC2010)
Physics Tutorial, GPU Physics (GDC2010)
 
A 2.5D Culling for Forward+ (SIGGRAPH ASIA 2012)
A 2.5D Culling for Forward+ (SIGGRAPH ASIA 2012)A 2.5D Culling for Forward+ (SIGGRAPH ASIA 2012)
A 2.5D Culling for Forward+ (SIGGRAPH ASIA 2012)
 
Using GPUs for Collision detection, Recent Advances in Real-Time Collision an...
Using GPUs for Collision detection, Recent Advances in Real-Time Collision an...Using GPUs for Collision detection, Recent Advances in Real-Time Collision an...
Using GPUs for Collision detection, Recent Advances in Real-Time Collision an...
 
Heterogeneous Particle based Simulation (SIGGRAPH ASIA 2011)
Heterogeneous Particle based Simulation (SIGGRAPH ASIA 2011)Heterogeneous Particle based Simulation (SIGGRAPH ASIA 2011)
Heterogeneous Particle based Simulation (SIGGRAPH ASIA 2011)
 
A Parallel Constraint Solver for a Rigid Body Simulation (SIGGRAPH ASIA 2011)
A Parallel Constraint Solver for a Rigid Body Simulation (SIGGRAPH ASIA 2011)A Parallel Constraint Solver for a Rigid Body Simulation (SIGGRAPH ASIA 2011)
A Parallel Constraint Solver for a Rigid Body Simulation (SIGGRAPH ASIA 2011)
 
Introduction to Monte Carlo Ray Tracing (CEDEC 2013)
Introduction to Monte Carlo Ray Tracing (CEDEC 2013)Introduction to Monte Carlo Ray Tracing (CEDEC 2013)
Introduction to Monte Carlo Ray Tracing (CEDEC 2013)
 
Forward+ (EUROGRAPHICS 2012)
Forward+ (EUROGRAPHICS 2012)Forward+ (EUROGRAPHICS 2012)
Forward+ (EUROGRAPHICS 2012)
 

Recently uploaded

情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法ssuser370dd7
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor arts yokohama
 
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~arts yokohama
 
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見Shumpei Kishi
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)ssuser539845
 
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfMatsushita Laboratory
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-LoopへTetsuya Nihonmatsu
 
20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdfAyachika Kitazaki
 

Recently uploaded (11)

情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor
 
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
 
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
 
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
 
2024 04 minnanoito
2024 04 minnanoito2024 04 minnanoito
2024 04 minnanoito
 
What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?
 
20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf
 
2024 03 CTEA
2024 03 CTEA2024 03 CTEA
2024 03 CTEA
 

Introduction to OpenCL (Japanese, OpenCLの基礎)

  • 2. 2INTRODUCTION TO OPENCL | JUNE, 2013 AGENDA } Introduction –  GPU Architecture } OpenCL Example –  Vector Add –  Reduction } Performance Tips } APU Specific Optimization
  • 4. 4INTRODUCTION TO OPENCL | JUNE, 2013 GPUの活用 } グラフィックスのタスク用のプロセッサ } 並列度の高い汎用計算にも向いている } CPUとは異なる設計 –  CPU:逐次処理 –  GPU:並列処理 } プログラミング言語 –  OpenGL, GLSL •  ラスターグラフィックスのAPI •  汎用計算用ではない –  グラフィックスAPIをハックしなければならない •  クロスプラットフォーム –  DirectX, HLSL •  ラスターグラフィックスAPI •  汎用計算にはDirect Compute (DX11) •  DirectX11をサポートしたプラットフォームが必要 (Windows 7) •  Windows OSのみ –  OpenCL CPU GPU work work work work work work work work work work work work
  • 5. 5INTRODUCTION TO OPENCL | JUNE, 2013 OPENCL } GPUを含めた並列プロセッサ用のOpen Compute Language (OpenCL) } OpenCL 1.0の仕様は 2008年にリリース } 現在はv1.2 } 言語はISO C99に拡張と制約を加えたもの } ソフトウェアのポータビリティ –  クロスプラットフォームのサポート •  Windows, Mac, Linux –  マルチデバイスのサポート •  GPU –  AMD, NVIDIA, Intel •  CPU •  etc –  一度書けばサポートされているデバイス上ならどこでも実行可能
  • 7. 7INTRODUCTION TO OPENCL | JUNE, 2013 演算ユニット } AMD Radeon HD 7970 (GCNアーキテクチャ) –  3.8 TFLOPS (S) –  974 GFLOPS (D) –  264 GB/s } 高い演算能力 –  演算を並列で行うため –  128 SIMDエンジン (コア) •  64 wide SIMD SIMDs (Cores) SIMD width Radeon HD 7970 (GPU) 128 64 FX 8350 (CPU) 8 8 (AVX) AMD Radeon HD 7970
  • 8. 8INTRODUCTION TO OPENCL | JUNE, 2013 メモリ } CPU –  レジスタ –  キャッシュ –  メモリ (Host memory) } GPU –  レジスタ –  キャッシュ –  ローカルメモリ (Local Data Share) –  メモリ (Global memory) Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg L1 Cache Local Data Share L2 Cache Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg L1 Cache Local Data Share Device (Global) Memory Reg Reg Reg Reg L1 Cache Reg Reg Reg Reg L1 Cache Reg Reg Reg Reg L1 Cache Reg Reg Reg Reg L1 Cache L2 Cache Host Memory PCIe x128
  • 9. 9INTRODUCTION TO OPENCL | JUNE, 2013 GPUプログラムの実行 } GPUはホストのメモリに直接アクセスできない –  デバイスメモリのみアクセス可能 } GPUでの計算手順 –  データをPCIeバスを通してデバイスメモリに移動 –  GPUでの演算 –  結果をホストメモリに読み戻し Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg L1 Cache Local Data Share L2 Cache Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg L1 Cache Local Data Share Device (Global) Memory Reg Reg Reg Reg L1 Cache Reg Reg Reg Reg L1 Cache Reg Reg Reg Reg L1 Cache Reg Reg Reg Reg L1 Cache L2 Cache Host Memory PCIe x128
  • 10. 10INTRODUCTION TO OPENCL | JUNE, 2013 OPENCLのアプリケーションの例 } 物理シミュレーション –  流体シミュレーション –  剛体シミュレーション } グラフィックス –  ポストプロセス –  レイトレーシング
  • 12. 12INTRODUCTION TO OPENCL | JUNE, 2013 CPU VECTOR ADD } CPUコードは簡単 float* a = new float[n]; float* b = new float[n]; float* c = new float[n]; for(int i=0; i<n; i++) { b[i] = i; c[i] = n; } for(int i=0; i<n; i++) { a[i] = b[i] + c[i]; } delete [] a; delete [] b; delete [] c; Memory allocation Initialization Computation Memory deallocation
  • 13. 13INTRODUCTION TO OPENCL | JUNE, 2013 OPENCL上で実装するために } 3つのことを行わなければならない 1.  OpenCLメモリの確保、解放 (アロケーション、デアロケーション) 2.  計算ロジックをOpenCLカーネルとして実装 3.  OpenCLカーネルをOpenCL APIを用いて実行
  • 14. 14INTRODUCTION TO OPENCL | JUNE, 2013 メモリのアロケーション、デアロケーション } CPU –  アロケーション –  デアロケーション } OpenCL –  アロケーション –  デアロケーション float* a = new float[n]; delete [] a; cl_mem a = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e ); clReleaseMemObject( a ); Memory size in byte
  • 15. 15INTRODUCTION TO OPENCL | JUNE, 2013 計算ロジックのOPENCLカーネルへの実装 } CPU –  n個の演算が逐次的に行われる } OpenCL –  n個の演算が並列で行われる –  ワークアイテムが一要素の計算を行う •  ワークアイテム(WI) == 演算の単位 –  それぞれの要素の処理の関数をOpenCLカーネルとして書く –  ホストのCコードの中ではなく別ファイル(.cl)に for(int i=0; i<n; i++) { a[i] = b[i] + c[i]; } __kernel void addKernel( __global float* a, __global float* b, __global float* c ) { int i = get_global_id(0); a[i] = b[i] + c[i]; } __global : for a memory allocated in global memory __local : for a memory allocated in local memory 計算のパターンが完全に並列ならばコードをそのまま 使うことができる
  • 16. 16INTRODUCTION TO OPENCL | JUNE, 2013 OPENCLカーネルのOPENCL APIを用いた実行 } OpenCLのメモリを引数にセットする –  引数の番号をそれぞれ指定する } カーネルの実行 clSetKernelArg(kernel1, 0, sizeof(cl_mem), (void*)&a); clSetKernelArg(kernel1, 1, sizeof(cl_mem), (void*)&b); clSetKernelArg(kernel1, 2, sizeof(cl_mem), (void*)&c); clEnqueueNDRangeKernel( queue, kernel1, 1, 0, gSize, lSize, 0, 0, 0 ); __kernel void addKernel( __global float* a, __global float* b, __global float* c ) { int i = get_global_id(0); a[i] = b[i] + c[i]; } Order of an argument Work group size [64, 1, 1] Global work size [n,1,1]
  • 17. 17INTRODUCTION TO OPENCL | JUNE, 2013 OPENCLでのVECTOR ADD __kernel void initKernel( __global float* b, __global float* c ) { int i = get_global_id(0); b[i] = i; c[i] = n; } __kernel void addKernel( __global float* a, __global float* b, __global float* c ) { int i = get_global_id(0); a[i] = b[i] + c[i]; } cl_mem a = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e ); cl_mem b = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e ); cl_mem c = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e ); clSetKernelArg(kernel0, 0, sizeof(cl_mem), (void*)&b); clSetKernelArg(kernel0, 1, sizeof(cl_mem), (void*)&c); clEnqueueNDRangeKernel( queue, kernel0, 1, 0, gSize, lSize, 0, 0, 0 ); clSetKernelArg(kernel1, 0, sizeof(cl_mem), (void*)&a); clSetKernelArg(kernel1, 1, sizeof(cl_mem), (void*)&b); clSetKernelArg(kernel1, 2, sizeof(cl_mem), (void*)&c); clEnqueueNDRangeKernel( queue, kernel1, 1, 0, gSize, lSize, 0, 0, 0 ); clReleaseMemObject( a ); clReleaseMemObject( b ); clReleaseMemObject( c ); Memory allocation Initialization Computation Memory deallocation
  • 18. 18INTRODUCTION TO OPENCL | JUNE, 2013 コードの比較 CPU OpenCL float* a = new float[n]; float* b = new float[n]; float* c = new float[n]; for(int i=0; i<n; i++) { b[i] = i; c[i] = n; } for(int i=0; i<n; i++) { a[i] = b[i] + c[i]; } delete [] a; delete [] b; delete [] c; cl_mem a = clCreateBuffer( context, CL_MEM_READ_WRITE, siz cl_mem b = clCreateBuffer( context, CL_MEM_READ_WRITE, siz cl_mem c = clCreateBuffer( context, CL_MEM_READ_WRITE, siz clSetKernelArg(kernel0, 0, sizeof(cl_mem), (void*)&b); clSetKernelArg(kernel0, 1, sizeof(cl_mem), (void*)&c); clEnqueueNDRangeKernel( queue, kernel0, 1, 0, gSize, lSize clSetKernelArg(kernel1, 0, sizeof(cl_mem), (void*)&a); clSetKernelArg(kernel1, 1, sizeof(cl_mem), (void*)&b); clSetKernelArg(kernel1, 2, sizeof(cl_mem), (void*)&c); clEnqueueNDRangeKernel( queue, kernel1, 1, 0, gSize, lSize clReleaseMemObject( a ); clReleaseMemObject( b ); clReleaseMemObject( c ); Memory allocation Initialization Computation Memory deallocation
  • 19. 19INTRODUCTION TO OPENCL | JUNE, 2013 OPENCL上で実装するために } 3つのことを行わなければならない 1.  OpenCLメモリの確保、解放 (アロケーション、デアロケーション) 2.  計算ロジックをOpenCLカーネルとして実装 3.  OpenCLカーネルをOpenCL APIを用いて実行 } 本当はもう少し必要 1.  OpenCLの初期化と解放 (Context, queue, device ID) 2.  OpenCLカーネルのコンパイル 3.  OpenCLメモリへのデータのコピー cl_mem a = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e ); clEnqueueNDRangeKernel( queue, kernel0, 1, 0, gSize, lSize, 0, 0, 0 );
  • 20. 20INTRODUCTION TO OPENCL | JUNE, 2013 OPENCLの初期化と解放 } OpenCLコンテクスト、キュー、デバイスIDの生成 } OpenCLコンテクスト、キューの解放 clReleaseCommandQueue( queue ); clReleaseContext( context ); cl_context context; cl_command_queue queue; cl_device_id device; cl_platform_id platform; cl_uint nPlatforms; clGetPlatformIDs( 0, 0, &nPlatforms ); clGetPlatformIDs( 1, &platform, 0 ); clGetDeviceIDs( platform, CL_DEVICE_TYPE_GPU, 1, &device, 0 ); context = clCreateContext( 0, 1, &device, 0, 0, &e ); queue = clCreateCommandQueue( context, device, 0, &e );
  • 21. 21INTRODUCTION TO OPENCL | JUNE, 2013 OPENCLカーネルのコンパイル } OpenCLカーネルをchar配列として読み込み (s_kernel) –  プログラムの生成 (Create Program) –  ビルド (Build Program) –  カーネルの生成 (Create Kernel) cl_kernel kernel1;! cl_program program = clCreateProgramWithSource( context, 1, &s_kernel, &length, &e );! clBuildProgram( program, 1, &device, 0, 0, 0 );! kernel1 = clCreateKernel( program, "addKernel", &e );
  • 22. 22INTRODUCTION TO OPENCL | JUNE, 2013 OPENCLのメモリへのアクセス } 直接アクセスすることはできない } 明示的なコピーが必要 } Map, Unmap float* host = new float[n]; cl_mem device = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e ); clEnqueueWriteBuffer( queue, device, CL_FALSE, 0, sizeof(float)*n, host, 0, 0, 0 ); clFinish( queue ); clEnqueueReadBuffer( queue, device, CL_FALSE, 0, sizeof(float)*n, host, 0, 0, 0 ); clFinish( queue ); delete [] host; clReleaseMemObject( device ); clEnqueueMapBuffer(), clEnqueueUnmapMemObject()
  • 23. 23INTRODUCTION TO OPENCL | JUNE, 2013 ホストコード // memory allocation and execution cl_mem a = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e ); cl_mem b = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e ); cl_mem c = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float)*n, 0, &e ); clSetKernelArg(kernel0, 0, sizeof(cl_mem), (void*)&b); clSetKernelArg(kernel0, 1, sizeof(cl_mem), (void*)&c); clEnqueueNDRangeKernel( queue, kernel0, 1, 0, gSize, lSize, 0, 0, 0 ); clSetKernelArg(kernel1, 0, sizeof(cl_mem), (void*)&a); clSetKernelArg(kernel1, 1, sizeof(cl_mem), (void*)&b); clSetKernelArg(kernel1, 2, sizeof(cl_mem), (void*)&c); clEnqueueNDRangeKernel( queue, kernel1, 1, 0, gSize, lSize, 0, 0, 0 ); clReleaseMemObject( a ); clReleaseMemObject( b ); clReleaseMemObject( c ); // initialization cl_context context; cl_command_queue queue; cl_device_id device; cl_platform_id platform; cl_uint nPlatforms; clGetPlatformIDs( 0, 0, &nPlatforms ); clGetPlatformIDs( 1, &platform, 0 ); clGetDeviceIDs( platform, CL_DEVICE_TYPE_GPU, 1, &device, 0 ); context = clCreateContext( 0, 1, &device, 0, 0, &e ); queue = clCreateCommandQueue( context, device, 0, &e ); // kernel creation cl_program program = clCreateProgramWithSource( context, 1, (const char **)&s_kernel0, &kernelLength0, &e ); clBuildProgram( program, 1, &device, 0, 0, 0 ); cl_kernel kernel0 = clCreateKernel(program, ”initKernel", &e); cl_program program1 = clCreateProgramWithSource( context, 1, (const char **)&s_kernel1, &kernelLength1, &e ); clBuildProgram( program1, 1, &device, 0, 0, 0 ); cl_kernel kernel1 = clCreateKernel(program1, "addKernel", &e); // release clReleaseKernel( kernel0 ); clReleaseKernel( kernel1 ); clReleaseCommandQueue( queue ); clReleaseContext( context );
  • 24. 24INTRODUCTION TO OPENCL | JUNE, 2013 TIPS } OpenCLの実行は非同期 –  clEnqueueReadBuffer()が呼ばれても、メモリがホストメモリにコピーされるとは限らない •  コマンドをDevice(GPU)に送るだけ –  clEnqueueNDRangeKernel()もDeviceにコマンドを送るだけ –  確実に実行するためにはclFinish()を使う •  DeviceプログラムとHostプログラムの同期 •  それまでに発行されたコマンドが実行されるのを待つ } APIの実行のエラーのステータスの確認 –  CL_SUCCESSならばOK –  それ以外ならば何かが正しくない •  引数の確認 } OpenCL printf –  デバッグに有用 –  パフォーマンスに影響 –  #pragma OPENCL EXTENSION cl_amd_printf : enable
  • 25. 25INTRODUCTION TO OPENCL | JUNE, 2013 OPENCL C言語拡張(OPENCLカーネル内) } ベクタータイプ –  float4 (x,y,z,w) –  int4 (x,y,z,w) } ワークアイテム、ワークグループの情報を取り出す関数 –  get_global_id() –  get_local_id() } 同期 –  barrier() } メモリ空間の指定 –  __kernel •  ホストから呼び出すことができるカーネル関数 –  __global •  グローバルメモリ –  __local •  ローカルメモリ __kernel void add4Kernel( __global float4* a, __global float4* b, __global float4* c ) { int i = get_global_id(0); a[i] = b[i] + c[i]; }
  • 27. 27INTRODUCTION TO OPENCL | JUNE, 2013 ワークアイテム } 計算の単位 } カーネルを一度実行 } Vector Addではカーネルをn回実行した –  n個のワークアイテムを実行 –  どのように実行?
  • 28. 28INTRODUCTION TO OPENCL | JUNE, 2013 実行の次元 (WORK DIMENSIONS) } 処理データの次元にあわせるのが一般的 } 1, 2, 3次元 2 dimensional execution 二次元配列の処理(画像) clEnqueueNDRangeKernel( q, k, 1, 0, [n,1,1], l, 0, 0, 0 ); 1 dimensional execution 一次元配列の処理 for(int i=0; i<n; i++) { a[i] = b[i] + c[i]; } for(int i=0; i<n; i++) for(int j=0; j<n; j++) { a[i][j] = b[i][j] + c[i][j]; } n n n clEnqueueNDRangeKernel( q, k, 2, 0, [n,n,1], l, 0, 0, 0 );
  • 29. 29INTRODUCTION TO OPENCL | JUNE, 2013 ワークグループ Work dim: 2 Global dim: 32x32 Local dim : 16x16 Using 4 SIMDs clEnqueueNDRangeKernel( q, k, 2, 0, [32,32,1], [16,16,1], 0, 0, 0 ); (0,0) (1,0) (2,0) (3,0) (0,1) (0,2) (0,3) Work dim: 2 Global dim: 32x32 Local dim : 8x8 Using 16 SIMDs clEnqueueNDRangeKernel( q, k, 2, 0, [32,32,1], [8,8,1], 0, 0, 0 ); (0,0) (1,0) (0,1) (1,1) get_group_id(0) == 2 get_group_id(1) == 0
  • 30. 30INTRODUCTION TO OPENCL | JUNE, 2013 ワークアイテムの識別 (0,0) (1,0) (2,0) (3,0) (0,1) (0,2) (0,3) get_local_id(0) == 5 get_local_id(1) == 2 get_global_id(0) == 8x2+5 get_global_id(1) == 8x0+2 Work dim: 2 Global dim: 32x32 clEnqueueNDRangeKernel( q, k, 2, 0, [32,32,1], [8,8,1], 0, 0, 0 ); Local dim: 8x8 Workgroup id: (2,0) __kernel void addKernel( __global float* a, __global float* b, __global float* c ) { int i = get_global_id(0); a[i] = b[i] + c[i]; }
  • 31. 31INTRODUCTION TO OPENCL | JUNE, 2013 まとめ (0,0) (1,0) (2,0) (3,0) (0,1) (0,2) (0,3) Work dimensions clEnqueueNDRangeKernel( q, k, 2, 0, [32,32,1], [8,8,1], 0, 0, 0 ); Global dimensions Local dimensions
  • 33. 33INTRODUCTION TO OPENCL | JUNE, 2013 REDUCTION (MAX) } 最大値を探す } Vector Addの例のような単純な並列処理ではない } 全ての要素をチェック } この例で学ぶのは –  OpenCLの拡張機能の使用 –  ワークグループの概念 –  LDS Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg L1 Cache Local Data Share L2 Cache Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg L1 Cache Local Data Share Device (Global) Memory x128
  • 34. 34INTRODUCTION TO OPENCL | JUNE, 2013 REDUCTION (MAX) CPU } maxValueと順番に比較していく OpenCL } メモリ書き込みの競合が起こる int* a = new int[n]; // initialize a[] float maxValue = 0; for(int i=0; i<n; i++) { maxValue = max( maxValue, a[i] ); } delete [] a; __kernel void reductionKernel( __global int* a, __global int* maxValue ) { int i = get_global_id(0); maxValue[0] = max( maxValue[0], a[i] ); }
  • 35. 35INTRODUCTION TO OPENCL | JUNE, 2013 REDUCTION (MAX) CPU } maxValueと順番に比較していく OpenCL } アトミックオペレーションを用いることで並列化可能 } アトミクスは拡張機能なので有効化する必要あり int* a = new int[n]; // initialize a[] float maxValue = 0; for(int i=0; i<n; i++) { maxValue = max( maxValue, a[i] ); } delete [] a; #pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable __kernel void reductionKernel( __global int* a, __global int* maxValue ) { int i = get_global_id(0); atomic_max( &maxValue[0], a[i] ); }
  • 36. 36INTRODUCTION TO OPENCL | JUNE, 2013 この実装の問題点 } 全てのワークアイテムがアトミックオペレーションを同じメモリに対して行う –  メモリ処理が逐次化される可能性もある –  GPUのパフォーマンスを引き出せない } 解決法 –  ワークグループを活用 a[N] maxValue
  • 37. 37INTRODUCTION TO OPENCL | JUNE, 2013 ワークグループ } ワークグループは複数のワークアイテムをまとめたもの } 一つのワークグループは一つのSIMDエンジンが実行 –  SIMDエンジンはLDSを持つ } ローカルデータシェア (LDS) –  レジスタはそれぞれのワークアイテムのみがアクセスできるメモリ –  LDSはワークグループ内のワークアイテムが共有できるもの –  LDSにアクセスするレイテンシ < グローバルメモリにアクセスするレイテンシ } ワークグループ内のワークアイテムは同期可能 Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg L1 Cache Local Data Share L2 Cache Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg Reg L1 Cache Local Data Share Device (Global) Memory x128
  • 38. 38INTRODUCTION TO OPENCL | JUNE, 2013 演算の可視化 } 二段階のreduction –  20ローカルアトミクス –  4グローバルアトミクス } 単純な実装 –  20グローバルアトミクス Work Group0 Work Group1 Work Group2 Work Group3 Global max Local max
  • 39. 39INTRODUCTION TO OPENCL | JUNE, 2013 二段階のREDUCTION KERNEL #pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable #pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable __kernel void reduction2levelKernel( __global int* a, __global int* maxValue ) { __local int localMax; int i = get_global_id(0); if( get_local_id(0) == 0 ) localMax = 0; barrier(CLK_LOCAL_MEM_FENCE); atomic_max( &localMax, a[i] ); barrier(CLK_LOCAL_MEM_FENCE); if( get_local_id(0) == 0 ) atomic_max( &maxValue[0], localMax ); } Enable Extensions Initialize local max Synchronization Local reduction Synchronization Global reduction
  • 41. 41INTRODUCTION TO OPENCL | JUNE, 2013 GPUの全てを使い切る } GPUのハイパフォーマンスはその並列アーキテクチャに起因する } 可能な限り多くの演算ユニットを使用する方が良い –  逐次コードを実行するとストリームプロセッサ一個しか使わない –  全体の1/(32*4*64) == 0.012%
  • 42. 42INTRODUCTION TO OPENCL | JUNE, 2013 ワークグループの大きさ : ウェーブフロントの大きさ } ワークグループはSIMDエンジンによって実行される } AMD GPUのSIMDエンジンは64個のワークアイテムを並列に処理 –  並列処理の単位 == ウェーブフロント } ワークグループの大きさ (ワークアイテムの数) == 64の倍数が良い
  • 43. 43INTRODUCTION TO OPENCL | JUNE, 2013 ワークグループの大きさ : ウェーブフロントの大きさ } X ワークグループサイズ == 1ワークアイテム –  SIMDエンジンが 1サイクルで処理 –  SIMDエンジンの大半は処理待ち (63 idles, 1active) } X ワークグループサイズ == 32ワークアイテム –  SIMDエンジンが 1サイクルで処理 –  SIMDエンジンの半分は処理待ち } O ワークグループサイズ == 128ワークアイテム –  SIMDエンジンが 2サイクルで処理 –  両方のサイクルとも処理待ちなし
  • 44. 44INTRODUCTION TO OPENCL | JUNE, 2013 メモリーコピーを避ける } グローバルメモリへのアクセスは遅い –  レイテンシが高い (待ち時間が多い) } 不要なデータは読まない } メモリの広範囲なランダムアクセスを避ける –  キャッシュが効果的ではなくなる } 可能であればLDSを使う –  LDSはユーザが管理できるキャッシュのようなもの –  使用する前にLDSに読み込む –  LDS内のランダムアクセスはグローバルメモリのアクセスに比べれば十分小さい
  • 45. 45INTRODUCTION TO OPENCL | JUNE, 2013 ローカルリソースの使用を控える } ローカルリソースの量には限界がある –  レジスタ –  LDS } あふれたレジスタはグローバルメモリに配置 –  Scratch Registersと呼ばれる –  それらへのアクセスはとても遅い –  GPUは実行することはできるので注意 } ローカルリソースの使用量はツールを使って確認可能 –  APP kernel analyzer –  Code XL } Southern Island GPU –  256 vector registers/WI
  • 46. 46INTRODUCTION TO OPENCL | JUNE, 2013 ホスト、デバイス間の同期を最小限にする } ホスト(CPU)とデバイス(GPU)の同期はGPUの実行パイプをストールさせる –  カーネルの実行の終了を待つ –  メモリコピーして値を読み出す } GPUは処理待ち } 出来るだけ多くのコマンドをキューに積む } GPUメモリの値を読み出さない } 同期を遅らせる } Code XLを使ってGPUの活動を可視化できる
  • 48. 48INTRODUCTION TO OPENCL | JUNE, 2013 APUのメモリ } GPUとCPUは物理的に同じメモリを使用している –  メモリアドレス空間は異なる } PCIeバスを通るデータ転送はない } データコピーは不要なはず } Zero Copy Memory –  明示的な宣言が必要 CPU + Discrete GPU APU (CPU + Integrated GPU)
  • 49. 49INTRODUCTION TO OPENCL | JUNE, 2013 ゼロコピーバッファ } ゼロコピーバッファのアロケーション } データへのアクセス –  APIコールの裏にはデータコピーがない –  ホストメモリのアドレスを返すだけ –  普通のバッファのマップはデータ転送を伴う cl_mem buffer = clCreateBuffer( context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, bufferSize, 0, &status ); void* ptr = clEnqueueMapBuffer(commandQueue, buffer, false, CL_MAP_READ | CL_MAP_WRITE, 0, bufferSize, 0, 0, 0, &status );
  • 50. 50INTRODUCTION TO OPENCL | JUNE, 2013 例 } 処理の粒度はまちまち } 衝突判定 –  Large vs Large => CPU –  Large vs Small => CPU –  Small vs Small => GPU } CPUとディスクリートGPUを用いると多くのデータ転 送が必要 –  パフォーマンスに響く OpenCL Case Study: Mixed Particle Simulation, Heterogeneous Computing with OpenCL, Chapter 10
  • 52. 52INTRODUCTION TO OPENCL | JUNE, 2013 BOLT } 並列演算プリミティブのC++ライブラリ } オープンソース } OpenCLのコーディングを行わずにGPUを用いることができる –  もしアルゴリズムがサポートされているプリミティブから組み立てることができれば } AMDハードウェアのみ –  Using OpenCL AMD extensions } https://github.com/HSA-Libraries/Bolt int _tmain( int argc, _TCHAR* argv[ ] ) { size_t length = 1024; //Create device_vector and initialize it to 1 bolt::cl::device_vector< int > boltInput( length, 1 ); bolt::cl::device_vector< int >::iterator boltEnd = bolt::cl::inclusive_scan ( boltInput.begin( ), boltInput.end( ), boltInput.begin( ) ); //Create std vector and initialize it to 1 std::vector< int > stdInput( length, 1 ); std::vector< int >::iterator stdEnd = bolt::cl::inclusive_scan ( stdInput.begin( ), stdInput.end( ), stdInput.begin( ) ); return 0; }
  • 53. 53INTRODUCTION TO OPENCL | JUNE, 2013 REFERENCES } OpenCL –  http://www.khronos.org/opencl/ –  http://www.khronos.org/registry/cl/specs/opencl-1.2.pdf } Heterogeneous Computing with OpenCL –  http://developer.amd.com/partners/university-programs/heterogeneous-computing-with-opencl/ } Introduction to OpenCL Programming –  http://developer.amd.com/wordpress/media/2013/01/Introduction_to_OpenCL_Programming-201005.pdf } AMD Graphics Core Next (GCN) Architecture –  http://www.amd.com/us/Documents/GCN_Architecture_whitepaper.pdf
  • 54. 54INTRODUCTION TO OPENCL | JUNE, 2013 DISCLAIMER & ATTRIBUTION The information presented in this document is for informational purposes only and may contain technical inaccuracies, omissions and typographical errors. The information contained herein is subject to change and may be rendered inaccurate for many reasons, including but not limited to product and roadmap changes, component and motherboard version changes, new model and/or product releases, product differences between differing manufacturers, software changes, BIOS flashes, firmware upgrades, or the like. AMD assumes no obligation to update or otherwise correct or revise this information. However, AMD reserves the right to revise this information and to make changes from time to time to the content hereof without obligation of AMD to notify any person of such revisions or changes. AMD MAKES NO REPRESENTATIONS OR WARRANTIES WITH RESPECT TO THE CONTENTS HEREOF AND ASSUMES NO RESPONSIBILITY FOR ANY INACCURACIES, ERRORS OR OMISSIONS THAT MAY APPEAR IN THIS INFORMATION. AMD SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT WILL AMD BE LIABLE TO ANY PERSON FOR ANY DIRECT, INDIRECT, SPECIAL OR OTHER CONSEQUENTIAL DAMAGES ARISING FROM THE USE OF ANY INFORMATION CONTAINED HEREIN, EVEN IF AMD IS EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ATTRIBUTION © 2013 Advanced Micro Devices, Inc. All rights reserved. AMD, the AMD Arrow logo and combinations thereof are trademarks of Advanced Micro Devices, Inc. in the United States and/or other jurisdictions. SPEC is a registered trademark of the Standard Performance Evaluation Corporation (SPEC). Other names are for informational purposes only and may be trademarks of their respective owners.
  • 55. 55INTRODUCTION TO OPENCL | JUNE, 2013 60MIN } 10 –  Introduction –  GPU Architecture } 25 –  OpenCL Example: Vector Add –  OpenCL Example: Reduction } 15 –  Performance Tips –  APU Specific Optimization