SlideShare ist ein Scribd-Unternehmen logo
1 von 54
Downloaden Sie, um offline zu lesen
PEZY-SCプログラミング概要
2019/04/13
PEZY Computing K.K. / ExaScaler Inc.
1
主な内容
 プログラミングに必要な基本的概念の説明
 PZCLの書き方
 プロファイルの取り方
 PEZY-SC2最適化入門
2
主な内容
 プログラミングに必要な基本的概念の説明
 PZCLの書き方
 プロファイルの取り方
 PEZY-SC2最適化入門
3
PEZY-SCの特徴
4
CPU 分岐を含む大規模なコードに強い
並列度は比較的小さい
GPU SIMDメニーコアによる並列化
小規模で単純な並列化可能なコードに強い
PEZY-SC
メモリ階層を意識することで最適化可能なプログラミングモデル
シンプルな命令セットによる省電力
MIMDメニーコアにより並列かつ分岐に強い
自由度の高いプログラミング環境 Village
City
・・・・
Prefecture
DRAM or PCIe
L1 Cache L1 Cache
L2 Cache
L3 Cache
PE PE PE PE
※各PEは20KBのローカルメモリを持つ
PEZY-SC2アーキテクチャ
PEZY-Confidential 5PEZY-SC2 (2,048PE)
Prefecture (256PE) City (16PE) Village (4PE) PE
Program Counter × 8
L1 Instruction Cache
64bit × 512w (4KB)
ALU
4FP ops/cycle
Register File
32bit × 512w (2KB)
Local Storage
32bit × 5120w (20KB)
PE
PE
L1 Data Cache
2KB
PE
PE
Village
(4PE)
L2 Data Cache
64KB
L2 Instruction Cache
32KB
Village
(4PE)
Village
(4PE)
Village
(4PE)
Special Function UnitCity
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
Prefecture (256PE) Prefecture (256PE)
LLC
2560KB
LLC
2560KB
LLC
2560KB
LLC
2560KB
Prefecture (256PE) Prefecture (256PE)
LLC
2560KB
LLC
2560KB
LLC
2560KB
LLC
2560KB
TCI DRAM 512GB/s
TCI DRAM 512GB/s
Prefecture (256PE) Prefecture (256PE)
LLC
2560KB
LLC
2560KB
LLC
2560KB
LLC
2560KB
Prefecture (256PE) Prefecture (256PE)
LLC
2560KB
LLC
2560KB
LLC
2560KB
LLC
2560KB
TCI DRAM 512GB/s
TCI DRAM 512GB/s
MIPS MIPS MIPS
MIPS MIPS MIPS
DDR4 DIMM 25GB/s DDR4 DIMM 25GB/s
DDR4 DIMM 25GB/s DDR4 DIMM 25GB/s
PCIe Gen4 x8
PCIe Gen4 x8
PCIe Gen4 x8
PCIe Gen4 x8
PEZY-SC2諸元
6
PEZY-SC2(2017-)
Process 16nm Fin FET+
Core Freq.
Core 1GHz(Target) / 700MHz(Current ZS2.2)
Peripherals 66MHz
On-chip
Memory
Cache
L1:4MB(D), 8MB(I), L2:8MB(D), 4MB(I)
LLC:40MB
ScratchPad 40MB(20KB/PE)
IPs
CPU MIPS64 R6(P6600) 6Core
PCIe I/F PCIe Gen4 8Lane 4Port(64GB/s)
DRAM I/F DDR4-3200MHz 4port(100GB/s)
Num of PEs 2,048 MIMD / 1,984 MIMD(Current ZS2.2)
Peak Performance
16.4TFlops/HP@1GHz, 11.2TFlops/HP@700MHz
8.2TFlops/SP@1GHz, 5.6TFlops/SP@700MHz
4.1TFlops/DP@1GHz, 2.8TFlops/DP@700MHz
Power Consumption 200W(peak estimated), ~100W(measured)
作成するプログラム
 2種類のプログラムを作成する必要がある
 CPU上のプログラム(C++で記述)
 PEZY-SC上のカーネルプログラム(PZCLで記述)
7
CPU
プログラム
カーネルプログラム1
カーネルプログラム2
main関数
呼び出し
起動
終了
起動
終了
上図のようにCPUプログラムからカーネルプログラムを起動する
※PZCL=カーネルプログラムを記述するPEZY独自仕様の言語
プログラム論理モデル
 OpenCLをベースとしている。
各PEZY-SCに以下のようなコンテクストを作成し、コマンドキュー
を通して通信を行う。
8
コンテクスト
プログラム
カーネル1 カーネル2 ・・・・・カーネル3
バッファ1 バッファ2 ・・・・・バッファ3
コマンドキュー
CPUプログラム
9
CPU
プログラム
カーネルプログラム1
カーネルプログラム2
main関数
呼び出し
起動
終了
起動
終了
CPUプログラム
 通常のC/C++プログラム+OpenCLライクな制御用
レイヤ(PZCL) により実装する
 cl.hppが使えるので、使用感としてはOpenCLを書い
