© 2017 IBM Corporation
数理・計算科学特論C
プログラミング言語処理系の最先端実装技術
第11講 ハードウェア・アクセラレーション
2018年1月9日
日本アイ・ビー・エム(株) 東京基礎研究所
石崎 一明 kiszk@acm.org
(資料作成協力:井上拓、大平怜)
IBM Research - Tokyo
© 2017 IBM Corporation
IBM Research - Tokyo
自己紹介
石崎 一明(いしざき かずあき) http://ibm.biz/ishizaki
1992年3月 早稲田大学理工学研究科修士課程電気工学専攻を修了。
1992年4月 日本アイ・ビー・エム(株)入社、東京基礎研究所勤務。以来、並列化コンパイラ、動的
コンパイラ、アプリケーション最適化、などの研究に従事。最近は、GPGPUのためのコンパイル技術
の研究、Apache Sparkの高速化、に従事。現在、同研究所シニア・テクニカル・スタッフ・メンバー
2002年12月 早稲田大学理工学研究科にて、博士(情報科学)を取得。
2008年から2009年まで、IBMワトソン研究所に滞在。
2004年に情報処理学会業績賞受賞。ACMシニアメンバー、情報処理学会シニアメンバー
主なAcademic Activity
2004, 5年 日本ソフトウェア科学会PPL 2004/2005ワークショップ プログラム委員
2006年 日本ソフトウェア科学会PPL 2006ワークショップ プログラム共同委員長
2008年 PC Member of ACM OOPSLA 2013 Conference
2007~2009年度 日本ソフトウェア科学会プログラミング論研究会 運営委員
2011~2014年度 情報処理学会アーキテクチャ研究会 運営委員
2015年~ 日本ソフトウェア科学会理事
2016年度~ 情報処理学会プログラミング研究会 運営委員
2017年 PC Member of IEEE BigData 2017
2
© 2017 IBM Corporation
IBM Research - Tokyo
講義予定のおさらい と 今回のトピック
3
Topic Lecturer Date Time
1 Runtime – JVM Overview & Interpreter 緒方 11/30 木 13:20~14:50
2 Runtime – Object Management &
Synchronization
河内谷 12/5 火 13:20~14:50
3 Runtime – Native Memory Management 緒方 12/5 火 15:05~16:35
4 Compiler – Overview 仲池 12/7 木 13:20~14:50
5 Compiler – Dataflow Analysis 稲垣 12/12 火 13:20~14:50
6 Compiler – Devirtualization & Inlining 石崎 12/12 火 15:05~16:35
7 Hot topic – X10 竹内 12/14 木 13:20~14:50
8 Hot topic – Open Source Java VM 堀江 12/19 火 13:20~14:50
9 Hot topic – Full-stack Optimization 堀井 12/19 火 15:05~16:35
10 Compiler – Trace Compilation & LLVM 井上 12/21 木 13:20~14:50
11 Hot topic – H/W Acceleration
(GPGPU, HTM, FPGA)
石崎 1/9 火 13:20~14:50
12 まとめと展望 小野寺 1/9 火 15:05~16:35
© 2017 IBM Corporation
IBM Research - Tokyo
今日の講義内容
▪ ハードウェアアクセラレータ、とは
– あるカテゴリの演算を効率よく実行可能
▪ プログラミング言語からハードウェアアクセラレータを使う方法
– 明示的にハードウェアアクセラレータを制御する命令を呼ぶ
–ライブラリを経由してハードウェアアクセラレータを制御する命令を呼ぶ
– システムが自動的にハードウェアアクセラレータを制御する命令を呼ぶ
▪ ハードウェアアクセラレータがよく使われる分野の一例
– 深層学習
4
© 2017 IBM Corporation
IBM Research - Tokyo
今日の授業でわかること
▪ ハードウェアアクセラレータの概要について
– SIMD
– GPGPU
– Hardware transactional memory
–FPGA
▪ プログラミング言語からハードウェアアクセラレータを使う方法とその利点欠点(
SIMDを例に)
– プログラマが命令を書く
–プログラマがライブラリを呼ぶ
– プログラマが書いたプログラムをコンパイラが変換する
▪ 深層学習について
– どのような処理が内部で行われているか
–どのような処理がハードウェアアクセラレータで高速化できるか
– プログラミング処理系として、どのような高速化ができるか
5
© 2017 IBM Corporation
IBM Research - Tokyo
ハードウェアアクセラレータとは?
6
© 2017 IBM Corporation
IBM Research - Tokyo
ハードウェアアクセラレータ
▪ CPUの汎用命令の組み合わせで処理していたのでは効率が悪い処理を、効
率よく処理するハードウェア
– 改善例
• スループットの改善
• レイテンシの改善
• 消費電力効率の改善
– ハードウェア例
• Single Instruction Multiple Data (SIMD)
• General Purpose Graphic Processing Unit (GPGPU)
• Hardware Transactional Memory (HTM)
• Field Programmable Gate Array (FPGA)
• 専用ハードウェア
–例: GRAvity PiPE (GRAPE) - 重力相互作用の計算
7
© 2017 IBM Corporation
IBM Research - Tokyo
SIMD
▪ CPU内で1命令(1つの命令カウンタ)で複数データに同時に同じ処理(2~64
程度)を行う
▪ 多くのプロセッサで実装されている
– Intel x86: MMX, SSE, SSE2, SSE3, SSE4, AVX, AVX2, AVX-512
–PowerPC: VMX, VSX
– System z
– ARM: NEON, NEON28
ベクタレジスタ
SIMD命令
A0 A1 A2 A3
B0 B1 B2 B3
C0 C1 C2 C3
add add add add
input 1
input 2
output
A0
B0
C0
add
input 1
input 2
output
add gr1,gr2,gr3 vadd vr1,vr2,vr3
scalar instruction SIMD instruction
© 2017 IBM Corporation
IBM Research - Tokyo
GPGPU
▪ 数千の実行ユニット(例:CUDA core)で異なるデータに対して同時に命令を実
行し、同じ処理を同時に行う
– 条件分岐を処理する場合、条件が成立した実行ユニットと条件が成立しな
い実行ユニットで異なる処理を行う
–ロードストアは、実行ユニットごとに異なるアドレスからロードストア可能
▪ 画像処理、密行列演算、などに高い性能を発揮する
▪ GPGPUを製造しているメーカは限られている
– NVIDIA、AMD、Intel、など9
Source: https://www.slideshare.net/NVIDIAJapan/nvidia-tesla-v100cuda-9
© 2017 IBM Corporation
IBM Research - Tokyo
HTM
▪ ハードウェアで、クリティカルセクションを楽観的に並行実行後、正当性を検査
– 命令の配置
• クリティカルセクションを
トランザクション開始・終了命令で囲む
–実行時
• トランザクションを同時に実行し
メモリ操作が衝突したかを検査。
衝突したら最初から実行し直す
– トランザクション中のメモリ操作は1ステップで
行われたかのように他スレッドからは観測される
→従来のロックよりも高い並列性が期待される
– 正当性検査に、実装からくる制限が存在する
▪ いくつかのプロセッサで実装されている
– 2012: Blue Gene/Q, zEC12
– 2013: Intel 4th Generation Core Processor
– 2014: IBM POWER8
– 2017: IBM POWER9
10
lock();
a->count++;
unlock();
xbegin();
a->count++;
xend();
xbegin();
a->count++;
xend();
xbegin();
b->count++;
xend();
xbegin();
a->count++;
xend();
xbegin();
a->count++;
xend();
Thread X Thread Y
ロック HTM
© 2017 IBM Corporation
IBM Research - Tokyo
FPGA
▪ プログラミングによって、内部の論理回路を何度も再構成な半導体デバイス
– 一般にCPUより、動作速度が遅い(1GHz程度)
▪ 性能あたりの消費電力を削減できることが多い
▪ FPGAを製造しているメーカは限られている
– Xilinx、Altera、など
11
© 2017 IBM Corporation
IBM Research - Tokyo
今日の授業でわかること
▪ ハードウェアアクセラレータの概要について
– SIMD → 同じ処理を数十のデータに適用可能
– GPGPU → 同じ処理を数千のデータに適用可能で、異なる処理も一部可能
– Hardware transactional memory → 高い並列性を得ることができる
–FPGA → 回路を書き換えることができ、電力当りの処理効率を高めやすい
▪ プログラミング言語からハードウェアアクセラレータを使う方法とその利点欠点(
SIMDを例に)
– プログラマがSIMD命令を書く
–プログラマがライブラリを呼ぶ
– プログラマが書いたプログラムをコンパイラが変換する
▪ 深層学習について
– どのような処理が内部で行われているか
–どのような処理がハードウェアアクセラレータで高速化できるか
– プログラミング処理系として、どのような高速化ができるか
12
© 2017 IBM Corporation
IBM Research - Tokyo
プログラミング言語から
ハードウェアアクセラレータを使うには?
13
© 2017 IBM Corporation
IBM Research - Tokyo
使い方の3つの方法
▪ 専用命令を使ってプログラミングする
▪ 特定の処理を行うライブラリを呼ぶ
– 例:行列積
▪ 普通にプログラムを書いて、コンパイラが自動的に専用命令を生成する
14
© 2017 IBM Corporation
IBM Research - Tokyo
SIMDの専用命令を使ってプログラミング
▪ 命令列を記述する方法
– アセンブラ、gcc/clangのasm文のインラインアセンブラ
– gcc/clangの組み込み関数(intrinsic)
• gccやclangでは、SIMD用にデータの型が拡張されている
• コンパイラが、レジスタ割付けや命令スケジューリングを行ってくれる
15
© 2017 IBM Corporation
IBM Research - Tokyo
SIMD組み込み関数によるプログラム例
16
for (i = 0; i < N; i += 8) {
__m256i v1 = _mm256_loadu_si256((__m256i *)(a+i));
__m256i v2 = _mm256_loadu_si256((__m256i *)(b+i));
__m256i v3 = _mm256_add_epi32(v1, v2);
_mm256_storeu_si256((__m256i *)(c+i), v3); }
for (i = 0; i < N; i++) c[i] = a[i] + b[i];
for (i = 0; i < N; i += 4) {
vector int v1 = vec_ld(0, a+i);
vector int v2 = vec_ld(0, b+i);
vector int v3 = vec_add(v1, v2);
vec_st(v3, 0, c+i); }
元のスカラループ
AVX2用組み込み関数を使った例
VMX用組み込み関数を使った例
8 (= 256 / 32)要素を同時に処理
32-bit整数配列
4 (= 128 / 32)を同時に処理
vec_add() isはSIMDのadd命令に対応する
vector int は4つの32-bit整数値を持つ
ベクタレジスタ
© 2017 IBM Corporation
IBM Research - Tokyo
SIMD組み込み関数でプログラミングする利点欠点
☺高い性能を得ることができる
– このためには、アルゴリズムやデータ配置まで変更することが多い
☺アセンブラで書くよりは、簡単にプログラムを書くことができる
– レジスタ割付けや命令スケジューリングは、コンパイラが行う
プログラミング、デバッグ、メンテナンスが容易ではない
プロセッサ・アーキテクチャに依存したコードとなり、プロセッサ間の移植性が
低い
Java、JavaScriptのようなプラットフォーム独立な言語では、あまり適していな
い
17
© 2017 IBM Corporation
IBM Research - Tokyo
SIMD命令を使うライブラリによるプログラム例
18
// c = αAB + βC を計算する
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
N, N, N,
1.0, A, N,
B, N,
0.0, C, N);
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
for (k = 0; k < N; k++)
C[i*N + j] += A[i*N + k] * B[k*N + j];
元のスカラループ
行列積を計算するライブラリを使った例
© 2017 IBM Corporation
IBM Research - Tokyo
SIMD命令を使うライブラリでプログラミングする利点欠点
☺高い性能を得ることができる
– プロセッサメーカーが最適化したライブラリは、プログラマがアセンブラで書
くより性能が高いことがある
☺簡単にプログラムを書くことができる
高速化できる処理が、ライブラリで提供された処理に限られる
データ配置などの前提が合わないときは、使用できない。もしくは、データ変換
が必要になる。
19
© 2017 IBM Corporation
IBM Research - Tokyo
コンパイラによる自動SIMD命令生成でプログラミング
▪ 自動ベクタ化(automatic vectorization)によって、プログラマが書いたコードか
ら、自動的にSIMD命令を生成する
▪ コンパイラは与えられたループを解析して、可能であればSIMD命令を用いる
ループを生成する
– 可能でない、と判断する主な原因
• ループ間にデータ依存(loop-carried dependence)がある
• ループ内に(if文などの)分岐がある場合
• メモリアクセスが、キャッシュ境界からずれている
• ループ内に、メソッド呼び出しがある
20
© 2017 IBM Corporation
IBM Research - Tokyo
コンパイラによる自動SIMD命令生成のプログラム例
▪ コンパイラが行う解析
– 入力と出力の配列が、同じメモリアドレスをアクセスしていないか?
Loop-carried dependenceの存在確認
– メモリアクセスが、キャッシュ境界からずれていないか?
• キャッシュ境界からずれた部分を処理する、非SIMDコードを生成する
– ループを繰り返し実行する回数N、はベクタ長の倍数か?
• 倍数でない可能性があるときは、端数を処理する非SIMDコードを生成
する
21
元のスカラループ
for (i = S; i < E; i++) c[i] = a[i] + b[i];
© 2017 IBM Corporation
IBM Research - Tokyo
コンパイラの解析を助ける方法
▪ アルゴリズムやデータ配置の変更
– アルゴリズム
• 例:SOR → Red-black SOR
– データ配置
• 例:Array of structs(AOS) → Struct of arrays(SOA)
▪ プログラムの性質の保証
– “restrict” keyword of C99
• ある配列変数が、他の変数とエイリアスしないことを保証する
– Pragmaを用いた、SIMDを使用する宣言
22
void func(double *restrict a, double *restrict b, double *restrict c)
{ /* 配列a[], b[], and c[]はこの関数の中で異なるアドレスであることを保証 */ }
#pragma omp simd (OpenMP 4.0)
#pragma simd (icc)
#pragma disjoint (xlc)
© 2017 IBM Corporation
IBM Research - Tokyo
AOSとSOA
▪ データ配置の変更は、非効率な非連続メモリアクセスをなくしたSIMD命令実行
のために、重要であることが多い
– コンパイラは、このようなデータ配置の変更は容易ではない
23
y0 z0x0 y1 z1x1 y2 z2x2 y3 z3x3 
x0 x1 x2 x3 
y4 z4x4
x4 y0 y1 y2 y3 y4 z0 z1 z2 z3 z4 
Array of Structures (AOS)
Structure of arrays (SOA)
y5x5
(4-wayのSIMDを仮定)
struct _AOS { double x, y, z; }
struct _AOS aos[N];
struct _SOA { double x[N], y[N], z[N]; }
struct _SOA soa;
x0 x1 x2 x3 x4y0 y1 y2 y3 z0 z1 z2 z3 
Hybrid
x5 x6 x7 y4
struct _HYBRID { double x[4], y[4], z[4]; }
struct _HYBRID hybrid[N/4];
© 2017 IBM Corporation
IBM Research - Tokyo
コンパイラによる自動SIMD命令生成でプログラミングする利点欠点
☺ソースコードをSIMD専用に変更する必要がない
SIMD組み込み関数、ライブラリを使った場合ほどの性能向上が得られないこ
とが多い
24
[1] Maleki et al. “An Evaluation of Vectorizing Compilers”, PACT 2011
on POWER7 on Nehalem
ベンチマークプログラムのSIMD無し実行に対する、平均性能向上比[1]
XLC ICC GCC
プログラムの変更なしに自動SIMD命令生成 1.66 1.84 1.58
プログラムを手で変換後、自動SIMD命令生成 2.97 2.38 N/A
SIMD組み込み関数で記述 3.15 2.45 N/A
© 2017 IBM Corporation
IBM Research - Tokyo
Java処理系でのSIMD命令利用方法
▪ 単純ループのコンパイラによる自動SIMD変換
• 複雑なループも技術的には変換可能だが、動的コンパイラでは時間が
かかる解析を行うことは難しい
– 行列積、行列ベクトル積を行うループなどは変換可能
–演算対象が一次元のprimitive type配列であること
– IBM Java 8、Open JDK 8/9に実装
▪ Javaクラスライブラリでの活用
– ループ処理が多いライブラリで使用
• java/lang/String, Java/util/Arrays, String encoding converter
• IBM Java 8に実装
▪ SIMD組み込み関数
– Vector APIとして議論中
25
for (int i = 0; i < C.length; i++) {
C[i] = A[i] + B[i];
}
FloatVector.FloatSpecies<Shapes.S256Bit> species =
(FloatVector.FloatSpecies<Shapes.S256Bit>)
Vector.speciesInstance(Float.class, Shapes.S_256_BIT);
void add(float[] A, float [] B, float [] C) {
FloatVector<Shapes.S256Bit> a, b, c;
a = species.fromArray(A, 0);
b = species.fromArray(B, 0);
c = a.add(b);
c.intoArray(C, 0); }
元のスカラループ
提案中の組み込み関数を使った例
https://software.intel.com/en-us/articles/vector-api-developer-program-for-java
© 2017 IBM Corporation
IBM Research - Tokyo
使い方の3つの方法のトレードオフ
▪ 専用命令・組み込み関数を使ってプログラミングする
☺性能が高い
プログラミングが容易ではない
プログラムのポータビリティが低い
▪ 特定の処理を行うライブラリを呼ぶ
☺性能が高い
☺プログラムのポータビリティが高い
予め決められた条件での処理しか高速化されない
▪ コンパイラが専用命令を生成する
☺プログラムのポータビリティが高い
性能がほどほど
変換されるプログラムが限られる
26
© 2017 IBM Corporation
IBM Research - Tokyo
GPGPUの利用方法
▪ 専用命令を使ってプログラミングする
– GPGPUメーカーが用意したアセンブリ言語、専用関数でプログラムを書く
• PTX(NVIDIA)、GCN(AMD)
▪ 特定の処理を行うライブラリを呼ぶ
–cuBLAS、などの行列演算
• プログラマがアセンブラで書くより速いことが多い
▪ 普通にプログラムを書いて、コンパイラが自動的に専用命令を生成する
– ホスト-アクセラレータ間の処理などは自分で書く(例:CUDA, OpenCL)
–コンパイラが自動でコードを生成する(例:OpenACC, OpenMP)
27
#pragma acc parallel loop
for (i = 0; i < N; i++) c[i] = a[i] + b[i];
cudaMalloc(&d_a, N*sizeof(float)); cudaMemcpy(d_a, a, N*sizeof(float), cudaMemcpyHostToDevice)
...
add<<GRID, BLOCK>>>(d_a, d_b, d_c);
cudaMemcpy(c, d_c, N*sizeof(float), cudaMemcpyDeviceToHost);
__global__ void add(float *a, float *b, float *c) {
I = blockIdx.x * blockDim.x + threadIdx.x;
c[i] = a[i] + b[i];}
© 2017 IBM Corporation
IBM Research - Tokyo
Java処理系でのHTMの利用方法
▪ 特定の処理を行うライブラリを呼ぶ
– java.util.concurrentライブラリでの活用
• 複雑なロックフリーアルゴリズムの代わりに、HTMを使用することで実
行パスが単純になり高速化
• IBM Java 8に実装
▪ 普通にプログラムを書いて、コンパイラが自動的に専用命令を生成する
– synchronized block・メソッドの置き換え
• synchronized block・メソッドのクリティカルセクションを、HTMで実行す
ることで高い並列性が得られる
• HTM実行で性能向上が得られない場合は、従来のロックによる実行に
移行
• IBM Java 8、OpenJDKに実装
28
© 2017 IBM Corporation
IBM Research - Tokyo
FPGAの利用方法
▪ 専用命令を使ってプログラミングする
– ゲートをGUI・テキストで入力
– 専用のハードウェア記述言語(VHDL、Verilog)で記述
▪ 特定の処理を行うライブラリを呼ぶ
–すでにプログラミングが済んだFPGAを呼び出す
• 圧縮、データ処理、ネットワーク処理、など
▪ プログラムを書いて、コンパイラが自動的に専用命令を生成する
– C++言語で、ライブラリ・新しい型などを用いてプログラミング(SystemC)
• ある程度ハードウェアの知識が必要(信号線専用の変数型、などを利用
している)
– ソフトウェアを記述する言語(CやJava)から回路を生成可能
• XILINX社Vivado HLS、など
29
© 2017 IBM Corporation
IBM Research - Tokyo
今日の授業でわかること
▪ ハードウェアアクセラレータの概要について
– SIMD
– GPGPU
– Hardware transactional memory
–FPGA
▪ プログラミング言語からハードウェアアクセラレータを使う方法とその利点欠点(
SIMDを例に)
– プログラマがSIMD命令を書く → 性能は高いが、プログラミングが難しい
–プログラマがライブラリを呼ぶ → 性能は高いが、処理が限られる
– プログラマが書いたプログラムをコンパイラが変換する → 性能はそこそこだ
が、ポータビリティは高い
▪ 深層学習について
– どのような処理が内部で行われているか
– どのような処理がハードウェアアクセラレータで高速化できるか
– プログラミング処理系として、どのような高速化ができるか30
© 2015 IBM Corporation
IBM Research - Tokyo
ハードウェアアクセラレータが
よく使われる分野の一例
31
© 2017 IBM Corporation
IBM Research - Tokyo
深層学習(Deep Learning)
▪ 2012年の画像認識コンテストにおいて、Deep Learningを使用したアルゴリズ
ム(AlexNet)が認識率を大きく改善し、圧倒的な勝利をおさめた
▪ その後、急速にDeep Learningに関する研究が進展し、アルゴリズムの改良と
ともに、様々な分野での適用が研究・実用化されている
–応用例
• 画像認識
• 機械翻訳
• オンラインショッピングの商品のおすすめ
• ゲーム
–囲碁、将棋
• 音声認識
• 自動運転
• …
32
© 2017 IBM Corporation
IBM Research - Tokyo
深層学習(Deep Learning)とは?
▪ 層(Layer)をたくさん(多いものは100以上)重ねたニューラルネットワーク
– あるデータを入力すると、正解に近い出力を生成する(推論・Inference)
– 推論をよりよいものにするためには、多くのデータを入力して、正解に近い
出力を生成するように学習する必要がある(学習・Training)
• 学習=重みの更新
▪ 層の各点では、矢印が持つ重みを用いて計算を行う
– 推論の例
33
魚 0.95
鳥 0.05
層 層 層 層
重み
重み
重み
© 2017 IBM Corporation
IBM Research - Tokyo
画像を認識するニューラルネットの例
▪ LeNet [Yann98]: 0~9の手書き文字の入力の認識
– データに、5x5のフィルタを適用し特徴を抽出した後、データの大きさを減らす
• 学習すると、フィルタの値が更新される
– 全結合層で1次元のベクタに変換する
–最後の層で、0-9に関する確率分布に変換する
34
0 0.01
…
6 0.002
7 0.91
8 0.003
9 0.05
畳み込み
活性化
層
32x32
5x5
28x28を
6種類
プー
リング
層
14x14を
6種類
10x10を
16種類
5x5を
16種類5x5
1x120
1x84
1x10
全結合畳み込み
活性化
プー
リング 全結合
全結合
© 2017 IBM Corporation
IBM Research - Tokyo
層で行う処理は、何を行っているか?
▪ 畳み込み(Convolution)
– 入力データとフィルタで行列の内積を求める
▪ 活性化関数(Activation function)
– Tanh:ハイパボリックタンジェント
– ReLU: 値が0以下であれば0,それ以外は入力値を取る
• 最近はReLUが使われることが多い
▪ プーリング関数(Pooling)
– MaxPooling: 近傍(例えば2x2)の最大値を取る
35
0 1 1 0 0
1 0 1 1 0
1 1 1 1 1
0 1 1 1 1
1 1 1 1 0
-1 1 -1
1 0 1
-1 1 -1
= 0x-1 + 1x1 + 1x-1 +
1x1 + 0x0 + 1x1 +
1x-1 + 1x1 + 1x-1 = 1
1 0 -1
0 1 1
-1 0 1
入力データ フィルタ
0 1 1 0 0
0
1
1
1
1
0
1
-1
-1
2 1 -1 1
1 0 0
0 1 1
0 0 1
1
0
0
2 1 0 1
1 1
2 1
ReLU
MaxPooling
© 2017 IBM Corporation
IBM Research - Tokyo
層で行う処理は、何を行っているか?
▪ 全結合(Full connection)
– 行列ベクトル積を求める
36
0
1
0
0
1
1 1 0
0 0 1
0 1 1
2
0
2
入力データ
重み
0
11 1 0
1 1 0
1 0 1
0 1 1
1 0 1
1x0 + 1x1 + 0x0 +
1x0 + 1x1 + 0x0 = 2
© 2017 IBM Corporation
IBM Research - Tokyo
各処理はどのように記述できるか?
▪ Convolution
– 4重ループで、外側2重は並列実行、内側2重は積和演算でリダクション実行可能
▪ ReLU
– 並列実行可能な2重ループで、max()を実行
37
parfor (yo = 0, yi = 1; yi < height-1; yi++, yo++) {
parfor (xo = 0, xi = 1; xi < width-1; xi++, xo++) {
reducefor (yf = 0; yf < filterHeight; yf++) {
reducefor (xf = 0; xf < filterWidth; xf++) {
output1[yo][xo] +=
input[yi + yf – 1][xi + xf – 1] * filter[yf][xf];
}}}}
parfor (yi = 0; yi < height; yi++) {
parfor (xi = 0; xi < width; xi++) {
output2[yi][xi] = max(0, output1[yi][xi]);
}}
※実際には、さらに計算量とデータの再利用を増やす変換が行われています(バッチ化)
© 2017 IBM Corporation
IBM Research - Tokyo
各処理はどのように記述できるか?
▪ MaxPooling
– 4重ループで、外側2重は並列実行、内側2重は最大値を求めるリダクション実行可能
▪ Full connection
– 2重ループで、外側は並列実行、内側は積和演算でリダクション実行可能
38
parfor (yo = 0; yo < height; yo++) {
reducefor (xf = 0; xf < weightWidth; yf++) {
output[yo] += weight[yo][xf] * input[xf];
}}
※実際には、さらに計算量とデータの再利用を増やす変換が行われています(バッチ化)
parfor (yi = 0, yo = 0; yi < height; yi += poolHeight, yo++) {
parfor (xi = 0, xo = 0; xi < width; xi += poolWidth, xo++) {
reducefor (maxval = -INF, yp = 0; yp < poolHeight; yp++) {
reducefor (xp = 0; xp < poolWidth; xp++) {
maxval = max(output2[yi+yp][xi+xp], maxval);
}}
output3[yo][xo] = maxval;
}}
© 2017 IBM Corporation
IBM Research - Tokyo
ハードウェアアクセラレータとの親和性
▪ Convolution
– 4重ループで、外側2重は並列実行、内側2重は積和演算でリダクション実行可能
▪ ReLu
– 並列実行可能な2重ループで、max()を実行
▪ MaxPooling
– 4重ループで、外側2重は並列実行、内側2重は最大値を求めるリダクション実行可能
▪ Full connection
– 2重ループで、外側は並列実行、内側は積和演算でリダクション実行可能
39
比較的決まった処理で、並列処理が多いので
ハードウェアアクセラレータ向き
特に、計算量の多いConvolutionを高速化したい
© 2017 IBM Corporation
IBM Research - Tokyo
どんなハードウェアアクセラレータが使われている?
▪ SIMD
– 行列演算の高速化は得意
▪ GPGPU
– NVIDIAのVoltaは、16bit浮動小数点行列演算専用回路を搭載
▪ Deep Learning専用プロセッサ
– Tensor Processing Unit2 (TPU2), (Google)
• 低精度浮動小数点行列演算とactivation functionを高速に実行する
– Nervana (Intel)
–Lightspeeur 2810S (Gyrfalcon technology)
– など
40
© 2017 IBM Corporation
IBM Research - Tokyo
ニューラルネットを記述して、実行する方法は?
▪ 深層学習用のフレームワークを用いて、ニューラルネットを記述する
– Caffe (UC Berkley), http://caffe.berkeleyvision.org/
– TensorFlow (Google), https://www.tensorflow.org/
– PyTorch (Facebook), http://pytorch.org/
–Chainer (PFN), https://chainer.org/
– MXNet (U of Washington, CMU, Amazon),
https://mxnet.incubator.apache.org/
– NNabla (Sony), https://nnabla.org/
–などなど
▪ これらのフレームワークは、ハードウェアアクセラレータが用意している専用ラ
イブラリを呼ぶ
– Convolution、などの代表的な演算を高速化するライブラリ
• cuDNN by NVIDIA
• Math Kernel Library for Deep Neural Networks (MKL-DNN) by Intel
41
© 2017 IBM Corporation
IBM Research - Tokyo
さらに高速化できないか?
▪ フレームワークで書かれたニューラルネットワーク構造は、プログラムとみなす
ことができる
– フレームワークによっては、Pythonで記述する
▪ 専用コンパイラで最適化を適用してコンパイルして、アクセラレータ命令を呼ぶ
コードを生成することで高速化を図る
– TensorFlow XLA
– TVM/NNVM
– PraidML
– PyTorch42
import tensorflow as tf
with tf.name_scope('conv1'):
w_tensor = tf.variable(...)
b_tensor = tf.variable(...)
c_tensor = tf.nn.conv2d(x_image, w_tensor, strides=...)
t_tensor = c_tensor + b_tensor
h_tensor = tf.nn.relu(t_tensor)
© 2017 IBM Corporation
IBM Research - Tokyo
TensorFlow XLA
43 Source: https://autodiff-workshop.github.io/slides/JeffDean.pdf
▪ HLO: 命令融合、共通式削除、などを行う
▪ LLO: 対象のアーキテクチャ独自の最適化を行う(実装はLLVMを使っている)
▪ Executor API: 各処理(例:conv2d, ReLU)を実行する
© 2017 IBM Corporation
IBM Research - Tokyo
NNVM/TVM
▪ NNVM: グラフ上での最適化を行う
– ノードの融合、など
▪ TVM: Tensorに関する最適化を行う
– Tensor計算の融合、など
44 Source: http://www.tvmlang.org/2017/10/06/nnvm-compiler-announcement.html
© 2017 IBM Corporation
IBM Research - Tokyo
最後におまけ
▪ AIやDeep Learningが流行って、言語処理の研究分野は廃れていくのか?
45
© 2017 IBM Corporation
IBM Research - Tokyo
最後におまけ
▪ AIやDeep Learningが流行って、言語処理の研究分野は廃れていくのか?
– そんなことはないです。
“言語処理系屋さん”、”コンパイラ屋さん”、には”需要”があります。
その時代に重要なワークロードがあれば、それを高速化する命令やアクセ
ラレータが開発されるでしょう。
使う人の裾野が広がれば、生産性を高めるための専用言語やフレームワ
ークが開発されます。
そして、人はわがままなので、生産性を高めるだけでなく高速化したい、と
言い出します。
こういう要求によりよく答えるために、言語設計や最適化コンパイラの研究
は続いていくと思っています。
46
© 2017 IBM Corporation
IBM Research - Tokyo
今日の授業でわかること
▪ ハードウェアアクセラレータの概要について
– SIMD
– GPGPU
– Hardware transactional memory
–FPGA
▪ プログラミング言語からハードウェアアクセラレータを使う方法とその利点欠点
– プログラマがSIMD命令を書く
– プログラマがライブラリを呼ぶ
–プログラマが書いたプログラムをコンパイラが変換する
▪ 深層学習について
– どのような処理が内部で行われているか → 行列演算
– どのような処理がハードウェアアクセラレータで高速化できるか → 浮動小数
点の行列演算
– プログラミング処理系として、どのような高速化ができるか → コンパイラ最
適化47
© 2017 IBM Corporation
IBM Research - Tokyo
今日の授業のまとめ
▪ ハードウェアアクセラレータの概要について
– SIMD
– GPGPU
– Hardware transactional memory
–FPGA
▪ プログラミング言語からハードウェアアクセラレータを使う方法とその利点欠点(
SIMDを例に)
– プログラマが命令を書く
–プログラマがライブラリを呼ぶ
– プログラマが書いたプログラムをコンパイラが変換する
▪ 深層学習について
– どのような処理が内部で行われているか
–どのような処理がハードウェアアクセラレータで高速化できるか
– プログラミング処理系として、どのような高速化ができるか
48

20180109 titech lecture_ishizaki_public

  • 1.
    © 2017 IBMCorporation 数理・計算科学特論C プログラミング言語処理系の最先端実装技術 第11講 ハードウェア・アクセラレーション 2018年1月9日 日本アイ・ビー・エム(株) 東京基礎研究所 石崎 一明 kiszk@acm.org (資料作成協力:井上拓、大平怜) IBM Research - Tokyo
  • 2.
    © 2017 IBMCorporation IBM Research - Tokyo 自己紹介 石崎 一明(いしざき かずあき) http://ibm.biz/ishizaki 1992年3月 早稲田大学理工学研究科修士課程電気工学専攻を修了。 1992年4月 日本アイ・ビー・エム(株)入社、東京基礎研究所勤務。以来、並列化コンパイラ、動的 コンパイラ、アプリケーション最適化、などの研究に従事。最近は、GPGPUのためのコンパイル技術 の研究、Apache Sparkの高速化、に従事。現在、同研究所シニア・テクニカル・スタッフ・メンバー 2002年12月 早稲田大学理工学研究科にて、博士(情報科学)を取得。 2008年から2009年まで、IBMワトソン研究所に滞在。 2004年に情報処理学会業績賞受賞。ACMシニアメンバー、情報処理学会シニアメンバー 主なAcademic Activity 2004, 5年 日本ソフトウェア科学会PPL 2004/2005ワークショップ プログラム委員 2006年 日本ソフトウェア科学会PPL 2006ワークショップ プログラム共同委員長 2008年 PC Member of ACM OOPSLA 2013 Conference 2007~2009年度 日本ソフトウェア科学会プログラミング論研究会 運営委員 2011~2014年度 情報処理学会アーキテクチャ研究会 運営委員 2015年~ 日本ソフトウェア科学会理事 2016年度~ 情報処理学会プログラミング研究会 運営委員 2017年 PC Member of IEEE BigData 2017 2
  • 3.
    © 2017 IBMCorporation IBM Research - Tokyo 講義予定のおさらい と 今回のトピック 3 Topic Lecturer Date Time 1 Runtime – JVM Overview & Interpreter 緒方 11/30 木 13:20~14:50 2 Runtime – Object Management & Synchronization 河内谷 12/5 火 13:20~14:50 3 Runtime – Native Memory Management 緒方 12/5 火 15:05~16:35 4 Compiler – Overview 仲池 12/7 木 13:20~14:50 5 Compiler – Dataflow Analysis 稲垣 12/12 火 13:20~14:50 6 Compiler – Devirtualization & Inlining 石崎 12/12 火 15:05~16:35 7 Hot topic – X10 竹内 12/14 木 13:20~14:50 8 Hot topic – Open Source Java VM 堀江 12/19 火 13:20~14:50 9 Hot topic – Full-stack Optimization 堀井 12/19 火 15:05~16:35 10 Compiler – Trace Compilation & LLVM 井上 12/21 木 13:20~14:50 11 Hot topic – H/W Acceleration (GPGPU, HTM, FPGA) 石崎 1/9 火 13:20~14:50 12 まとめと展望 小野寺 1/9 火 15:05~16:35
  • 4.
    © 2017 IBMCorporation IBM Research - Tokyo 今日の講義内容 ▪ ハードウェアアクセラレータ、とは – あるカテゴリの演算を効率よく実行可能 ▪ プログラミング言語からハードウェアアクセラレータを使う方法 – 明示的にハードウェアアクセラレータを制御する命令を呼ぶ –ライブラリを経由してハードウェアアクセラレータを制御する命令を呼ぶ – システムが自動的にハードウェアアクセラレータを制御する命令を呼ぶ ▪ ハードウェアアクセラレータがよく使われる分野の一例 – 深層学習 4
  • 5.
    © 2017 IBMCorporation IBM Research - Tokyo 今日の授業でわかること ▪ ハードウェアアクセラレータの概要について – SIMD – GPGPU – Hardware transactional memory –FPGA ▪ プログラミング言語からハードウェアアクセラレータを使う方法とその利点欠点( SIMDを例に) – プログラマが命令を書く –プログラマがライブラリを呼ぶ – プログラマが書いたプログラムをコンパイラが変換する ▪ 深層学習について – どのような処理が内部で行われているか –どのような処理がハードウェアアクセラレータで高速化できるか – プログラミング処理系として、どのような高速化ができるか 5
  • 6.
    © 2017 IBMCorporation IBM Research - Tokyo ハードウェアアクセラレータとは? 6
  • 7.
    © 2017 IBMCorporation IBM Research - Tokyo ハードウェアアクセラレータ ▪ CPUの汎用命令の組み合わせで処理していたのでは効率が悪い処理を、効 率よく処理するハードウェア – 改善例 • スループットの改善 • レイテンシの改善 • 消費電力効率の改善 – ハードウェア例 • Single Instruction Multiple Data (SIMD) • General Purpose Graphic Processing Unit (GPGPU) • Hardware Transactional Memory (HTM) • Field Programmable Gate Array (FPGA) • 専用ハードウェア –例: GRAvity PiPE (GRAPE) - 重力相互作用の計算 7
  • 8.
    © 2017 IBMCorporation IBM Research - Tokyo SIMD ▪ CPU内で1命令(1つの命令カウンタ)で複数データに同時に同じ処理(2~64 程度)を行う ▪ 多くのプロセッサで実装されている – Intel x86: MMX, SSE, SSE2, SSE3, SSE4, AVX, AVX2, AVX-512 –PowerPC: VMX, VSX – System z – ARM: NEON, NEON28 ベクタレジスタ SIMD命令 A0 A1 A2 A3 B0 B1 B2 B3 C0 C1 C2 C3 add add add add input 1 input 2 output A0 B0 C0 add input 1 input 2 output add gr1,gr2,gr3 vadd vr1,vr2,vr3 scalar instruction SIMD instruction
  • 9.
    © 2017 IBMCorporation IBM Research - Tokyo GPGPU ▪ 数千の実行ユニット(例:CUDA core)で異なるデータに対して同時に命令を実 行し、同じ処理を同時に行う – 条件分岐を処理する場合、条件が成立した実行ユニットと条件が成立しな い実行ユニットで異なる処理を行う –ロードストアは、実行ユニットごとに異なるアドレスからロードストア可能 ▪ 画像処理、密行列演算、などに高い性能を発揮する ▪ GPGPUを製造しているメーカは限られている – NVIDIA、AMD、Intel、など9 Source: https://www.slideshare.net/NVIDIAJapan/nvidia-tesla-v100cuda-9
  • 10.
    © 2017 IBMCorporation IBM Research - Tokyo HTM ▪ ハードウェアで、クリティカルセクションを楽観的に並行実行後、正当性を検査 – 命令の配置 • クリティカルセクションを トランザクション開始・終了命令で囲む –実行時 • トランザクションを同時に実行し メモリ操作が衝突したかを検査。 衝突したら最初から実行し直す – トランザクション中のメモリ操作は1ステップで 行われたかのように他スレッドからは観測される →従来のロックよりも高い並列性が期待される – 正当性検査に、実装からくる制限が存在する ▪ いくつかのプロセッサで実装されている – 2012: Blue Gene/Q, zEC12 – 2013: Intel 4th Generation Core Processor – 2014: IBM POWER8 – 2017: IBM POWER9 10 lock(); a->count++; unlock(); xbegin(); a->count++; xend(); xbegin(); a->count++; xend(); xbegin(); b->count++; xend(); xbegin(); a->count++; xend(); xbegin(); a->count++; xend(); Thread X Thread Y ロック HTM
  • 11.
    © 2017 IBMCorporation IBM Research - Tokyo FPGA ▪ プログラミングによって、内部の論理回路を何度も再構成な半導体デバイス – 一般にCPUより、動作速度が遅い(1GHz程度) ▪ 性能あたりの消費電力を削減できることが多い ▪ FPGAを製造しているメーカは限られている – Xilinx、Altera、など 11
  • 12.
    © 2017 IBMCorporation IBM Research - Tokyo 今日の授業でわかること ▪ ハードウェアアクセラレータの概要について – SIMD → 同じ処理を数十のデータに適用可能 – GPGPU → 同じ処理を数千のデータに適用可能で、異なる処理も一部可能 – Hardware transactional memory → 高い並列性を得ることができる –FPGA → 回路を書き換えることができ、電力当りの処理効率を高めやすい ▪ プログラミング言語からハードウェアアクセラレータを使う方法とその利点欠点( SIMDを例に) – プログラマがSIMD命令を書く –プログラマがライブラリを呼ぶ – プログラマが書いたプログラムをコンパイラが変換する ▪ 深層学習について – どのような処理が内部で行われているか –どのような処理がハードウェアアクセラレータで高速化できるか – プログラミング処理系として、どのような高速化ができるか 12
  • 13.
    © 2017 IBMCorporation IBM Research - Tokyo プログラミング言語から ハードウェアアクセラレータを使うには? 13
  • 14.
    © 2017 IBMCorporation IBM Research - Tokyo 使い方の3つの方法 ▪ 専用命令を使ってプログラミングする ▪ 特定の処理を行うライブラリを呼ぶ – 例:行列積 ▪ 普通にプログラムを書いて、コンパイラが自動的に専用命令を生成する 14
  • 15.
    © 2017 IBMCorporation IBM Research - Tokyo SIMDの専用命令を使ってプログラミング ▪ 命令列を記述する方法 – アセンブラ、gcc/clangのasm文のインラインアセンブラ – gcc/clangの組み込み関数(intrinsic) • gccやclangでは、SIMD用にデータの型が拡張されている • コンパイラが、レジスタ割付けや命令スケジューリングを行ってくれる 15
  • 16.
    © 2017 IBMCorporation IBM Research - Tokyo SIMD組み込み関数によるプログラム例 16 for (i = 0; i < N; i += 8) { __m256i v1 = _mm256_loadu_si256((__m256i *)(a+i)); __m256i v2 = _mm256_loadu_si256((__m256i *)(b+i)); __m256i v3 = _mm256_add_epi32(v1, v2); _mm256_storeu_si256((__m256i *)(c+i), v3); } for (i = 0; i < N; i++) c[i] = a[i] + b[i]; for (i = 0; i < N; i += 4) { vector int v1 = vec_ld(0, a+i); vector int v2 = vec_ld(0, b+i); vector int v3 = vec_add(v1, v2); vec_st(v3, 0, c+i); } 元のスカラループ AVX2用組み込み関数を使った例 VMX用組み込み関数を使った例 8 (= 256 / 32)要素を同時に処理 32-bit整数配列 4 (= 128 / 32)を同時に処理 vec_add() isはSIMDのadd命令に対応する vector int は4つの32-bit整数値を持つ ベクタレジスタ
  • 17.
    © 2017 IBMCorporation IBM Research - Tokyo SIMD組み込み関数でプログラミングする利点欠点 ☺高い性能を得ることができる – このためには、アルゴリズムやデータ配置まで変更することが多い ☺アセンブラで書くよりは、簡単にプログラムを書くことができる – レジスタ割付けや命令スケジューリングは、コンパイラが行う プログラミング、デバッグ、メンテナンスが容易ではない プロセッサ・アーキテクチャに依存したコードとなり、プロセッサ間の移植性が 低い Java、JavaScriptのようなプラットフォーム独立な言語では、あまり適していな い 17
  • 18.
    © 2017 IBMCorporation IBM Research - Tokyo SIMD命令を使うライブラリによるプログラム例 18 // c = αAB + βC を計算する cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, N, N, N, 1.0, A, N, B, N, 0.0, C, N); for (i = 0; i < N; i++) for (j = 0; j < N; j++) for (k = 0; k < N; k++) C[i*N + j] += A[i*N + k] * B[k*N + j]; 元のスカラループ 行列積を計算するライブラリを使った例
  • 19.
    © 2017 IBMCorporation IBM Research - Tokyo SIMD命令を使うライブラリでプログラミングする利点欠点 ☺高い性能を得ることができる – プロセッサメーカーが最適化したライブラリは、プログラマがアセンブラで書 くより性能が高いことがある ☺簡単にプログラムを書くことができる 高速化できる処理が、ライブラリで提供された処理に限られる データ配置などの前提が合わないときは、使用できない。もしくは、データ変換 が必要になる。 19
  • 20.
    © 2017 IBMCorporation IBM Research - Tokyo コンパイラによる自動SIMD命令生成でプログラミング ▪ 自動ベクタ化(automatic vectorization)によって、プログラマが書いたコードか ら、自動的にSIMD命令を生成する ▪ コンパイラは与えられたループを解析して、可能であればSIMD命令を用いる ループを生成する – 可能でない、と判断する主な原因 • ループ間にデータ依存(loop-carried dependence)がある • ループ内に(if文などの)分岐がある場合 • メモリアクセスが、キャッシュ境界からずれている • ループ内に、メソッド呼び出しがある 20
  • 21.
    © 2017 IBMCorporation IBM Research - Tokyo コンパイラによる自動SIMD命令生成のプログラム例 ▪ コンパイラが行う解析 – 入力と出力の配列が、同じメモリアドレスをアクセスしていないか? Loop-carried dependenceの存在確認 – メモリアクセスが、キャッシュ境界からずれていないか? • キャッシュ境界からずれた部分を処理する、非SIMDコードを生成する – ループを繰り返し実行する回数N、はベクタ長の倍数か? • 倍数でない可能性があるときは、端数を処理する非SIMDコードを生成 する 21 元のスカラループ for (i = S; i < E; i++) c[i] = a[i] + b[i];
  • 22.
    © 2017 IBMCorporation IBM Research - Tokyo コンパイラの解析を助ける方法 ▪ アルゴリズムやデータ配置の変更 – アルゴリズム • 例:SOR → Red-black SOR – データ配置 • 例:Array of structs(AOS) → Struct of arrays(SOA) ▪ プログラムの性質の保証 – “restrict” keyword of C99 • ある配列変数が、他の変数とエイリアスしないことを保証する – Pragmaを用いた、SIMDを使用する宣言 22 void func(double *restrict a, double *restrict b, double *restrict c) { /* 配列a[], b[], and c[]はこの関数の中で異なるアドレスであることを保証 */ } #pragma omp simd (OpenMP 4.0) #pragma simd (icc) #pragma disjoint (xlc)
  • 23.
    © 2017 IBMCorporation IBM Research - Tokyo AOSとSOA ▪ データ配置の変更は、非効率な非連続メモリアクセスをなくしたSIMD命令実行 のために、重要であることが多い – コンパイラは、このようなデータ配置の変更は容易ではない 23 y0 z0x0 y1 z1x1 y2 z2x2 y3 z3x3  x0 x1 x2 x3  y4 z4x4 x4 y0 y1 y2 y3 y4 z0 z1 z2 z3 z4  Array of Structures (AOS) Structure of arrays (SOA) y5x5 (4-wayのSIMDを仮定) struct _AOS { double x, y, z; } struct _AOS aos[N]; struct _SOA { double x[N], y[N], z[N]; } struct _SOA soa; x0 x1 x2 x3 x4y0 y1 y2 y3 z0 z1 z2 z3  Hybrid x5 x6 x7 y4 struct _HYBRID { double x[4], y[4], z[4]; } struct _HYBRID hybrid[N/4];
  • 24.
    © 2017 IBMCorporation IBM Research - Tokyo コンパイラによる自動SIMD命令生成でプログラミングする利点欠点 ☺ソースコードをSIMD専用に変更する必要がない SIMD組み込み関数、ライブラリを使った場合ほどの性能向上が得られないこ とが多い 24 [1] Maleki et al. “An Evaluation of Vectorizing Compilers”, PACT 2011 on POWER7 on Nehalem ベンチマークプログラムのSIMD無し実行に対する、平均性能向上比[1] XLC ICC GCC プログラムの変更なしに自動SIMD命令生成 1.66 1.84 1.58 プログラムを手で変換後、自動SIMD命令生成 2.97 2.38 N/A SIMD組み込み関数で記述 3.15 2.45 N/A
  • 25.
    © 2017 IBMCorporation IBM Research - Tokyo Java処理系でのSIMD命令利用方法 ▪ 単純ループのコンパイラによる自動SIMD変換 • 複雑なループも技術的には変換可能だが、動的コンパイラでは時間が かかる解析を行うことは難しい – 行列積、行列ベクトル積を行うループなどは変換可能 –演算対象が一次元のprimitive type配列であること – IBM Java 8、Open JDK 8/9に実装 ▪ Javaクラスライブラリでの活用 – ループ処理が多いライブラリで使用 • java/lang/String, Java/util/Arrays, String encoding converter • IBM Java 8に実装 ▪ SIMD組み込み関数 – Vector APIとして議論中 25 for (int i = 0; i < C.length; i++) { C[i] = A[i] + B[i]; } FloatVector.FloatSpecies<Shapes.S256Bit> species = (FloatVector.FloatSpecies<Shapes.S256Bit>) Vector.speciesInstance(Float.class, Shapes.S_256_BIT); void add(float[] A, float [] B, float [] C) { FloatVector<Shapes.S256Bit> a, b, c; a = species.fromArray(A, 0); b = species.fromArray(B, 0); c = a.add(b); c.intoArray(C, 0); } 元のスカラループ 提案中の組み込み関数を使った例 https://software.intel.com/en-us/articles/vector-api-developer-program-for-java
  • 26.
    © 2017 IBMCorporation IBM Research - Tokyo 使い方の3つの方法のトレードオフ ▪ 専用命令・組み込み関数を使ってプログラミングする ☺性能が高い プログラミングが容易ではない プログラムのポータビリティが低い ▪ 特定の処理を行うライブラリを呼ぶ ☺性能が高い ☺プログラムのポータビリティが高い 予め決められた条件での処理しか高速化されない ▪ コンパイラが専用命令を生成する ☺プログラムのポータビリティが高い 性能がほどほど 変換されるプログラムが限られる 26
  • 27.
    © 2017 IBMCorporation IBM Research - Tokyo GPGPUの利用方法 ▪ 専用命令を使ってプログラミングする – GPGPUメーカーが用意したアセンブリ言語、専用関数でプログラムを書く • PTX(NVIDIA)、GCN(AMD) ▪ 特定の処理を行うライブラリを呼ぶ –cuBLAS、などの行列演算 • プログラマがアセンブラで書くより速いことが多い ▪ 普通にプログラムを書いて、コンパイラが自動的に専用命令を生成する – ホスト-アクセラレータ間の処理などは自分で書く(例:CUDA, OpenCL) –コンパイラが自動でコードを生成する(例:OpenACC, OpenMP) 27 #pragma acc parallel loop for (i = 0; i < N; i++) c[i] = a[i] + b[i]; cudaMalloc(&d_a, N*sizeof(float)); cudaMemcpy(d_a, a, N*sizeof(float), cudaMemcpyHostToDevice) ... add<<GRID, BLOCK>>>(d_a, d_b, d_c); cudaMemcpy(c, d_c, N*sizeof(float), cudaMemcpyDeviceToHost); __global__ void add(float *a, float *b, float *c) { I = blockIdx.x * blockDim.x + threadIdx.x; c[i] = a[i] + b[i];}
  • 28.
    © 2017 IBMCorporation IBM Research - Tokyo Java処理系でのHTMの利用方法 ▪ 特定の処理を行うライブラリを呼ぶ – java.util.concurrentライブラリでの活用 • 複雑なロックフリーアルゴリズムの代わりに、HTMを使用することで実 行パスが単純になり高速化 • IBM Java 8に実装 ▪ 普通にプログラムを書いて、コンパイラが自動的に専用命令を生成する – synchronized block・メソッドの置き換え • synchronized block・メソッドのクリティカルセクションを、HTMで実行す ることで高い並列性が得られる • HTM実行で性能向上が得られない場合は、従来のロックによる実行に 移行 • IBM Java 8、OpenJDKに実装 28
  • 29.
    © 2017 IBMCorporation IBM Research - Tokyo FPGAの利用方法 ▪ 専用命令を使ってプログラミングする – ゲートをGUI・テキストで入力 – 専用のハードウェア記述言語(VHDL、Verilog)で記述 ▪ 特定の処理を行うライブラリを呼ぶ –すでにプログラミングが済んだFPGAを呼び出す • 圧縮、データ処理、ネットワーク処理、など ▪ プログラムを書いて、コンパイラが自動的に専用命令を生成する – C++言語で、ライブラリ・新しい型などを用いてプログラミング(SystemC) • ある程度ハードウェアの知識が必要(信号線専用の変数型、などを利用 している) – ソフトウェアを記述する言語(CやJava)から回路を生成可能 • XILINX社Vivado HLS、など 29
  • 30.
    © 2017 IBMCorporation IBM Research - Tokyo 今日の授業でわかること ▪ ハードウェアアクセラレータの概要について – SIMD – GPGPU – Hardware transactional memory –FPGA ▪ プログラミング言語からハードウェアアクセラレータを使う方法とその利点欠点( SIMDを例に) – プログラマがSIMD命令を書く → 性能は高いが、プログラミングが難しい –プログラマがライブラリを呼ぶ → 性能は高いが、処理が限られる – プログラマが書いたプログラムをコンパイラが変換する → 性能はそこそこだ が、ポータビリティは高い ▪ 深層学習について – どのような処理が内部で行われているか – どのような処理がハードウェアアクセラレータで高速化できるか – プログラミング処理系として、どのような高速化ができるか30
  • 31.
    © 2015 IBMCorporation IBM Research - Tokyo ハードウェアアクセラレータが よく使われる分野の一例 31
  • 32.
    © 2017 IBMCorporation IBM Research - Tokyo 深層学習(Deep Learning) ▪ 2012年の画像認識コンテストにおいて、Deep Learningを使用したアルゴリズ ム(AlexNet)が認識率を大きく改善し、圧倒的な勝利をおさめた ▪ その後、急速にDeep Learningに関する研究が進展し、アルゴリズムの改良と ともに、様々な分野での適用が研究・実用化されている –応用例 • 画像認識 • 機械翻訳 • オンラインショッピングの商品のおすすめ • ゲーム –囲碁、将棋 • 音声認識 • 自動運転 • … 32
  • 33.
    © 2017 IBMCorporation IBM Research - Tokyo 深層学習(Deep Learning)とは? ▪ 層(Layer)をたくさん(多いものは100以上)重ねたニューラルネットワーク – あるデータを入力すると、正解に近い出力を生成する(推論・Inference) – 推論をよりよいものにするためには、多くのデータを入力して、正解に近い 出力を生成するように学習する必要がある(学習・Training) • 学習=重みの更新 ▪ 層の各点では、矢印が持つ重みを用いて計算を行う – 推論の例 33 魚 0.95 鳥 0.05 層 層 層 層 重み 重み 重み
  • 34.
    © 2017 IBMCorporation IBM Research - Tokyo 画像を認識するニューラルネットの例 ▪ LeNet [Yann98]: 0~9の手書き文字の入力の認識 – データに、5x5のフィルタを適用し特徴を抽出した後、データの大きさを減らす • 学習すると、フィルタの値が更新される – 全結合層で1次元のベクタに変換する –最後の層で、0-9に関する確率分布に変換する 34 0 0.01 … 6 0.002 7 0.91 8 0.003 9 0.05 畳み込み 活性化 層 32x32 5x5 28x28を 6種類 プー リング 層 14x14を 6種類 10x10を 16種類 5x5を 16種類5x5 1x120 1x84 1x10 全結合畳み込み 活性化 プー リング 全結合 全結合
  • 35.
    © 2017 IBMCorporation IBM Research - Tokyo 層で行う処理は、何を行っているか? ▪ 畳み込み(Convolution) – 入力データとフィルタで行列の内積を求める ▪ 活性化関数(Activation function) – Tanh:ハイパボリックタンジェント – ReLU: 値が0以下であれば0,それ以外は入力値を取る • 最近はReLUが使われることが多い ▪ プーリング関数(Pooling) – MaxPooling: 近傍(例えば2x2)の最大値を取る 35 0 1 1 0 0 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 -1 1 -1 1 0 1 -1 1 -1 = 0x-1 + 1x1 + 1x-1 + 1x1 + 0x0 + 1x1 + 1x-1 + 1x1 + 1x-1 = 1 1 0 -1 0 1 1 -1 0 1 入力データ フィルタ 0 1 1 0 0 0 1 1 1 1 0 1 -1 -1 2 1 -1 1 1 0 0 0 1 1 0 0 1 1 0 0 2 1 0 1 1 1 2 1 ReLU MaxPooling
  • 36.
    © 2017 IBMCorporation IBM Research - Tokyo 層で行う処理は、何を行っているか? ▪ 全結合(Full connection) – 行列ベクトル積を求める 36 0 1 0 0 1 1 1 0 0 0 1 0 1 1 2 0 2 入力データ 重み 0 11 1 0 1 1 0 1 0 1 0 1 1 1 0 1 1x0 + 1x1 + 0x0 + 1x0 + 1x1 + 0x0 = 2
  • 37.
    © 2017 IBMCorporation IBM Research - Tokyo 各処理はどのように記述できるか? ▪ Convolution – 4重ループで、外側2重は並列実行、内側2重は積和演算でリダクション実行可能 ▪ ReLU – 並列実行可能な2重ループで、max()を実行 37 parfor (yo = 0, yi = 1; yi < height-1; yi++, yo++) { parfor (xo = 0, xi = 1; xi < width-1; xi++, xo++) { reducefor (yf = 0; yf < filterHeight; yf++) { reducefor (xf = 0; xf < filterWidth; xf++) { output1[yo][xo] += input[yi + yf – 1][xi + xf – 1] * filter[yf][xf]; }}}} parfor (yi = 0; yi < height; yi++) { parfor (xi = 0; xi < width; xi++) { output2[yi][xi] = max(0, output1[yi][xi]); }} ※実際には、さらに計算量とデータの再利用を増やす変換が行われています(バッチ化)
  • 38.
    © 2017 IBMCorporation IBM Research - Tokyo 各処理はどのように記述できるか? ▪ MaxPooling – 4重ループで、外側2重は並列実行、内側2重は最大値を求めるリダクション実行可能 ▪ Full connection – 2重ループで、外側は並列実行、内側は積和演算でリダクション実行可能 38 parfor (yo = 0; yo < height; yo++) { reducefor (xf = 0; xf < weightWidth; yf++) { output[yo] += weight[yo][xf] * input[xf]; }} ※実際には、さらに計算量とデータの再利用を増やす変換が行われています(バッチ化) parfor (yi = 0, yo = 0; yi < height; yi += poolHeight, yo++) { parfor (xi = 0, xo = 0; xi < width; xi += poolWidth, xo++) { reducefor (maxval = -INF, yp = 0; yp < poolHeight; yp++) { reducefor (xp = 0; xp < poolWidth; xp++) { maxval = max(output2[yi+yp][xi+xp], maxval); }} output3[yo][xo] = maxval; }}
  • 39.
    © 2017 IBMCorporation IBM Research - Tokyo ハードウェアアクセラレータとの親和性 ▪ Convolution – 4重ループで、外側2重は並列実行、内側2重は積和演算でリダクション実行可能 ▪ ReLu – 並列実行可能な2重ループで、max()を実行 ▪ MaxPooling – 4重ループで、外側2重は並列実行、内側2重は最大値を求めるリダクション実行可能 ▪ Full connection – 2重ループで、外側は並列実行、内側は積和演算でリダクション実行可能 39 比較的決まった処理で、並列処理が多いので ハードウェアアクセラレータ向き 特に、計算量の多いConvolutionを高速化したい
  • 40.
    © 2017 IBMCorporation IBM Research - Tokyo どんなハードウェアアクセラレータが使われている? ▪ SIMD – 行列演算の高速化は得意 ▪ GPGPU – NVIDIAのVoltaは、16bit浮動小数点行列演算専用回路を搭載 ▪ Deep Learning専用プロセッサ – Tensor Processing Unit2 (TPU2), (Google) • 低精度浮動小数点行列演算とactivation functionを高速に実行する – Nervana (Intel) –Lightspeeur 2810S (Gyrfalcon technology) – など 40
  • 41.
    © 2017 IBMCorporation IBM Research - Tokyo ニューラルネットを記述して、実行する方法は? ▪ 深層学習用のフレームワークを用いて、ニューラルネットを記述する – Caffe (UC Berkley), http://caffe.berkeleyvision.org/ – TensorFlow (Google), https://www.tensorflow.org/ – PyTorch (Facebook), http://pytorch.org/ –Chainer (PFN), https://chainer.org/ – MXNet (U of Washington, CMU, Amazon), https://mxnet.incubator.apache.org/ – NNabla (Sony), https://nnabla.org/ –などなど ▪ これらのフレームワークは、ハードウェアアクセラレータが用意している専用ラ イブラリを呼ぶ – Convolution、などの代表的な演算を高速化するライブラリ • cuDNN by NVIDIA • Math Kernel Library for Deep Neural Networks (MKL-DNN) by Intel 41
  • 42.
    © 2017 IBMCorporation IBM Research - Tokyo さらに高速化できないか? ▪ フレームワークで書かれたニューラルネットワーク構造は、プログラムとみなす ことができる – フレームワークによっては、Pythonで記述する ▪ 専用コンパイラで最適化を適用してコンパイルして、アクセラレータ命令を呼ぶ コードを生成することで高速化を図る – TensorFlow XLA – TVM/NNVM – PraidML – PyTorch42 import tensorflow as tf with tf.name_scope('conv1'): w_tensor = tf.variable(...) b_tensor = tf.variable(...) c_tensor = tf.nn.conv2d(x_image, w_tensor, strides=...) t_tensor = c_tensor + b_tensor h_tensor = tf.nn.relu(t_tensor)
  • 43.
    © 2017 IBMCorporation IBM Research - Tokyo TensorFlow XLA 43 Source: https://autodiff-workshop.github.io/slides/JeffDean.pdf ▪ HLO: 命令融合、共通式削除、などを行う ▪ LLO: 対象のアーキテクチャ独自の最適化を行う(実装はLLVMを使っている) ▪ Executor API: 各処理(例:conv2d, ReLU)を実行する
  • 44.
    © 2017 IBMCorporation IBM Research - Tokyo NNVM/TVM ▪ NNVM: グラフ上での最適化を行う – ノードの融合、など ▪ TVM: Tensorに関する最適化を行う – Tensor計算の融合、など 44 Source: http://www.tvmlang.org/2017/10/06/nnvm-compiler-announcement.html
  • 45.
    © 2017 IBMCorporation IBM Research - Tokyo 最後におまけ ▪ AIやDeep Learningが流行って、言語処理の研究分野は廃れていくのか? 45
  • 46.
    © 2017 IBMCorporation IBM Research - Tokyo 最後におまけ ▪ AIやDeep Learningが流行って、言語処理の研究分野は廃れていくのか? – そんなことはないです。 “言語処理系屋さん”、”コンパイラ屋さん”、には”需要”があります。 その時代に重要なワークロードがあれば、それを高速化する命令やアクセ ラレータが開発されるでしょう。 使う人の裾野が広がれば、生産性を高めるための専用言語やフレームワ ークが開発されます。 そして、人はわがままなので、生産性を高めるだけでなく高速化したい、と 言い出します。 こういう要求によりよく答えるために、言語設計や最適化コンパイラの研究 は続いていくと思っています。 46
  • 47.
    © 2017 IBMCorporation IBM Research - Tokyo 今日の授業でわかること ▪ ハードウェアアクセラレータの概要について – SIMD – GPGPU – Hardware transactional memory –FPGA ▪ プログラミング言語からハードウェアアクセラレータを使う方法とその利点欠点 – プログラマがSIMD命令を書く – プログラマがライブラリを呼ぶ –プログラマが書いたプログラムをコンパイラが変換する ▪ 深層学習について – どのような処理が内部で行われているか → 行列演算 – どのような処理がハードウェアアクセラレータで高速化できるか → 浮動小数 点の行列演算 – プログラミング処理系として、どのような高速化ができるか → コンパイラ最 適化47
  • 48.
    © 2017 IBMCorporation IBM Research - Tokyo 今日の授業のまとめ ▪ ハードウェアアクセラレータの概要について – SIMD – GPGPU – Hardware transactional memory –FPGA ▪ プログラミング言語からハードウェアアクセラレータを使う方法とその利点欠点( SIMDを例に) – プログラマが命令を書く –プログラマがライブラリを呼ぶ – プログラマが書いたプログラムをコンパイラが変換する ▪ 深層学習について – どのような処理が内部で行われているか –どのような処理がハードウェアアクセラレータで高速化できるか – プログラミング処理系として、どのような高速化ができるか 48