ているのと変わらない
10
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
if (platforms.size() == 0) {
std::cout << "Platform size 0¥n";
return -1;
}
cl_context_properties properties[] =
{ CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0};
cl::Context context(CL_DEVICE_TYPE_DEFAULT, properties);
std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
const char* helloStr = "void pzc_hello(void) { }";
cl::Program::Sources source(1, std::make_pair(helloStr,strlen(helloStr)));
cl::Program program_ = cl::Program(context, source);
program_.build(devices);
cl::Kernel kernel(program_, "hello", &err);
cl::Event event;
cl::CommandQueue queue(context, devices[0], 0, &err);
queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(128), cl::NullRange, NULL, &event);
event.wait();
カーネルプログラム
11
CPU
プログラム
カーネルプログラム1
カーネルプログラム2
main関数
呼び出し
起動
終了
起動
終了
カーネルプログラム
 コンパイルは2種類を提供
 オフラインコンパイル
 オンラインコンパイル
 カーネルの記述にはPZCL C/C++を使用
 フロントエンドはClangなので、C、C++の言語仕様
の多くをサポート
 標準ライブラリは未サポート
 C++14のコア機能は使える
 C++は使えるがあまりサポートしない(つまり自己防衛)
12
カーネルプログラム
 “pzc_”というprefixをつけた関数がカーネル関数として利用可能。
このときclCreateKernelに”pzc_”を外した名前で指定する。
// カーネルコード
void pzc_Add(float* a, float* b, float* c, int count)
{
………
}
// CPUコード
kernel = clCreateKernel(program, "Add", &result)
13Confidential
カーネルプログラム
 以下のようなPEZY-SC制御に必要なBuiltIn-APIがある
 sync_L1 (L1キャッシュにアクセスする単位でのスレッド同期)
 sync_L2 (L2キャッシュにアクセスする単位でのスレッド同期)
 sync (グローバルなスレッド同期)
 flush_L1 (L1キャッシュのフラッシュ)
 flush_L2 (L2キャッシュのフラッシュ)
 flush (グローバルなフラッシュ)
 get_pid (PE ID取得)
 get_tid (PE内スレッドID取得)
 chgthread (PE内スレッドの表裏切り替え)
14
カーネルプログラム
 OpenCLのディレクティブ、BuiltIn-API は使用できない
 __kernelやsampler_t など
 バッファフラッシュの制御はユーザが明示的に行う必要がある。
(ほとんどの場合、プログラムの終了時には明示的にflush命令
を発行する)
Confidential 15
カーネルプログラム(例)
void pzc_foo(…)
{
 PE ID取得(get_pid)
 PE内スレッドID取得(get_tid)
 自スレッドに割り当てられた処理の実行
 出力バッファフラッシュ(flush)
}
Confidential 16
 基本的な構造
カーネルプログラム(例)
void pzc_foo(float* a, …)
{
 PE ID取得(get_pid)
 PE内スレッドID取得(get_tid)
 自スレッドに割り当てられた処理の実行
 出力バッファフラッシュ(flush)
}
Confidential 17
 OpenCLとの違い
__kernel void foo(__global float* a, …)
{
 global_id取得(get_global_id(0))
 自スレッドに割り当てられた処理の実行
}
カーネルプログラム(例)
void pzc_foo(float* a, …)
{
 PE ID取得(get_pid)
 PE内スレッドID取得(get_tid)
 自スレッドに割り当てられた処理の実行
 出力バッファフラッシュ(flush)
}
Confidential 18
 OpenCLとの違い
__kernel void foo(__global float* a, …)
{
 global_id取得(get_global_id(0))
 自スレッドに割り当てられた処理の実行
}
修飾子ではなく、
”pzc_” prefix
__global修飾子は
必要ない
バッファのキャッシュ書き
戻しはソフトウェア責任
主な内容
 プログラミングに必要な基本的概念の説明
 PZCLの書き方
 プロファイルの取り方
 PEZY-SC2最適化入門
19
PEZY-SCxサンプルコード
 サンプルコード
 http://github.com/pezy-mokumoku/samples
 サンプルの内容
 基本的なカーネルの使い方
 カーネルの書き方、マルチデバイスの制御の仕方、Atomic
演算の使い方等
 Reduction
 BandwidthTest, Stream
 その他随時追加予定
 ご要望等あればご意見ください
20
pzcAdd
 vecAdd
 CPU実装
21
void vecAdd(size_t num, double* dst, const double* src0, const double* src1)
{
for(size_t i = 0; i < count; i++) {
dst[i] = src0[i] + src1[i];
}
}
dst src0 src1
= +
pzcAdd
22
CPU
プログラム
Add
main関数
呼び出し
起動
終了
void pzc_add(size_t num,
double* dst,
const double* src0,
const double* src1)
{
size_t pid = get_pid();
size_t tid = get_tid();
size_t gid = pid * get_maxtid() + tid;
const size_t GLOBAL_WORK_SIZE = get_maxtid() *
get_maxpid();
for (size_t i = gid; i < num; i += GLOBAL_WORK_SIZE) {
double s0 = src0[i];
double s1 = src1[i];
chgthread();
dst[i] = s0 + s1;
}
flush();
}
23
• カーネルプログラム
• 加算するコードをPEZY-SCのカーネルコードとして実装
• pzc_add()が指定されたスレッド数分実行される。
• tid, pidにユニークなIDが割り当てられるので、各スレッドはそれぞれの
indexを計算する。
pzcAdd
dst[0] = src0[0] + src1[0]
dst[1] = src0[1] + src1[1]
dst[2] = src0[2] + src1[2]
‥‥‥
スレッド0
スレッド1
スレッド2
pzcAdd
 各スレッドの動作
24
void pzc_add(size_t num,
double* dst,
const double* src0,
const double* src1)
{
size_t pid = get_pid();
size_t tid = get_tid();
size_t gid = pid * get_maxtid() + tid;
const size_t GLOBAL_WORK_SIZE =
get_maxtid() * get_maxpid();
for (size_t i = gid; i < num; i += GLOBAL_WORK_SIZE) {
double s0 = src0[i];
double s1 = src1[i];
chgthread();
dst[i] = s0 + s1;
}
flush();
}
pzcAdd
25
CPU
プログラム
Add
main関数
呼び出し
起動
終了
pzcAdd
 CPUプログラム
 ハンドリング処理(1/5)
 Platformの取得
 Platformに紐づくデバイスの取得
 使用するデバイスの指定
26
// Get Platform
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
const auto& Platform = platforms[0];
// Get devices
std::vector<cl::Device> devices;
Platform.getDevices(CL_DEVICE_TYPE_DEFAULT, &devices);
// Use first device.
const auto& device = devices[0];
pzcAdd
 CPUプログラム
 ハンドリング処理(2/5)
 デバイスとの間にContextを作成
 Contextに対して、コマンドを送り込むCommandQueue
を作成
 デバイスに紐づくカーネルのバイナリを読み込む
 カーネル名をもとにKernelオブジェクトを作成
27
// Create Context.
auto context = cl::Context(device);
// Create CommandQueue.
auto command_queue = cl::CommandQueue(context, device, 0);
// Create Program.
// Load compiled binary file and create cl::Program object.
auto program = createProgram(context, device, "kernel/kernel.pz");
// Create Kernel.
// Give kernel name without pzc_ prefix.
auto kernel = cl::Kernel(program, "add");
pzcAdd
 CPUプログラム
 ハンドリング処理(3/5)
 デバイス用のメモリ領域を確保
 デバイス用入力メモリ領域に対してホスト用入力メモリ領
域のデータを転送
 デバイス用出力メモリ領域を初期化
28
// Create Buffers.
auto device_src0 = cl::Buffer(context, CL_MEM_READ_WRITE, sizeof(double) * num);
auto device_src1 = cl::Buffer(context, CL_MEM_READ_WRITE, sizeof(double) * num);
auto device_dst = cl::Buffer(context, CL_MEM_READ_WRITE, sizeof(double) * num);
// Send src.
command_queue.enqueueWriteBuffer(device_src0, true, 0, sizeof(double) * num,
&src0[0]);
command_queue.enqueueWriteBuffer(device_src1, true, 0, sizeof(double) * num,
&src1[0]);
// Clear dst.
cl::Event write_event;
command_queue.enqueueFillBuffer(device_dst, 0, 0, sizeof(double) * num, nullptr,
&write_event);
write_event.wait();
pzcAdd
 CPUプログラム
 ハンドリング処理(4/5)
 カーネルに対して引数をセット
 起動するワークアイテム数を特定する
 カーネルを起動
 カーネルの終了を待つ
29
// Set kernel args.
kernel.setArg(0, num);
kernel.setArg(1, device_dst);
kernel.setArg(2, device_src0);
kernel.setArg(3, device_src1);
// Get workitem size.
// sc1-64: 8192 (1024 PEs * 8 threads)
// sc2 : 15782 (1984 PEs * 8 threads)
size_t global_work_size = ...
// Run device kernel.
cl::Event event;
command_queue.enqueueNDRangeKernel(kernel, cl::NullRange,
cl::NDRange(global_work_size), cl::NullRange, nullptr, &event);
// Waiting device completion.
event.wait();
PEZY-SC2の制約
ワークアイテムは128の倍数とする
物理スレッド数(15872)を超えたスレッドをワークアイテ
ムとして指定しても動作はするが、その場合はn回のカーネ
ル起動になる
pzcAdd
 ワークアイテム数
 15872?
 現在のPEZY-SC2の仕様
 歩留まり向上のため、124 Cityが動くものを使用
 124 City * 16PE * 8Thread = 15872をSC2では基準とす
る
30
$ ./MultiDevice
-----------------------------------------------
Program: ./MultiDevice
Use 8 device(s)
Work size = 16128
Work size = 16384
Work size = 16000
Work size = 16384
Work size = 16384
Work size = 16000
Work size = 16256
Work size = 16128
pzcAdd
 CPUプログラム
 ハンドリング処理(5/5)
 デバイス用出力メモリ領域からホスト用出力メモリ領域に
データを転送
 CommandQueueに残ったコマンドの終了を待つ
31
// Get dst.
command_queue.enqueueReadBuffer(device_dst, true, 0, sizeof(double) * num,
&dst[0]);
// Finish all commands.
command_queue.flush();
command_queue.finish();
主な内容
 プログラミングに必要な基本的概念の説明
 PZCLの書き方
 プロファイルの取り方
 PEZY-SC2最適化入門
32
プロファイルの取り方
 プロファイルの取り方は2種類
 SDKのExtensionを使用
 カーネル全体のプロファイル
 パフォーマンスカウンタを読む
 カーネル内部、一部分のプロファイルを取得
 プロファイラは?
 まだありません…
 Perfを準備中
 PZSDK 5.0にてサポート予定
33
プロファイルの取り方
 SDKのExtensionを使用
 参考になるSample
 2_Advanced/ext_profile
 取れる情報
 カーネル全体でのPEの動作状況
 動いているサイクル数、止まっているサイクル数…
 キャッシュの動作状況
 L1, L2のRead/Writeリクエスト数、ヒット数
34
プロファイルの取り方
 SDKのExtensionを使用
 使い方
 関数を確認する
 PZSDKのドキュメントのURL入れる
 Extentionのアドレスを取得する
 これはOpenCLのやり方と同じ
35
// Please refer to the pzcl_ext.h or Runtime Extensions section in pzsdk document.
pfnPezyExtSetProfile clExtSetProfile = nullptr;
pfnPezyExtGetProfilePEStatistics clExtGetProfilePEStatistics = nullptr;
pfnPezyExtGetProfilePE clExtGetProfilePE = nullptr;
pfnPezyExtGetProfileCacheStatistics clExtGetProfileCacheStatistics = nullptr;
pfnPezyExtGetProfileCache clExtGetProfileCache = nullptr;
clExtSetProfile = (pfnPezyExtSetProfile)clGetExtensionFunctionAddress("pezy_set_profile");
clExtGetProfilePEStatistics =
(pfnPezyExtGetProfilePEStatistics)clGetExtensionFunctionAddress("pezy_get_profile_pe_statistics");
clExtGetProfilePE =
(pfnPezyExtGetProfilePE)clGetExtensionFunctionAddress("pezy_get_profile_pe");
clExtGetProfileCacheStatistics =
(pfnPezyExtGetProfileCacheStatistics)clGetExtensionFunctionAddress("pezy_get_profile_cache_statistics");
clExtGetProfileCache =
(pfnPezyExtGetProfileCache)clGetExtensionFunctionAddress("pezy_get_profile_cache");
プロファイルの取り方
 SDKのExtensionを使用
 使い方
 pfnPezyExtSetProfile
 プロファイルを有効/無効にする
 pfnPezyExtGetProfilePEStatistics
 PE全体のプロファイル情報を取得する
 pfnPezyExtGetProfilePE
 PEそれぞれのプロファイル情報を取得する
 pfnPezyExtGetProfileCacheStatistics
 キャッシュ(L1, L2) 全体のプロファイル情報を取得する
 pfnPezyExtGetProfileCache
 キャッシュ(L1, L2) それぞれのプロファイル情報を取得す
る
36
プロファイルの取り方
 SDKのExtensionを使用
 sampleの結果
37
$ ./ext_profile 65536
num 65536
Use device : PEZY-SC2
workitem : 15872
***** PE profile statistics *****
elapse_ns : 9741 [ns]
efficiency : 11.129 [%]
***** First city PE profile *****
PE 0 (run, stall, wait) : ( 6819, 2745, 3222) [cycle]
PE 1 (run, stall, wait) : ( 6819, 2685, 3282) [cycle]
…
PE 15 (run, stall, wait) : ( 6819, 3069, 2898) [cycle]
***** L1 cache profile statistics *****
read hit rate : 89.264 [%]
write hit rate : 87.500 [%]
***** First city L1 cache profile *****
Vill 0 read (request, hit) : ( 184, 164) [count]
Vill 0 write (request, hit) : ( 40, 35) [count]
…
Vill 3 read (request, hit) : ( 184, 164) [count]
Vill 3 write (request, hit) : ( 40, 35) [count]
***** L2 cache profile statistics *****
read hit rate : 68.185 [%]
write hit rate : 75.000 [%]
***** First city L2 cache profile *****
City 0 read (request, hit) : ( 336, 231) [count]
City 0 write (request, hit) : ( 80, 60) [count]
PASS
プロファイルの取り方
 パフォーマンスカウンタを読む
 参考になりそうなsample: なし(!?)
 以下のようなコードで読める
 Run = 0x18, stall = 0x1a, wait = 0x1e
38
using perf_counter_t = uint64_t;
template<int reg_idx>
perf_counter_t
read_perf_gpr(void)
{
while (1) {
uint32_t hi0 = __builtin_pz_read_gpr(reg_idx + 1);
uint32_t lo0 = __builtin_pz_read_gpr(reg_idx + 0);
uint32_t hi1 = __builtin_pz_read_gpr(reg_idx + 1);
if (hi1 == hi0) {
return (((uint64_t)hi0)<<32) | lo0;
}
}
return 0;
}
主な内容
 プログラミングに必要な基本的概念の説明
 PZCLの書き方
 プロファイルの取り方
 PEZY-SC2最適化入門
39
PEZY-SC2最適化入門
 PEZY-SC2最適化入門
 まず考えること
 ちゃんと並列化できているか
 メモリアクセス最適化
 その次に考えること
 オーバーヘッドの削減
 Dual-issue
40
PEZY-SC2最適化入門
 ちゃんと並列化できているか?
 PEの命令は基本的にレイテンシ4、スループット1
 1スレッドでだけ実行するところが多いと性能は1/4相当
 スレッドマッピングを考える
 並列化単位と言い換えてもいい
41
TH0F TH1F
TH2F
TH0B TH1B
TH3F
TH3B TH2B
l.chgthread
l.actthread
clk
clk
clk
clk
PEZY-SC2最適化入門
 スレッドマッピング
 どういうスレッド構成が一番いい?
 出力1要素1スレッド
 いわゆるelementwise
 出力1要素1PE
 8スレッドで並列化
 フィルタの処理とかがあっている?
 1要素1City
 16PE * 8スレッドで並列化
 リダクションを必要とする処理とか
42
アプリケーションによって異なるので、試行錯誤が必要!
PEZY-SC2最適化入門
 メモリアクセスの最適化
 基本方針はメモリアクセスを削減する
 レジスタ、ローカルメモリ、L1, L2, LLCをうまく使う
 消せない場合は遅いところへのアクセスを緩和してい
く
 ローカルメモリを使う、ブロッキングする、スレッドを切
り替えてレイテンシを隠す、アクセスするタイミングをそ
ろえる…
43
PEZY-SC2アーキテクチャ(再掲)
PEZY-Confidential 44PEZY-SC2 (2,048PE)
Prefecture (256PE) City (16PE) Village (4PE) PE
Program Counter × 8
L1 Instruction Cache
64bit × 512w (4KB)
ALU
4FP ops/cycle
Register File
32bit × 512w (2KB)
Local Storage
32bit × 5120w (20KB)
PE
PE
L1 Data Cache
2KB
PE
PE
Village
(4PE)
L2 Data Cache
64KB
L2 Instruction Cache
32KB
Village
(4PE)
Village
(4PE)
Village
(4PE)
Special Function UnitCity
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
Prefecture (256PE) Prefecture (256PE)
LLC
2560KB
LLC
2560KB
LLC
2560KB
LLC
2560KB
Prefecture (256PE) Prefecture (256PE)
LLC
2560KB
LLC
2560KB
LLC
2560KB
LLC
2560KB
TCI DRAM 512GB/s
TCI DRAM 512GB/s
Prefecture (256PE) Prefecture (256PE)
LLC
2560KB
LLC
2560KB
LLC
2560KB
LLC
2560KB
Prefecture (256PE) Prefecture (256PE)
LLC
2560KB
LLC
2560KB
LLC
2560KB
LLC
2560KB
TCI DRAM 512GB/s
TCI DRAM 512GB/s
MIPS MIPS MIPS
MIPS MIPS MIPS
DDR4 DIMM 25GB/s DDR4 DIMM 25GB/s
DDR4 DIMM 25GB/s DDR4 DIMM 25GB/s
PCIe Gen4 x8
PCIe Gen4 x8
PCIe Gen4 x8
PCIe Gen4 x8
PEZY-SC2アーキテクチャ(再掲)
PEZY-Confidential 45PEZY-SC2 (2,048PE)
Prefecture (256PE) City (16PE) Village (4PE) PE
Program Counter × 8
L1 Instruction Cache
64bit × 512w (4KB)
ALU
4FP ops/cycle
Register File
32bit × 512w (2KB)
Local Storage
32bit × 5120w (20KB)
PE
PE
L1 Data Cache
2KB
PE
PE
Village
(4PE)
L2 Data Cache
64KB
L2 Instruction Cache
32KB
Village
(4PE)
Village
(4PE)
Village
(4PE)
Special Function UnitCity
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
City
(16PE)
Prefecture (256PE) Prefecture (256PE)
LLC
2560KB
LLC
2560KB
LLC
2560KB
LLC
2560KB
Prefecture (256PE) Prefecture (256PE)
LLC
2560KB
LLC
2560KB
LLC
2560KB
LLC
2560KB
TCI DRAM 512GB/s
TCI DRAM 512GB/s
Prefecture (256PE) Prefecture (256PE)
LLC
2560KB
LLC
2560KB
LLC
2560KB
LLC
2560KB
Prefecture (256PE) Prefecture (256PE)
LLC
2560KB
LLC
2560KB
LLC
2560KB
LLC
2560KB
TCI DRAM 512GB/s
TCI DRAM 512GB/s
MIPS MIPS MIPS
MIPS MIPS MIPS
DDR4 DIMM 25GB/s DDR4 DIMM 25GB/s
DDR4 DIMM 25GB/s DDR4 DIMM 25GB/s
PCIe Gen4 x8
PCIe Gen4 x8
PCIe Gen4 x8
PCIe Gen4 x8
11.2 TB/s
11.2 TB/s
1.4 TB/s
76 GB/s
PEZY-SC2最適化入門
 ローカルメモリを使う
 参考になるsample: 2_Advanced/pzcAdd_local
 ローカルメモリ?
46
PE
Program Counter × 8
L1 Instruction Cache
64bit × 512w (4KB)
ALU
4FP ops/cycle
Register File
32bit × 512w (2KB)
Local Storage
32bit × 5120w (20KB)
PE
L1 Data Cache
2KB
各PEに20KBある
普段はスタックとして使用
スタックは2.5KB/Thread
スレッド7用スタック領域(2.5KB)
スレッド6用スタック領域(2.5KB)
スレッド5用スタック領域(2.5KB)
スレッド4用スタック領域(2.5KB)
スレッド3用スタック領域(2.5KB)
スレッド2用スタック領域(2.5KB)
スレッド1用スタック領域(2.5KB)
スレッド0用スタック領域(2.5KB)
20KB
0x0000
0x4fff
PEZY-SC2最適化入門
 ローカルメモリを使う
 スタックのサイズは任意に変更可能
 1KB/Threadにすると、12KBがユーザー利用可能領域にな
る
 ユーザー利用可能領域は1PE(=8スレッド)で共有
47
スレッド7用スタック領域(2.5KB)
スレッド6用スタック領域(2.5KB)
スレッド5用スタック領域(2.5KB)
スレッド4用スタック領域(2.5KB)
スレッド3用スタック領域(2.5KB)
スレッド2用スタック領域(2.5KB)
スレッド1用スタック領域(2.5KB)
スレッド0用スタック領域(2.5KB)
20KB
0x0000
0x4fff
スレッド7用スタック領域(1KB)
スレッド6用スタック領域(1KB)
スレッド5用スタック領域(1KB)
スレッド4用スタック領域(1KB)
スレッド3用スタック領域(1KB)
スレッド2用スタック領域(1KB)
スレッド1用スタック領域(1KB)
スレッド0用スタック領域(1KB)
8KB
0x0000
0x2000
ユーザ利用可能領域(12KB) 12KB
0x4fff
PEZY-SC2最適化入門
 ローカルメモリを使う
 使い方
 SDKのExtensionを使う
 Host
 dev
48
// Create Kernel.
// Give kernel name without pzc_ prefix.
auto kernel = cl::Kernel(program, "addWithLocal");
// Get stack size modify function.
typedef CL_API_ENTRY cl_int(CL_API_CALL *
pfnPezyExtSetPerThreadStackSize)(cl_kernel kernel, size_t size);
const auto clExtSetPerThreadStackSize =
reinterpret_cast<pfnPezyExtSetPerThreadStackSize>(clGetExtensionFunctionAddress("
pezy_set_per_thread_stack_size"));
if (clExtSetPerThreadStackSize == nullptr) {
throw "pezy_set_per_thread_stack_size not found";
}
// Set stack size each thread.
size_t stack_size_per_thread = 1024;
clExtSetPerThreadStackSize(kernel(), stack_size_per_thread);
void* local_mem_top_addr = (void*)get_local_mem_addr();
PEZY-SC2最適化入門
 スレッドを切り替える
 PEZY-SCxの特徴
 スレッドの表と裏のコントロール
 4スレッドラウンドロビン
 裏に切り替えない限り、4スレッドで回り続ける
49
TH0F TH1F
TH2F
TH0B TH1B
TH3F
TH3B TH2B
l.chgthread
l.actthread
clk
clk
clk
clk
PEZY-SC2最適化入門
 スレッドを切り替える
 スレッド切り替えのタイミング
 chgthread命令発行時
 各レベルsync命令発行時
 各レベルflush命令発行時
50
PEZY-SC2最適化入門
 スレッドを切り替える
 スレッドを切り替えないとどうなるのか?
 flushに到達して初めてスレッドが切り替わる
 ストールは消せないし、キャッシュアクセスも良くない
51
void pzc_add(size_t num,
double* dst,
const double* src0,
const double* src1)
{
size_t pid = get_pid();
size_t tid = get_tid();
size_t gid = pid * get_maxtid() + tid;
const size_t GLOBAL_WORK_SIZE = get_maxtid() *
get_maxpid();
for (size_t i = gid; i < num; i += GLOBAL_WORK_SIZE) {
double s0 = src0[i];
double s1 = src1[i];
dst[i] = s0 + s1;
}
flush();
}
t0 t4
flush
memory
request
PEZY-SC2最適化入門
 スレッドを切り替える
 スレッドを切り替えるとどうなるのか
 メモリアクセスしたときのストールを、別のスレッドに切
り替えることにより隠せる
 キャッシュにも当たりやすい
52
void pzc_add(size_t num,
double* dst,
const double* src0,
const double* src1)
{
size_t pid = get_pid();
size_t tid = get_tid();
size_t gid = pid * get_maxtid() + tid;
const size_t GLOBAL_WORK_SIZE = get_maxtid() *
get_maxpid();
for (size_t i = gid; i < num; i += GLOBAL_WORK_SIZE) {
double s0 = src0[i];
double s1 = src1[i];
dst[i] = s0 + s1;
chgthread();
}
flush();
}
t0 t4
memory
requeststall
chgthread
PEZY-SC2最適化入門
 アクセスのタイミングをそろえる
 メモリアクセスのタイミングがバラバラ
53
void pzc_add(size_t num,
double* dst,
const double* src0,
const double* src1)
{
size_t pid = get_pid();
size_t tid = get_tid();
size_t gid = pid * get_maxtid() + tid;
const size_t GLOBAL_WORK_SIZE = get_maxtid() *
get_maxpid();
for (size_t i = gid; i < num; i += GLOBAL_WORK_SIZE) {
double s0 = src0[i];
double s1 = src1[i];
chgthread();
dst[i] = s0 + s1;
}
flush();
}
t0 t1 … t7
memory
request
PEZY-SC2最適化入門
 アクセスのタイミングをそろえる
 メモリアクセスのタイミングが揃ったことにより性能が向
上する”場合がある”
 Syncのコストと比較してどうなるかは要検討
54
void pzc_add(size_t num,
double* dst,
const double* src0,
const double* src1)
{
size_t pid = get_pid();
size_t tid = get_tid();
size_t gid = pid * get_maxtid() + tid;
const size_t GLOBAL_WORK_SIZE = get_maxtid() *
get_maxpid();
for (size_t i = gid; i < num; i += GLOBAL_WORK_SIZE) {
sync_L2();
double s0 = src0[i];
double s1 = src1[i];
chgthread();
dst[i] = s0 + s1;
}
flush();
}
t0 t1 … t7
memory
request
sync

Weitere ähnliche Inhalte

Was ist angesagt?

OPcache の最適化器の今
OPcache の最適化器の今OPcache の最適化器の今
OPcache の最適化器の今y-uti
 
Dockerと外部ルータを連携させる仕組みを作ってみた
Dockerと外部ルータを連携させる仕組みを作ってみたDockerと外部ルータを連携させる仕組みを作ってみた
Dockerと外部ルータを連携させる仕組みを作ってみたnpsg
 
jcmd をさわってみよう
jcmd をさわってみようjcmd をさわってみよう
jcmd をさわってみようTsunenaga Hanyuda
 
PHP AST 徹底解説(補遺)
PHP AST 徹底解説(補遺)PHP AST 徹底解説(補遺)
PHP AST 徹底解説(補遺)do_aki
 
Mastodonインスタンスをセットアップできるスタートアップスクリプトについて
MastodonインスタンスをセットアップできるスタートアップスクリプトについてMastodonインスタンスをセットアップできるスタートアップスクリプトについて
Mastodonインスタンスをセットアップできるスタートアップスクリプトについてさくらインターネット株式会社
 
JIT のコードを読んでみた
JIT のコードを読んでみたJIT のコードを読んでみた
JIT のコードを読んでみたy-uti
 
Dive into dockerネットワーク
Dive into dockerネットワークDive into dockerネットワーク
Dive into dockerネットワークKazuyuki Mori
 
php-src の歩き方
php-src の歩き方php-src の歩き方
php-src の歩き方do_aki
 
Task Spooler を試した
Task Spooler を試したTask Spooler を試した
Task Spooler を試したy-uti
 
Symfony2でより良いソフトウェアを作るために
Symfony2でより良いソフトウェアを作るためにSymfony2でより良いソフトウェアを作るために
Symfony2でより良いソフトウェアを作るためにAtsuhiro Kubo
 
signal の話 或いは Zend Signals とは何か
signal の話 或いは Zend Signals とは何かsignal の話 或いは Zend Signals とは何か
signal の話 或いは Zend Signals とは何かdo_aki
 
Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門
Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門
Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門Preferred Networks
 
PHP と SAPI と ZendEngine3 と
PHP と SAPI と ZendEngine3 とPHP と SAPI と ZendEngine3 と
PHP と SAPI と ZendEngine3 とdo_aki
 
FPGAアクセラレータの作り方 (IBM POWER+CAPI編)
FPGAアクセラレータの作り方 (IBM POWER+CAPI編)FPGAアクセラレータの作り方 (IBM POWER+CAPI編)
FPGAアクセラレータの作り方 (IBM POWER+CAPI編)Mr. Vengineer
 

Was ist angesagt? (20)

Free bsd jail入門
Free bsd jail入門Free bsd jail入門
Free bsd jail入門
 
OPcache の最適化器の今
OPcache の最適化器の今OPcache の最適化器の今
OPcache の最適化器の今
 
Dockerと外部ルータを連携させる仕組みを作ってみた
Dockerと外部ルータを連携させる仕組みを作ってみたDockerと外部ルータを連携させる仕組みを作ってみた
Dockerと外部ルータを連携させる仕組みを作ってみた
 
jcmd をさわってみよう
jcmd をさわってみようjcmd をさわってみよう
jcmd をさわってみよう
 
PHP AST 徹底解説(補遺)
PHP AST 徹底解説(補遺)PHP AST 徹底解説(補遺)
PHP AST 徹底解説(補遺)
 
Mastodonインスタンスをセットアップできるスタートアップスクリプトについて
MastodonインスタンスをセットアップできるスタートアップスクリプトについてMastodonインスタンスをセットアップできるスタートアップスクリプトについて
Mastodonインスタンスをセットアップできるスタートアップスクリプトについて
 
VerilatorとSystemC
VerilatorとSystemCVerilatorとSystemC
VerilatorとSystemC
 
JIT のコードを読んでみた
JIT のコードを読んでみたJIT のコードを読んでみた
JIT のコードを読んでみた
 
Dive into dockerネットワーク
Dive into dockerネットワークDive into dockerネットワーク
Dive into dockerネットワーク
 
Docker入門
Docker入門Docker入門
Docker入門
 
ARM Compute Library
ARM Compute LibraryARM Compute Library
ARM Compute Library
 
php-src の歩き方
php-src の歩き方php-src の歩き方
php-src の歩き方
 
Task Spooler を試した
Task Spooler を試したTask Spooler を試した
Task Spooler を試した
 
Symfony2でより良いソフトウェアを作るために
Symfony2でより良いソフトウェアを作るためにSymfony2でより良いソフトウェアを作るために
Symfony2でより良いソフトウェアを作るために
 
Dockerと継続的インテグレーション
Dockerと継続的インテグレーションDockerと継続的インテグレーション
Dockerと継続的インテグレーション
 
signal の話 或いは Zend Signals とは何か
signal の話 或いは Zend Signals とは何かsignal の話 或いは Zend Signals とは何か
signal の話 或いは Zend Signals とは何か
 
Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門
Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門
Kubernete Meetup Tokyo #18 - Kubebuilder/controller-runtime 入門
 
PHP と SAPI と ZendEngine3 と
PHP と SAPI と ZendEngine3 とPHP と SAPI と ZendEngine3 と
PHP と SAPI と ZendEngine3 と
 
PHP勉強会 #51
PHP勉強会 #51PHP勉強会 #51
PHP勉強会 #51
 
FPGAアクセラレータの作り方 (IBM POWER+CAPI編)
FPGAアクセラレータの作り方 (IBM POWER+CAPI編)FPGAアクセラレータの作り方 (IBM POWER+CAPI編)
FPGAアクセラレータの作り方 (IBM POWER+CAPI編)
 

Ähnlich wie PEZY-SC programming overview

PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門Yosuke Onoue
 
OpenCLに触れてみよう
OpenCLに触れてみようOpenCLに触れてみよう
OpenCLに触れてみようYou&I
 
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
 
Dbts2012 unconference wttrw_yazekatsu_publish
Dbts2012 unconference wttrw_yazekatsu_publishDbts2012 unconference wttrw_yazekatsu_publish
Dbts2012 unconference wttrw_yazekatsu_publishYohei Azekatsu
 
【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門sandai
 
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】Masahito Zembutsu
 
mod_auth_ticket - Bringing Single-Sign-On to lighttpd
mod_auth_ticket - Bringing Single-Sign-On to lighttpdmod_auth_ticket - Bringing Single-Sign-On to lighttpd
mod_auth_ticket - Bringing Single-Sign-On to lighttpdTaisuke Yamada
 
Building production server on docker
Building production server on dockerBuilding production server on docker
Building production server on dockerHiroshi Miura
 
Building production server on docker
Building production server on dockerBuilding production server on docker
Building production server on dockerHiroshi Miura
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめMakiko Konoshima
 
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1Etsuji Nakai
 
Cloudstack user group meeting in osaka
Cloudstack user group meeting in osakaCloudstack user group meeting in osaka
Cloudstack user group meeting in osakaNaotaka Jay HOTTA
 
Tremaで試すFirewall
Tremaで試すFirewallTremaで試すFirewall
Tremaで試すFirewallM Hagiwara
 
CloudFoundry 2 on Apache CloudStack 4.2.1
CloudFoundry 2 on Apache CloudStack 4.2.1CloudFoundry 2 on Apache CloudStack 4.2.1
CloudFoundry 2 on Apache CloudStack 4.2.1Kotaro Noyama
 
Statically detecting vulnerability under memory pressure using exhaustive search
Statically detecting vulnerability under memory pressure usingexhaustive searchStatically detecting vulnerability under memory pressure usingexhaustive search
Statically detecting vulnerability under memory pressure using exhaustive searchRuo Ando
 
Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
 Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術までAkihiro Suda
 
ASP.NET vNextの全貌
ASP.NET vNextの全貌ASP.NET vNextの全貌
ASP.NET vNextの全貌A AOKI
 
Circle ci and docker+serverspec
Circle ci and docker+serverspecCircle ci and docker+serverspec
Circle ci and docker+serverspecTsuyoshi Yamada
 
pkgsrc とは何か? - よもやま話
pkgsrc とは何か? - よもやま話pkgsrc とは何か? - よもやま話
pkgsrc とは何か? - よもやま話Akio OBATA
 

Ähnlich wie PEZY-SC programming overview (20)

PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門PyOpenCLによるGPGPU入門
PyOpenCLによるGPGPU入門
 
OpenCLに触れてみよう
OpenCLに触れてみようOpenCLに触れてみよう
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
 
Dbts2012 unconference wttrw_yazekatsu_publish
Dbts2012 unconference wttrw_yazekatsu_publishDbts2012 unconference wttrw_yazekatsu_publish
Dbts2012 unconference wttrw_yazekatsu_publish
 
【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門
 
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
 
mod_auth_ticket - Bringing Single-Sign-On to lighttpd
mod_auth_ticket - Bringing Single-Sign-On to lighttpdmod_auth_ticket - Bringing Single-Sign-On to lighttpd
mod_auth_ticket - Bringing Single-Sign-On to lighttpd
 
Building production server on docker
Building production server on dockerBuilding production server on docker
Building production server on docker
 
Building production server on docker
Building production server on dockerBuilding production server on docker
Building production server on docker
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ
 
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
 
Cloudstack user group meeting in osaka
Cloudstack user group meeting in osakaCloudstack user group meeting in osaka
Cloudstack user group meeting in osaka
 
Tremaで試すFirewall
Tremaで試すFirewallTremaで試すFirewall
Tremaで試すFirewall
 
CloudFoundry 2 on Apache CloudStack 4.2.1
CloudFoundry 2 on Apache CloudStack 4.2.1CloudFoundry 2 on Apache CloudStack 4.2.1
CloudFoundry 2 on Apache CloudStack 4.2.1
 
Statically detecting vulnerability under memory pressure using exhaustive search
Statically detecting vulnerability under memory pressure usingexhaustive searchStatically detecting vulnerability under memory pressure usingexhaustive search
Statically detecting vulnerability under memory pressure using exhaustive search
 
Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
 Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
 
Mac Ports
Mac PortsMac Ports
Mac Ports
 
ASP.NET vNextの全貌
ASP.NET vNextの全貌ASP.NET vNextの全貌
ASP.NET vNextの全貌
 
Circle ci and docker+serverspec
Circle ci and docker+serverspecCircle ci and docker+serverspec
Circle ci and docker+serverspec
 
pkgsrc とは何か? - よもやま話
pkgsrc とは何か? - よもやま話pkgsrc とは何か? - よもやま話
pkgsrc とは何か? - よもやま話
 

PEZY-SC programming overview