SlideShare a Scribd company logo
1 of 128
CPU GPU
Ultimate CGRA w/ high-speed compiler
CGRA for Energy-efficient Cryptography
Beyond-Neuromorphic Systems
Non-Deterministic Computing
20210401
1
ナレータ VOICEVOX:もち子(cv 明日葉よもぎ)
はらぺこエンジニアに贈るCGRAの世界2022
(ダイジェスト版)
スパコンからIoTまで 省エネ社会に
AI+BCだけじゃない超効率計算手法
20210401
2
20180716 2
電力需要の60%が情報機器
実効為替レートが低下し
CPU/GPUが買えない未来
AIもクラウドもスパコンも
増やせない未来
CO2が減らないSociety 5.0
電力需要の10%が情報機器
非ノイマン型を
自給・輸出する未来
身の丈に合ったAIとスパコン
と電力消費
低炭素社会
202X年 ノイマン型の段階的削減!?
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8 80-loops
ALUALU
I-Cache
ALU
ALU
D-Cache
Registers
I-Cache
ALU
ALU
D-Cache
Regs.
Regs.
D-Cache
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
All
instructions
are
executed.
I-Cache
ALU
ALU
D-Cache
Registers
3
Vect.Insn.1
Vect.Insn.2
Vect.Insn.3
Vect.Insn.4
Vect.Insn.5
Vect.Insn.6
Vect.Insn.7
Vect.Insn.8
Vector
Registers
Register
File
20210401
3
ノイマン型(ぬるま湯)を捨て、非ノイマン型土俵で頭を使えということ
"GoogleのTPUにも使われたシストリックアレイアー
キテクチャとDeep Learningについて", 富士通研究
所技術講演会, Jul. (2017)
"プログラマビリティを維持できる限界に向けて”,
SONY本社研究紹介, Mar. (2020)
"Deep Learningに向けたApproximate Computingと
シストリックアレイアーキテクチャ", 革新的コン
ピューティングの研究開発戦略検討会, CRDS/JST,
Jul. (2017)
"Approximate Computingとシストリックアレイ", ジス
クソフト技術講演会, Dec. (2017)
"99%メモリなアクセラレータIMAX(In Memory
Accelerator eXtension)", CAE計算環境研究会@関
西シスラボ 第8回シンポジウム, Mar. (2017)
"Systolic Arrays as The Last Frontiers", Invited
talk in IPB Seminar and UI seminar @ Indonesia,
Jan. (2019)
“IMAX2: A CGRA with FPU+Multithreading+Chiplet",
Panel: CGRA and their Opportunities as Application
Accelerators, ASAP2021, invited panel, Jul. (2021)
“コンピュータ(データセンタ)の消費電力低減策
意見交換会”, LCS/JST, Jul. (2021)
"非ノイマン型の世界 -CGRAを含む最近の研究紹
介-", JEITAデバイス技術分科会招待講演, Nov.
(2021)
"CGRAのJITコンパイル化と高機能化の魔法教え
ます", 回路とシステムワークショップ招待講演, Aug.
(2022)
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
for {
iter=0 iter=1 iter=2 iter=3 iter=4 iter=5 iter=6 iter=7
}
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Super Scalar, VLIW
I-Cache
ALU
ALU
D-Cache
Registers
EAG EAG
20210401
4
for {
iter=0 iter=1 iter=2 iter=3 iter=4 iter=5 iter=6 iter=7
}
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
VECTOR
Insn.1 Insn.1 Insn.1 Insn.1 Insn.1 Insn.1 Insn.1
Insn.1
I-Cache
ALU
ALU
D-Cache / Main Memory
Registers
EAG
V-insn.1
ALU
ALU
ALU
ALU
ALU
ALU
V-insn.2
Insn.2 Insn.2 Insn.2 Insn.2 Insn.2 Insn.2 Insn.2
Insn.2
20210401
5
for {
iter=0 iter=1 iter=2 iter=3 iter=4 iter=5 iter=6 iter=7
}
CGRA
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Insn.1
Insn.2
Insn.3
Insn.4
Insn.5
Insn.6
Insn.7
Insn.8
Local Memory
Registers EAG
ALU
ALU
Local Memory
Registers EAG
ALU
ALU
Local Memory
Registers EAG
ALU
ALU
Local Memory
Registers EAG
ALU
ALU
Insn.1 Insn.2
Insn.3 Insn.4
Insn.1 Insn.2 Insn.1 Insn.2
Insn.5 Insn.6
Insn.3 Insn.4
Insn.1 Insn.2
Insn.3 Insn.4
Insn.1 Insn.2 Insn.1 Insn.2
Insn.7 Insn.8
Insn.5 Insn.6
Insn.3 Insn.4
Insn.1 Insn.2
Insn.5 Insn.6
Insn.3 Insn.4
Insn.1 Insn.2
Insn.3 Insn.4
Insn.1 Insn.2 Insn.1 Insn.2
20210401
6
20210401
7
Scalar, SIMD and CGRA
time
I1
L2
VST
L2
VLD VLD
VFMA
I1
L2
VST
L2
VLD VLD
VFMA
I1
L2
VST
L2
VLD VLD
VFMA
I1
L2
VST
L2
VLD VLD
VFMA
MM
LD LM MM
LD LM FMA LM
ST LD LM LD LM FMA LM
ST
LD LM MM
LD LM FMA LM
ST LD LM LD LM FMA LM
ST
LD LM MM
LD LM FMA LM
ST LD LM LD LM FMA LM
ST
LD LM MM
LD LM FMA LM
ST LD LM LD LM FMA LM
ST
LD LD FMA ST
D1 D1 D1
I1 I1 I1
L2
L2
LD LD FMA ST
D1 D1 D1
I1 I1 I1
L2
L2
LD LD FMA ST
D1 D1 D1
I1 I1 I1
L2
L2
LD LD FMA ST
D1 D1 D1
I1 I1 I1
L2
L2
LD LD FMA ST
D1 D1 D1
I1 I1 I1
L2
L2
LD LD FMA ST
D1 D1 D1
I1 I1 I1
L2
L2
LD LD FMA ST
D1 D1 D1
I1 I1 I1
L2
L2
LD LD FMA ST
D1 D1 D1
I1 I1 I1
L2
L2
MM
I1
I1
I1
I1
VST
VST
VST
VST
VFMA
VFMA
VFMA
VFMA
VLD
VLD
VLD
VLD
VLD
VLD
VLD
VLD
MM
Scalar
(VL=32)
Vector1
(VL=256)
Vector2
(VL=2048)
CGRA
(VL=16K)
20210401
8
従来のプログラムは手順を書く
A B C
D
for (i=0; i<128; i++)
D[i]=A[i]+B[i]*C[i];
D[256] A[256] B[256] C[256]
float A[256],B[256],C[256],D[256];
for (i=0; i<128; i++)
D[i+128]=A[i+128]+B[i]*C[i+128];
Main memory
D A B C B
D A C
20210401
9
キャッシュメモリが頑張る
A B C
D
for (i=0; i<128; i++)
D[i]=A[i]+B[i]*C[i];
D[256] A[256] B[256] C[256]
for (i=0; i<128; i++)
D[i+128]=A[i+128]+B[i]*C[i+128];
Main memory
Cache memory
20210401
10
データフローを書くと明示的に分散配置できる
D
A B C
D
A B C
D
A B C
Load Ai (top=A,len=64)
Load Bi (top=B,len=64)
Load Ci (top=C,len=64)
Di=Ai+Bi*Ci
Store Di (top=D,len=64)
Similar to assembly language, but has DMA info.
j=i+64; Load Aj (top=A+64,len=64)
Load Bi (top=B, len=64)
Load Cj (top=C+64,len=64)
Dj=Aj+Bi*Cj
Store Dj (top=D+64,len=64)
k=i+128;Load Ak (top=A+128,len=64)
Load Bi (top=B, len=64)
Load Ck (top=C+128,len=64)
Dk=Ak+Bi*Ck
Store Dk (top=D+128,len=64)
Can broadcast
1988 VPP 4way VLIW+8elem. Vector
My CGRAs began from VLIW+Vector processor
F D W
C
D
M M M M
M M M M D D M M M M
Load pipe Store pipe
FPU pipe
F D
F D
Cache lines are shared among
heterogeneous multithreads.
M M M M M M M M
D
W
M M M M M M M M
M M M M M M M M
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
E
C
E
E
E
E
M M M M
B
B
B
B
B
B
B
B
B
B
Vector Length
≤ 2048 dwords
($miss)
F D D
2008 LAPP 8way VLIW+32stage Array
C2
E
E
E
LD
M M M M
C1
E
E
E
LD
C0
E
E
E
E
B
B
B
B
B
C3
E
E
E
E
HW Mapper (8stages) HW Mapper (binary compatible)
Vector Length
≤ 1024 words
E
E
E
E
E
E
E
ST
E
E
E
LD
E
E
E
LD
E
E
E
E
E
E
E
ST
2006 OROCHI 9way VLIW+5way SS
20210401
11
Data from all cache ways are passed through array.
Location free LD/ST can keep binary compatibility.
ただし、ノイマン型に学ばない非ノイマン型には、汎用性も未来もない
20210401
12
例えば、FPGAを真似ただけのCGRAは、コンパイルに1時間
これをコンピュータと呼ぶのは無理がある
プログラムやデータの変換に長時間がかかる
新原理非ノイマン型に存在価値はない
Start of IMAX
20210401
13
CPUのレジスタファイルに該当
(32bit x 2waySIMD = 64bit幅)
CPUの条件判定器、
浮動小数点パイプライン演算器、
(32bit x 2wayFMA = 64bit幅)
SAD等メディア演算、
32要素確率的積和演算、
SHA256用ハッシュ計算、
アドレス生成器に該当
CPUのローカルメモリに該当
(64KB)
CPUのレジスタファイルに該当
ノイマン型に学ばない非ノ
イマン型には、汎用性も未
来もない。
CPUから始めることで、類
似の汎用性を自然に獲得。
4列⇒1列に重畳
20210401
14
4列分のダブルバッファ・
レジスタファイル
4列分をマルチスレッド実行
メモリ空間を最大4分割
(64KB, 32KB, 16KB, 混在)
4列分のダブルバッファ・
レジスタファイル
大部分のCGRAは、浮動小
数点演算器を搭載しない。
浮動小数点累算が、CGRA
のパイプライン動作を止め
てしまうから。
そこで、マルチスレッディン
グの知恵を借りた。
あとで、汎用性向上に役立
つことになる。
Slave型外部IF
20210401
15
演算しながら、次データを
4列分の空間へ自律的受信
256bit/cycle
演算しながら、
HOSTの読み出しDMAに対し、
自律的に読み出し合流
256bit/cycle
次のUNITへ
豪華な外部メモリIFは、大
電力消費の主犯。
貧弱なメモリIFでも高性能
を出せるように頭を使う。
Slave型かつ自律アドレス
フィルタにより、ブロード
キャストやギャザを自然に
実現。
データ入れ替えはコンパイ
ラが判断し最適化。
20210401
16
Folding機能
CPUの通常データパスに該当
20210401
17
Dual port導入
8ワードロードx4、2ワードロードx8、
2ワードロードx4⇒演算x4⇒ストアx4
を収容
メモリ空間は最大4分割
ダブルバッファとしても利用
20210401
18
伝搬レジスタ
物理4本、論理16本の
UNIT間バイパスによる
データ伝搬
20210401
19
アドレス同調機構
疎行列の圧縮、
圧縮済疎行列どうしの行列積、
マージソートに対応
40ops/1unit, 2560ops/64units, 10240ops/4chips
20210401
20
load store
octa-ld
Add/sub/mul
And/or/xor
Shift
+FPU
+Media
octa-ld
Add/sub/mul
And/or/xor
Shift
+FPU
+Media
For
1st column
Double buffer
for write
for read
20210401
21
For
2nd column
load store
octa-ld
Add/sub/mul
And/or/xor
Shift
+FPU
+Media
octa-ld
Add/sub/mul
And/or/xor
Shift
+FPU
+Media
Double buffer
for write
for read
40ops/1unit, 2560ops/64units, 10240ops/4chips
20210401
22
For
3rd column
load store
octa-ld
Add/sub/mul
And/or/xor
Shift
+FPU
+Media
octa-ld
Add/sub/mul
And/or/xor
Shift
+FPU
+Media
Double buffer
for write
for read
40ops/1unit, 2560ops/64units, 10240ops/4chips
20210401
23
For
4th column
load store
octa-ld
Add/sub/mul
And/or/xor
Shift
+FPU
+Media
octa-ld
Add/sub/mul
And/or/xor
Shift
+FPU
+Media
Double buffer
for write
for read
40ops/1unit, 2560ops/64units, 10240ops/4chips
ノイマン型に学んだ論理UNITを並べていく
20210401
24
F F A A
F F A A
F F M M
C C M M
R R R R
R
論理UNITを4つ並べる、最後には、これが1基の物理UNITになる
20210401
25
R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
さらに縦に並べて全体のデータ流は上から下へ
20210401
26
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
さらにマルチチップ拡張として、横に増やす
20210401
27
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
ここで、論理4UNITを物理1UNITに重畳
20210401
28
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
演算位置とローカルメモリ位置の同調制御のため、リング構造化
20210401
29
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
F F A A
F F A A
F F M M
C C M M
R R R R
A
B
C
D
E
A
B
C
D
E
A
B
C
D
E
物理64UNITx4を基本構造としてプログラム(最大2560オペレーション)
64bit
ARM
AXIIF
2560op x 4
64KB x 64 x 4
20210401
30
メモリバスに応じて並列接続、この図では8万オペレーションを写像
A B
C
D
E
H
B
M
2
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
A B
C
D
E
2560op x 32 = 81920op
20210401
31
HOST
20210401
32
演算ネットワークとメモリネットワーク
演算器はリング構造 メモリネットワークは8並列
20210401
33
論理的プログラミングモデルは4列 ⇒ 物理構造は1列
20210401
34
非ノイマン型で重要なのは、演算器を並べることではない
書き込み後にロード or 書き込みながらロード
20210401
35
いかに、データフローを途切れなく埋め込むか
ストア後に読み出す or ストアしながら読み出す
20210401
36
CGRA的パイプライン処理に加え、上位のパイプライン処理も重要
LogN個のUNITを使い、
O(N)のマージソート
O(N)のFFT
結果をストアしながら、前回結果を読み出す(double buffering)
20210401
37
外部メモリとも協調させ、途切れないデータフローを作る
C
O
N
F
R
E
G
s
A
D
D
R
Overlapping post-drain, burst-exec, pre-fetch
L
M
M
L
M
M
L
M
M
Burst exec.
R
E
G
s
A
D
D
R
L
M
M
L
M
M
L
M
M
Burst exec.
C
O
N
F
A
D
D
R
R
E
G
s
Sequential execution
L
M
M
L
M
M
L
M
M
Burst exec. A
D
D
R
R
E
G
s
L
M
M
time
L
M
M
L
M
M
Burst exec.
PIO/DMA External Memory
PIO/DMA External Memory
R
E
G
s
A
D
D
R
L
M
M
L
M
M
L
M
M
Burst exec.
演算器とローカルメモリのサンドイッチ構造により様々な応用
More complicated memory access for light field, graph, string search, AI, …
20210401
38
39
・中島康彦, 木村睦, 張任遠: "制御装置(スパイクメモリ構成方法)", 特願2021- 27859 (2021. 2. 24)
・トランティホン, 中島康彦: "処理要素、その制御方法および制御プログラム、並びに処理装置(BC)", 特願2021-009164 (2021. 1. 22)
・中島康彦, 高前田伸也: "データ処理装置(メモリ内蔵アクセラレータの構成方法)", 中国ZL201680019602 (2020. 12. 11)
・中島康彦: "データ処理装置(高効率アクセラレータ構成方法)", PCT/JP2020/025123 (2020. 6. 26)
・中島康彦, 木村睦, 張任遠: "データ処理装置(メムキャパシタ構成方法)", 特願2020-91392 (2020. 5. 26)
・中島康彦: "データ処理装置(高効率アクセラレータ構成方法)", 特願2019-517698 (2019. 9. 19)
・Yasuhiko Nakashima, Shinya Takamaeda: "Data processing Device", United States Patent 10,275,392 (2019.4.30)
・中島康彦: "データ処理装置(NCHIP制御方法)", 特願2019-121853 (2019. 6. 28)
・Yasuhiko Nakashima, Takashi Nakada: "Data processing Device for Performing a Plurality of Calculation Processes in Parallel", European Patent Application No.09820420.9 (H31. 1. 18)
・中島康彦: "データ処理装置(高効率アクセラレータ構成方法)", PCT/JP2018/018169 (H30. 5. 10)
・中島康彦: "データ処理装置(高効率アクセラレータ構成方法)", 特願2017-96061 (H29. 5. 12)
・Jun Yao, Yasuhiko Nakashima, Tao Wang, Wei Zhang, Zuqi Liu, Shuzhan Bi: "METHOD FOR ACCESSING MEMORY OF MULTI-CORE SYSTEM, RELATED APPARATUS, SYSTEM, AND STORAGE MEDIUM",
PCT/CN2017/083523 (2017. 5. 8)
・中島康彦, 高前田伸也: "データ処理装置(メモリ内蔵アクセラレータの構成方法)", PCT/JP2016/061302 (H28. 4. 6)
・中島康彦, 高前田伸也: "データ処理装置(メモリ内蔵アクセラレータの構成方法)", 特願2015-079552 (H27. 4. 8)
・中島康彦: "エミュレーション方式", 特願2013-055660 (H25. 3. 18)
・中島康彦, 姚駿: "データ供給装置及びデータ処理装置", PCT/JP2013/057503 (H25. 3. 15)
・中島康彦, 姚駿: "データ供給装置及びデータ処理装置", 特願2012-061110 (H24. 3. 16)
20210401
39
28nmLSI : 200x performance/area compared with GPGPU
現有最大規模のプロトタイプは10240オペレーション
20210401
40
各種GPUとの比較
Kernel
CPU
ARMv8 1.2GHz
GPU 256core
JetsonTX2 1.3GHz
DDR4 480Gbps
16nm 43.6mm²
CGRA 64core*4
IMAX2 140MHz
DDR4 40Gbps
[28nm想定 14.6mm² *4]
8nm想定 1.2mm² *4
GPU 3584core
GTX1080Ti 1.5GHz
GDDR5 3872Gbps
16nm 471mm²
GPU 10496core
RTX3090 1.4GHz
GDDR6X 7490Gbps
8nm 628mm²
DDR bandwidth 12 1 97 187
Power 7.5W ARM 0.6W + [31W] 2.7W 250W 350W
MM 3160msec 170 16 [3msec]
[EDP=284] EDP=30
12
EDP=36K
1.2
EDP=504
CNN 2080msec
280
EDP=588K
23 [4msec]
[EDP=505] EDP=53
18
EDP=81K
2.9
EDP=2943
Lightfield 14500msec
1190
EDP=10.6M
754 [126msec]
[EDP=501K] EDP=52K
43
EDP=462K
35
EDP=428K
Sparse
MM 32002 - - 333+469 [134ms]
[EDP=567K] EDP=59K
Cusparse使用
2044
EDP=1045M
Cusparse使用
280
EDP=27.4M
Sparse
MM 40002 - - 2378+734 [519ms]
[EDP=8.51M] EDP=889K
Cusparse使用
3492
EDP=3049M
Cusparse使用
350
EDP=43.1M
Top-down approach
20210401
41
HBM2
HOST HOST
I/O I/O
FFT CONV
MM SORT SpMM
Multilevel pipelining
20210401
42
HBM2
20210401
43
レイアウトはこんな感じ
CGRA 64core*4
IMAX2 140MHz
DDR4 40Gbps
8nm想定 1.2mm² *4
GPU 10496core
RTX3090 1.4GHz
GDDR6X 7490Gbps
8nm 628mm²
75%がDP-SRAM https://thinkcomputers.org/renowned-ir-photographer-fritzchens-fritz-
shares-die-shots-of-nvidia-3000-series-ga-102-silicon/
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAMLogic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
DP
SRAM
Logic
External interface
DP
SRAM
IMAX (64units) x 120 modules = 307200 operations / 4 cycles
20210401
44
HBM2
HOST HOST
IMAX (1.2mm2/8nm) x 120 modules ≃ 144mm2 ?
CPU GPU
Ultimate CGRA w/ high-speed compiler
CGRA for Energy-efficient Cryptography
Beyond-Neuromorphic Systems
Non-Deterministic Computing
20210401
45
ナレータ VOICEVOX:もち子(cv 明日葉よもぎ)
はらぺこエンジニアに贈るCGRAの世界2022
(画像フィルタ)
スパコンからIoTまで 省エネ社会に
AI+BCだけじゃない超効率計算手法
/* SCREEN=WD*HT */
for (row=0; row<HT; row++) {
for (col=0; col<WD; col++) {
pix = in[row*WD+col];
r = t[ pix>>24 ];
g = t[256+((pix>>16)&255)];
b = t[512+((pix>> 8)&255)];
out[row*WD+col]=r<<24 | g<<16 | b<<8;
} }
20210401
46
簡単な tone_curveをC言語で書く
Load →
Store ←
Color map tables
int loop=WD/2;
//EMAX5A begin tone_curve mapdist=0
while (loop--) {
mop(OP_LDR, &BR[0][1][1], in++, 0LL, MSK_D0, in, WD, 0, 0, NULL, 0);
mop(OP_LDBR, &BR[1][1][1], t1, BR[0][1][1], MSK_B3, t, 256*3/4, 0, 0, NULL, 0);
mop(OP_LDBR, &BR[1][1][0], t1, BR[0][1][1], MSK_B7, t, 256*3/4, 0, 0, NULL, 0);
mop(OP_LDBR, &BR[1][2][1], t2, BR[0][1][1], MSK_B2, t, 256*3/4, 0, 0, NULL, 0);
mop(OP_LDBR, &BR[1][2][0], t2, BR[0][1][1], MSK_B6, t, 256*3/4, 0, 0, NULL, 0);
mop(OP_LDBR, &BR[1][3][1], t3, BR[0][1][1], MSK_B1, t, 256*3/4, 0, 0, NULL, 0);
mop(OP_LDBR, &BR[1][3][0], t3, BR[0][1][1], MSK_B5, t, 256*3/4, 0, 0, NULL, 0);
exe(OP_CCAT, &r1, BR[1][1][0], EXP_H3210, BR[1][1][1], EXP_H3210, 0, EXP_H3210,OP_NOP,0,OP_NOP,0);
exe(OP_CCAT, &r2, BR[1][2][0], EXP_H3210, BR[1][2][1], EXP_H3210, 0, EXP_H3210,OP_NOP,0,OP_NOP,0);
exe(OP_CCAT, &r3, BR[1][3][0], EXP_H3210, BR[1][3][1], EXP_H3210, 0, EXP_H3210,OP_NOP,0,OP_NOP,0);
exe(OP_MMRG, &r0, r1, EXP_H3210, r2, EXP_H3210, r3, EXP_H3210,OP_NOP,0,OP_NOP,0);
mop(OP_STR, &r0, out++, 0LL, MSK_D0, out, WD, 0, 0, NULL, 0);
}
//EMAX5A end
20210401
47
2way SIMD版
SIMD Load →
SIMD Store ←
Color map tables
20210401
48
2way SIMD版
CCATが増えた
ロード数が3から6に増えた
Input
pixels
Load
Sort
Select center
Output
4bytes
4bytes
20210401
49
メディアンフィルタを超高速実行する
20210401
50
演算だけ並べても意味がないと言ったことの意味
LM
LM
LM
LM
Main
Memory
PREFETCH
DRAIN
LM
LM
20210401
51
コンパイル結果
①
⑮
④
②
③
⑤
⑥
⑦
⑧
⑨
⑩
⑪
⑫
⑬
⑭
⑯
LM
LM
LM
LM
PREFETCH
LM
LM
DRAIN
20210401
52
メディアンフィルタよりも簡単なアンシャープマスク
for (row=0; row<HT; row++) {
//EMAX5A begin unsharp mapdist=1
for (CHIP=0; CHIP<NCHIP; CHIP++) { /* output channels are parallelized by multi-chip (OC/#chip) */
for (INIT0=1,LOOP0=WD,col=0-4LL; LOOP0--; INIT0=0) {
exe(OP_ADD, &col, col, EXP_H3210, 4LL, EXP_H3210, 0, EXP_H3210, OP_AND, 0x00000ffffffffLL, OP_NOP,0);
exe(OP_ADD, &in_center, row_center, EXP_H3210, col, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
mop(OP_LDWR, &r1, in_center, -1276, MSK_D0, row_prev, WD, NULL, 0);
mop(OP_LDWR, &r2, in_center, -1284, MSK_D0, row_prev, WD, NULL, 0);
mop(OP_LDWR, &r5, in_center, -1280, MSK_D0, row_prev, WD, NULL, 0);
exe(OP_MAUH, &r11, r1, EXP_B5410, r2, EXP_B5410, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MAUH, &r12, r1, EXP_B7632, r2, EXP_B7632, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
mop(OP_LDWR, &r6, in_center, 4, MSK_D0, row_center, WD, NULL, 0);
mop(OP_LDWR, &r7, in_center, -4, MSK_D0, row_center, WD, NULL, 0);
mop(OP_LDWR, &r0, in_center, 0, MSK_D0, row_center, WD, NULL, 0);
exe(OP_MLUH, &r20, r0, EXP_B5410, 239, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MLUH, &r21, r0, EXP_B7632, 239, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
mop(OP_LDWR, &r3, in_center, 1284, MSK_D0, row_next, WD, row_next_next, WD);
mop(OP_LDWR, &r4, in_center, 1276, MSK_D0, row_next, WD, row_next_next, WD);
mop(OP_LDWR, &r8, in_center, 1280 , MSK_D0, row_next, WD, row_next_next, WD);
exe(OP_MAUH, &r15, r5, EXP_B5410, r6, EXP_B5410, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MAUH, &r16, r5, EXP_B7632, r6, EXP_B7632, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MAUH3, &r11, r3, EXP_B5410, r4, EXP_B5410, r11, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MAUH3, &r12, r3, EXP_B7632, r4, EXP_B7632, r12, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MLUH, &r13, r11, EXP_H3210, 13, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MLUH, &r14, r12, EXP_H3210, 13, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MAUH3, &r15, r7, EXP_B5410, r8, EXP_B5410, r15, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MAUH3, &r16, r7, EXP_B7632, r8, EXP_B7632, r16, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_NOP, &r7, r15, EXP_H3210, 0LL, EXP_H3210, 0, EXP_H3210, OP_OR, 0, OP_SRLM, 2);
exe(OP_MLUH, &r17, r15, EXP_H3210, 15, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_NOP, &r8, r16, EXP_H3210, 0LL, EXP_H3210, 0, EXP_H3210, OP_OR, 0, OP_SRLM, 2);
exe(OP_MLUH, &r18, r16, EXP_H3210, 15, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MSUH3, &r10, r20, EXP_H3210, r7, EXP_H3210, r17, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MSUH3, &r11, r21, EXP_H3210, r8, EXP_H3210, r18, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MSUH, &r20, r10, EXP_H3210, r13, EXP_H3210, 0, EXP_H3210, OP_OR, 0, OP_SRLM, 7);
exe(OP_MSUH, &r21, r11, EXP_H3210, r14, EXP_H3210, 0, EXP_H3210, OP_OR, 0, OP_SRLM, 7);
exe(OP_MH2BW, &r31, r21, EXP_H3210, r20, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
mop(OP_STWR, &r31, out_center, col, MSK_D0, out_center, WD, row_prev, WD);
}
}
//EMAX5A end
}
r1 r5 r2
r7 r0 r6
r4 r8 r3
20210401
53
フレーム補間
20210401
54
超解像
for (Y=0; Y<768; Y++) {
k = Y*240/768;
kfraq = (((Y*240)<<4)/768)&15;
for (X=0; X<1024; X++) {
l = X*320/1024;
lfraq = (((X*320)<<4)/1024)&15;/
out[Y][X] = ((in[k ][l ]>>24&0xff)*r1 + (in[k ][l-1]>>24&0xff)*r2 + (in[k ][l+1]>>24&0xff)*r3
+ (in[k-1][l ]>>24&0xff)*r4 + (in[k+1][l ]>>24&0xff)*r5 + (in[k-1][l-1]>>24&0xff)*r6
+ (in[k-1][l+1]>>24&0xff)*r7 + (in[k+1][l-1]>>24&0xff)*r8 + (in[k+1][l+1]>>24&0xff)*r9)/256<<24
| ((in[k ][l ]>>16&0xff)*r1 + (in[k ][l-1]>>16&0xff)*r2 + (in[k ][l+1]>>16&0xff)*r3
+ (in[k-1][l ]>>16&0xff)*r4 + (in[k+1][l ]>>16&0xff)*r5 + (in[k-1][l-1]>>16&0xff)*r6
+ (in[k-1][l+1]>>16&0xff)*r7 + (in[k+1][l-1]>>16&0xff)*r8 + (in[k+1][l+1]>>16&0xff)*r9)/256<<16
| ((in[k ][l ]>> 8&0xff)*r1 + (in[k ][l-1]>> 8&0xff)*r2 + (in[k ][l+1]>> 8&0xff)*r3
+ (in[k-1][l ]>> 8&0xff)*r4 + (in[k+1][l ]>> 8&0xff)*r5 + (in[k-1][l-1]>> 8&0xff)*r6
+ (in[k-1][l+1]>> 8&0xff)*r7 + (in[k+1][l-1]>> 8&0xff)*r8 + (in[k+1][l+1]>> 8&0xff)*r9)/256<<8;
}
}
K-1
K = Y*240/768
L-1 L = X*320/1024
(X,Y) 1024x768の1画素
(L,K) 320x240画像
kfraq = (((Y*240)<<4)/ 768)&15;/* 4bit */
lfraq = (((X*320)<<4)/1024)&15;/* 4bit */
Y=1 kfraq= 5/16
Y=2 kfraq=10/16
Y=3 kfraq=15/16
Y=4 kfraq= 4/16
Y=5 kfraq= 9/16
X=1 lfraq= 5/16
X=2 lfraq=10/16
X=3 lfraq=15/16
X=4 lfraq= 4/16
X=5 lfraq= 9/16
20210401
55
ステレオマッチング
for (row=8; row<240-8; row++) {
for (Y=-8; Y<8; Y++) {
for (col=8; col<320-8; col++) {
for (X=-8; X<8; X++)
SAD2[row][col] += sad(L[row+Y][col+X+視差], R[row+Y][col+X]);
}
}
}
for (row=-8; row<240-8; row++) {
//EMAX5A begin wdifline mapdist=0
for (CHIP=0; CHIP<NCHIP; CHIP++) {
for (INIT0=1,LOOP0=320,col=0-4LL; LOOP0--; INIT0=0) {
exe(OP_ADD, &col, col, EXP_H3210, 4LL, EXP_H3210, 0, EXP_H3210, OP_AND, 0x00000000ffffffffLL, OP_NOP, 0);
exe(OP_ADD, &rofs1, L, EXP_H3210, col, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_ADD, &rofs2, R, EXP_H3210, col, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
mop(OP_LDWR, &r2, rofs1, 0, MSK_D0, L, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r3, rofs1, 4, MSK_D0, L, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r4, rofs1, 8, MSK_D0, L, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r5, rofs1, 12, MSK_D0, L, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r6, rofs2, 0, MSK_D0, R, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r7, rofs2, 4, MSK_D0, R, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r8, rofs2, 8, MSK_D0, R, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r9, rofs2, 12, MSK_D0, R, 320, 0, 0, NULL, 320);
exe(OP_MSAD, &r22, r2, EXP_H3210, r6, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
mop(OP_LDWR, &r12, rofs1, 16, MSK_D0, L, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r13, rofs1, 20, MSK_D0, L, 320, 0, 0, NULL, 320);
exe(OP_MSAD, &r23, r3, EXP_H3210, r7, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
mop(OP_LDWR, &r14, rofs1, 24, MSK_D0, L, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r15, rofs1, 28, MSK_D0, L, 320, 0, 0, NULL, 320);
exe(OP_MSAD, &r24, r4, EXP_H3210, r8, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
mop(OP_LDWR, &r16, rofs2, 16, MSK_D0, R, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r17, rofs2, 20, MSK_D0, R, 320, 0, 0, NULL, 320);
exe(OP_MSAD, &r25, r5, EXP_H3210, r9, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
mop(OP_LDWR, &r18, rofs2, 24, MSK_D0, R, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r19, rofs2, 28, MSK_D0, R, 320, 0, 0, NULL, 320);
exe(OP_MSSAD, &r12, r22, EXP_H3210, r12, EXP_H3210, r16, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
mop(OP_LDWR, &r2, rofs1, 32, MSK_D0, L, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r3, rofs1, 36, MSK_D0, L, 320, 0, 0, NULL, 320);
exe(OP_MSSAD, &r13, r23, EXP_H3210, r13, EXP_H3210, r17, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
mop(OP_LDWR, &r4, rofs1, 40, MSK_D0, L, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r5, rofs1, 44, MSK_D0, L, 320, 0, 0, NULL, 320);
exe(OP_MSSAD, &r14, r24, EXP_H3210, r14, EXP_H3210, r18, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
mop(OP_LDWR, &r6, rofs2, 32, MSK_D0, R, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r7, rofs2, 36, MSK_D0, R, 320, 0, 0, NULL, 320);
exe(OP_MSSAD, &r15, r25, EXP_H3210, r15, EXP_H3210, r19, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
mop(OP_LDWR, &r8, rofs2, 40, MSK_D0, R, 320, 0, 0, NULL, 320);
mop(OP_LDWR, &r9, rofs2, 44, MSK_D0, R, 320, 0, 0, NULL, 320);
exe(OP_MSSAD, &r22, r12, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MSSAD, &r23, r13, EXP_H3210, r3, EXP_H3210, r7, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MSSAD, &r24, r14, EXP_H3210, r4, EXP_H3210, r8, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MSSAD, &r25, r15, EXP_H3210, r5, EXP_H3210, r9, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MAUH3, &r31, r22, EXP_H3210, r23, EXP_H3210, r24, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
exe(OP_MAUH3, &r1, r31, EXP_H3210, r25, EXP_H3210, 0, EXP_H3210, OP_SUMHL,0, OP_NOP, 0);
mop(OP_LDWR, &BR[8][0][1], sad2, col, MSK_D0, sad2, 320, 0, 1, NULL, 320);
exe(OP_ADD, &AR[8][0], BR[8][0][1], EXP_H3210, r1, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
mop(OP_STWR, &AR[8][0], col, sad2, MSK_D0, sad2, 320, 0, 1, NULL, 320);
:のこり15か所のSADにも加算
}
}
//EMAX5A end
}
//EMAX5A drain_dirty_lmm
20210401
56
ステレオマッチング
CPU GPU
Ultimate CGRA w/ high-speed compiler
CGRA for Energy-efficient Cryptography
Beyond-Neuromorphic Systems
Non-Deterministic Computing
20210401
57
ナレータ VOICEVOX:もち子(cv 明日葉よもぎ)
はらぺこエンジニアに贈るCGRAの世界2022
(機械学習)
スパコンからIoTまで 省エネ社会に
AI+BCだけじゃない超効率計算手法
20210401
58
機械学習=トレーニング+インファレンス
GPU: unpack and matrix-multiplication (x9 memory space)
1 -1-1-1 1 -1-1-1 1 1 -1-1-1 1 -1-1-1 1
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3 … 0.27
1.3 … 1.27
2.3 … 2.27
: : :
: : :
27.0 27.1 27.2
: …
: : :
27.3 … 27:27
unpack_patch2col
1.0 1.1
1.1 1.2
1.2 1.3
1.0 1.1 …
1.1 1.2 :
1.2 1.3 …
1:25 2.0 2.1
1.26 2.1 2.2
1.27 2.2 2.3
… 1.25 25.0
:… 1.26 25.1
… 1.27 25.2
25.1 … 25.25
25.2 … 25.26
25.3 … 25.27
… 2.25 26.0
: 2.26 26.1
… 2.27 26.2
26.1 … 26.25
26.2 : 26.26
26.3 … 26:27
: : :
2.2 2.3 …
: : :
2.27 3.4 3.5
: : :
… 3.27 27.2
: : :
27.3 … 27:27
3x3
26x26
28
28
…
…
…
…
:
…
: : : : 4.5 4.27
4.4
x100
x100
copy
0.0 0.1 … 0.25
0.1 0.2 … 0.26
0.27
…
0.3
0.2
1 -1 -1
-1 1 -1
-1-1 1
C
M&A
CPU/GPUの畳み込み演算
20210401
59
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3 … 0.27
1.3 … 1.27
2.3 … 2.27
: : :
: : :
27.0 27.1 27.2
: …
: : :
27.3 … 27:27
…
…
…
…
:
…
: : : : 4.5 4.27
4.4
0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3 … 0.27
1.3 … 1.27
2.3 … 2.27
: : : : …
…
…
…
…
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3 … 0.27
1.3 … 1.27
2.3 … 2.27
: : : : …
…
…
…
…
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3 … 0.27
1.3 … 1.27
2.3 … 2.27
: : : : …
…
…
…
…
-1 -1
1 -1 1
1 1 -1
-1 … 1
-1 … 1
1 … 1
: : : : …
…
…
…
…
1 -1
1 -1 1
1 1 -1
-1 … 1
-1 … 1
1 … 1
: : : : …
…
…
…
…
1 -1 -1
1 -1 1
1 1 -1
-1 …
-1 … 1
1 … 1
: : : : …
…
…
…
…
0.0 0.1
-1
1
OCH#0
OCH#1
OCH#2
OCH#0
OCH#1
OCH#2
OCH#0
OCH#1
OCH#2
0.0 0.1 0.2
1.0 1.1 1.2
0.25
1.25
: : :
…
…
…
0.0 0.1 0.2
1.0 1.1 1.2
0.25
1.25
: : :
…
…
…
0.0 0.1 0.2
1.0 1.1 1.2
0.25
1.25
: : :
…
…
…
0.0 0.1 0.2
1.0 1.1 1.2
0.25
1.25
: : :
…
…
…
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
1 -1 -1
-1 1 -1
-1 -1 1
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3 … 0.27
1.3 … 1.27
2.3 … 2.27
: : :
: : :
27.0 27.1 27.2
: …
: : :
27.3 … 27:27
…
…
…
…
:
…
: : : : 4.5 4.27
4.4
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3 … 0.27
1.3 … 1.27
2.3 … 2.27
: : :
: : :
27.0 27.1 27.2
: …
: : :
27.3 … 27:27
…
…
…
…
:
…
: : : : 4.5 4.27
4.4
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3 … 0.27
1.3 … 1.27
2.3 … 2.27
: : :
: : :
27.0 27.1 27.2
: …
: : :
27.3 … 27:27
…
…
…
…
:
…
: : : : 4.5 4.27
4.4
ICH#0
ICH#0
ICH#1
ICH#2
ICH#3
ICH#0
ICH#1
ICH#2
ICH#3
OCH#0
OCH#1
1
1
FMUL
FMA
ICH#1
ICH#5
54 units
Kernel bcast
ICH#0 bcast
ICH#1 bcast
Drain
4 columns
20210401
60
IMAXの畳み込み演算
imax() {
Ull CHIP; Ull LOOP1, LOOP0; Ull INIT1, INIT0;
Ull AR[64][4]; Ull BR[64][4][4];
Ull r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15;
Ull r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31;
Ull cc0, cc1, cc2, cc3, ex0, ex1; Ull cofs, rofs, oofs, k;
for (top=0; top<M1/NCHIP; top+=RMGRP) { /* will be parallelized by multi-chip (M/#chip) */
for (blk=0; blk<L; blk+=H) {
typedef struct {Uint i[8]} Ui8;
Uint *a0[NCHIP]; Uint *a[H][NCHIP]; Ui8 *b[H], *b0[H], *b1[H], *b2[H], *b3[H];
Ui8 *c0[NCHIP]; Ui8 *c00[NCHIP], *c01[NCHIP], *c02[NCHIP], *c03[NCHIP];
for (k=0; k<H; k++) {
b[k] = B+(blk+k)*M2; b0[k] = b[k]; b1[k] = (Uint*)b[k]+2; b2[k] = (Uint*)b[k]+4; b3[k] = (Uint*)b[k]+6;
}
for (CHIP=0; CHIP<NCHIP; CHIP++) { /* will be parallelized by multi-chip (M/#chip) */
a0[CHIP] = A+(CHIP*M1/NCHIP+top)*L;
for (k=0; k<H; k++) a[k][CHIP] = a0[CHIP]+blk+k;
c0[CHIP] = C1+(CHIP*M1/NCHIP+top)*M2;
c00[CHIP]= (Uint*)c0[CHIP]+0; c01[CHIP]= (Uint*)c0[CHIP]+2; c02[CHIP]= (Uint*)c0[CHIP]+4; c03[CHIP]= (Uint*)c0[CHIP]+6;
}
//EMAX5A begin mm mapdist=0
/*3*/ for (CHIP=0; CHIP<NCHIP; CHIP++) { /* will be parallelized by multi-chip (M/#chip) */
/*2*/ for (INIT1=1,LOOP1=RMGRP,rofs=(0-L*4)<<32|((0-M2*4)&0xffffffff); LOOP1--; INIT1=0) { /* stage#0 *//* mapped to FOR() on BR[63][1][0] */
/*1*/ for (INIT0=1,LOOP0=M2/W/2,cofs=(0-W*8)<<32|((0-W*8)&0xffffffff); LOOP0--; INIT0=0) { /* stage#0 *//* mapped to FOR() on BR[63][0][0] */
exe(OP_ADD, &cofs, INIT0?cofs:cofs, EXP_H3210, (W*8)<<32|(W*8), EXP_H3210, 0LL, EXP_H3210, OP_AND, 0xffffffffffffffffLL, OP_NOP, 0LL);
exe(OP_ADD, &rofs, rofs, EXP_H3210, INIT0?(L*4)<<32|(M2*4):0, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe(OP_ADD, &oofs, rofs, EXP_H3210, cofs, EXP_H3210, 0, EXP_H3210, OP_AND, 0xffffffff, OP_NOP, 0LL); /* stage#1 */
mop(OP_LDR, 3, &BR[1][0][1], (Ull)b0[0], (Ull)cofs, MSK_W1, (Ull)b[0], M2/2, 0, 0, (Ull)NULL, M2/2); /* stage#1 */
mop(OP_LDR, 3, &BR[1][0][0], (Ull)b1[0], (Ull)cofs, MSK_W1, (Ull)b[0], M2/2, 0, 0, (Ull)NULL, M2/2); /* stage#1 */
mop(OP_LDR, 3, &BR[1][1][1], (Ull)b2[0], (Ull)cofs, MSK_W1, (Ull)b[0], M2/2, 0, 0, (Ull)NULL, M2/2); /* stage#1 */
mop(OP_LDR, 3, &BR[1][1][0], (Ull)b3[0], (Ull)cofs, MSK_W1, (Ull)b[0], M2/2, 0, 0, (Ull)NULL, M2/2); /* stage#1 2KB */
mop(OP_LDUWR,1, &BR[1][2][1], (Ull)a[0][CHIP], (Ull)rofs, MSK_W1, (Ull)a0[CHIP], L*RMGRP/2, 0, 0, (Ull)NULL, L*RMGRP/2); /* stage#1 16KB */
exe(OP_FML, &AR[2][0], BR[1][0][1], EXP_H3210, BR[1][2][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); /* stage#2 */
exe(OP_FML, &AR[2][1], BR[1][0][0], EXP_H3210, BR[1][2][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); /* stage#2 */
exe(OP_FML, &AR[2][2], BR[1][1][1], EXP_H3210, BR[1][2][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); /* stage#2 */
exe(OP_FML, &AR[2][3], BR[1][1][0], EXP_H3210, BR[1][2][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); /* stage#2 */
sgemm00_core1( 2, 1, 3);
sgemm00_core1( 3, 2, 4);
:
sgemm00_core1(59, 58, 60);
sgemm00_core1(60, 59, 61);
sgemm00_final(61, 62);
} } }
//EMAX5A end
} }
//EMAX5A drain_dirty_lmm
}
Just repeating following macros
IMAXの行列積
20210401
61
#define sgemm00_core1(r, rm1, rp1) 
mop(OP_LDR, 3, &BR[r][0][1], b0[rm1], cofs, MSK_W1, b[rm1], M2/2, 0, 0, NULL, M2/2);
mop(OP_LDR, 3, &BR[r][0][0], b1[rm1], cofs, MSK_W1, b[rm1], M2/2, 0, 0, NULL, M2/2);
mop(OP_LDR, 3, &BR[r][1][1], b2[rm1], cofs, MSK_W1, b[rm1], M2/2, 0, 0, NULL, M2/2);
mop(OP_LDR, 3, &BR[r][1][0], b3[rm1], cofs, MSK_W1, b[rm1], M2/2, 0, 0, NULL, M2/2);
mop(OP_LDUWR,1, &BR[r][2][1], a[rm1][CHIP], rofs, MSK_W1, a0[CHIP], L*RMGRP/2, 0, 0, NULL, L*RMGRP/2);
exe (OP_FMA, &AR[rp1][0], AR[r][0], EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][0][1], EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe (OP_FMA, &AR[rp1][1], AR[r][1], EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][0][0], EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe (OP_FMA, &AR[rp1][2], AR[r][2], EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][1][1], EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe (OP_FMA, &AR[rp1][3], AR[r][3], EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][1][0], EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL)
#define sgemm00_final(r, rp1) 
exe(OP_CMP_LT, &cc1, cofs, EXP_H3210, cofslimit1, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe(OP_CMP_LT, &cc2, cofs, EXP_H3210, cofslimit2, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe(OP_CMP_LT, &cc3, cofs, EXP_H3210, cofslimit3, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
mop(OP_LDUWR, 1, &BR[rp1][0][1], c00[CHIP], oofs, MSK_W0, c0[CHIP], Clen, 0, 1, NULL, Clen);
mop(OP_LDUWR, 1, &BR[rp1][1][1], c01[CHIP], oofs, MSK_W0, c0[CHIP], Clen, 0, 1, NULL, Clen);
mop(OP_LDUWR, 1, &BR[rp1][2][1], c02[CHIP], oofs, MSK_W0, c0[CHIP], Clen, 0, 1, NULL, Clen);
mop(OP_LDUWR, 1, &BR[rp1][3][1], c03[CHIP], oofs, MSK_W0, c0[CHIP], Clen, 0, 1, NULL, Clen);
exe (OP_FAD, &AR[rp1][0], AR[r][0], EXP_H3210, BR[rp1][0][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe (OP_FAD, &AR[rp1][1], AR[r][1], EXP_H3210, BR[rp1][1][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe (OP_FAD, &AR[rp1][2], AR[r][2], EXP_H3210, BR[rp1][2][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe (OP_FAD, &AR[rp1][3], AR[r][3], EXP_H3210, BR[rp1][3][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
mop(OP_STWR, 1, &AR[rp1][0], oofs, c00[CHIP], MSK_D0, c0[CHIP], Clen, 0, 1, NULL, Clen);
cex (OP_CEXE, &ex1, 0, 0, 0, cc1, 0xaaaa);
mop(OP_STWR, ex1, &AR[rp1][1], oofs, c01[CHIP], MSK_D0, c0[CHIP], Clen, 0, 1, NULL, Clen);
cex (OP_CEXE, &ex2, 0, 0, 0, cc2, 0xaaaa);
mop(OP_STWR, ex2, &AR[rp1][2], oofs, c02[CHIP], MSK_D0, c0[CHIP], Clen, 0, 1, NULL, Clen);
cex (OP_CEXE, &ex3, 0, 0, 0, cc3, 0xaaaa);
mop(OP_STWR, ex3, &AR[rp1][3], oofs, c03[CHIP], MSK_D0, c0[CHIP], Clen, 0, 1, NULL, Clen)
One physical (four logical) unit
One physical (four logical) unit
マクロの中身
Prefetching
Length of area
Top of area
LD/ST offset
LD/ST base addr.
20210401
62
#define sgemm00_core1
mop(OP_LDUWR, 1, &BR[r][0][1]
mop(OP_LDUWR, 1, &BR[r][0][0]
mop(OP_LDUWR, 1, &BR[r][1][1]
mop(OP_LDUWR, 1, &BR[r][1][0]
mop(OP_LDUWR, 1, &BR[r][2][1]
exe(OP_FMA, &AR[rp1][0]
exe(OP_FMA, &AR[rp1][1]
exe(OP_FMA, &AR[rp1][2]
exe(OP_FMA, &AR[rp1][3]
#define sgemm00_final
exe(OP_CMP_LT, &cc1
exe(OP_CMP_LT, &cc2
exe(OP_CMP_LT, &cc3
mop(OP_LDUWR, 1, &BR[rp1][0][1]
mop(OP_LDUWR, 1, &BR[rp1][1][1]
mop(OP_LDUWR, 1, &BR[rp1][2][1]
mop(OP_LDUWR, 1, &BR[rp1][3][1]
exe(OP_FAD, &AR[rp1][0], AR[r][0]
exe(OP_FAD, &AR[rp1][1], AR[r][1]
exe(OP_FAD, &AR[rp1][2], AR[r][2]
exe(OP_FAD, &AR[rp1][3], AR[r][3]
mop(OP_STWR, 1, &AR[rp1][0]
cex(OP_CEXE, &ex1, cc1
mop(OP_STWR, ex1, &AR[rp1][1]
cex(OP_CEXE, &ex2, cc2
mop(OP_STWR, ex2, &AR[rp1][2]
cex(OP_CEXE, &ex3, cc3
mop(OP_STWR, ex3, &AR[rp1][3]
20210401
63
行列積のコンパイル結果
unpack_patch2col(tmp_col:25x[100x24x24] <-- ninput:■100x28x28, ksize, kstride)
reshape nhidden:100x[8x24x24] --> tmp_dst:8x[100x24x24]
(C1)multiply_float2D(▲g_Ki2h:8x25 <-- tmp_dst:8x[100x24x24], tmp_col:25x[100x24x24]^T)
(C2)multiply_float2D(tmp_col:25x[100x24x24] <-- Ki2h:8x25^T, tmp_dst:8x[100x24x24])
pack_col2patch(ninput:■100x28x28 <-- tmp_col:25x[100x24x24], 5, 1)
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
… … 0.27
… … 1.27
… … 2.27
: : :
: : :
27.0 27.1 27.2
… …
: : :
27.3 … 27:27
28
28
0:23
1:23
2:23
:
:
…
23:0 23:1 23:2 … … 4.27
23.23
xICx100
24
24
x100x8
tmp_dst
ninput
(original)
g_Ki2h
(C1)
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.23
1.23
2.23
: : :
23.0 23.1 23.2
:
23.23
…
…
…
…
…
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3
1.3
2.3
: : : :
0.4
1.4
2.4
:
: : : : 4.4
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3
1.3
2.3
: : : :
0.4
1.4
2.4
:
: : : : 4.4
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3
1.3
2.3
: : : :
0.4
1.4
2.4
:
: : : : 4.4
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3
1.3
2.3
: : : :
0.4
1.4
2.4
:
: : : : 4.4
0.0 0.1 …
: : …
0.4 0.5 …
0.23 1.0 1.1
: : :
0:27 1.4 1.5
1.0 1.1 …
: : :
1.4 1.5 …
1:23 2.0 2.1
: : :
1.27 2.4 2.5
… 1.23 23.0
:… : :
… 1.27 23.4
23.1 … 23.23
: … :
23.5 … 23.27
… 2.23 24.0
: : :
… 2.27 24.4
24.1 … 24.23
: : :
24.5 … 24:27
: : :
4.4 4.5 …
: : :
4.27 5.4 5.5
: : :
… 5.27 27.4
: : :
27.5 … 27:27
5x5
xIC
24x24
x100
tmp_col
(reshaped for GPU)
copy
5x5xICx8
nhidden 24 x8x100
20210401
64
IMAXの重み用バックプロパゲーション
unpack_patch2col(tmp_col:25x[100x24x24] <-- ninput:■100x28x28, ksize, kstride)
reshape nhidden:100x[8x24x24] --> tmp_dst:8x[100x24x24]
(C1)multiply_float2D(▲g_Ki2h:8x25 <-- tmp_dst:8x[100x24x24], tmp_col:25x[100x24x24]^T)
(C2)multiply_float2D(tmp_col:25x[100x24x24] <-- Ki2h:8x25^T, tmp_dst:8x[100x24x24])
pack_col2patch(ninput:■100x28x28 <-- tmp_col:25x[100x24x24], 5, 1)
24
24
x8x100
nhidden
Ki2h
ninput
(C2)
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3
1.3
2.3
: : : :
0.4
1.4
2.4
:
: : : : 4.4
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3
1.3
2.3
: : : :
0.4
1.4
2.4
:
: : : : 4.4
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3
1.3
2.3
: : : :
0.4
1.4
2.4
:
: : : : 4.4
0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.3
1.3
2.3
: : : :
0.4
1.4
2.4
:
: : : : 4.4
0.0 0.1
0.0 0.2
1.0 1.1 1.2
2.0 2.1 2.2
… … 0.27
… … 1.27
… … 2.27
: : :
: : :
27.0 27.1 27.2
… …
: : :
27.3 … 27:27
28
28
0:23
1:23
2:23
:
:
…
23:0 23:1 23:2 … … 4.27
23.23
xICx100
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.23
1.23
2.23
: : :
:23.0 23.1 23.2
:
23.23
…
…
…
…
…
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.23
1.23
2.23
: : :
:23.0 23.1 23.2
:
23.23
…
…
…
…
…
0.0 0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.23
1.23
2.23
: : :
:23.0 23.1 23.2
:
23.23
…
…
…
…
…
0.1 0.2
1.0 1.1 1.2
2.0 2.1 2.2
0.23
1.23
2.23
: : :
23.0 23.1 23.2
:
23.23
…
…
…
…
…
0.0
0.0 0.1 …
: …
0.4 0.5 …
0.23 1.0 1.1
: 1.1 :
0:27 1.4 1.5
1.0 1.1 …
1.1 : :
1.4 1.5 …
1:23 2.0 2.1
: : :
1.27 2.4 2.5
… 1.23 23.0
:… : :
… 1.27 23.4
23.1 … 23.23
: … :
23.5 … 23.27
… 2.23 24.0
: : :
… 2.27 24.4
24.1 … 24.23
: : :
24.5 … 24:27
: : :
4.4 4.5 …
: : :
4.27 5.4 5.5
: : :
… 5.27 27.4
: : :
27.5 … 27:27
5x5
xIC
24x24
x100
contribution
of pixel/ninput
:
merge
5x5xICx8
Integration
of OC(8)
0.1
tmp_col
(reshaped for GPU)
20210401
65
IMAXの入力用バックプロパゲーション
0.50×0.50≒0.20
0000111101
0111110000
0000110000
Multiplier by AND gate
0.50+0.50≒0.50*2
0000111101
0111110000
0101111000
Scaled adder by random selector
20210401
66
ストカスティック積和演算
0.50+0.50=1.00
Adder by population counter
Tati Erlina, Yan Chen, Renyuan Zhang and Yasuhiko Nakashima: "An Efficient Time-based Stochastic Computing
Circuitry Employing Neuron-MOS", GLSVLSI2019, pp.51-56, May. (2019)
20210401
67
IMAXのストカスティック積和演算
CPU GPU
Ultimate CGRA w/ high-speed compiler
CGRA for Energy-efficient Cryptography
Beyond-Neuromorphic Systems
Non-Deterministic Computing
20210401
68
ナレータ VOICEVOX:もち子(cv 明日葉よもぎ)
はらぺこエンジニアに贈るCGRAの世界2022
(高次数ステンシル計算)
スパコンからIoTまで 省エネ社会に
AI+BCだけじゃない超効率計算手法
20210401
69
様々なステンシル計算
20210401
70
FD6の写像
青枠:x方向に並ぶロード
紫 :y方向に並ぶロード
赤枠:z方向に並ぶロード
20210401
71
FD6の写像
FD6
20210401
72
FD6の写像
20210401
73
ライトフィールド画像処理
Refocus All in Focus Perspective Shift
20210401
74
ライトフィールド画像処理
20210401
75
ライトフィールド画像処理
レンダリング
距離画像生成
CPU GPU
Ultimate CGRA w/ high-speed compiler
CGRA for Energy-efficient Cryptography
Beyond-Neuromorphic Systems
Non-Deterministic Computing
20210401
76
ナレータ VOICEVOX:もち子(cv 明日葉よもぎ)
はらぺこエンジニアに贈るCGRAの世界2022
(逆行列)
スパコンからIoTまで 省エネ社会に
AI+BCだけじゃない超効率計算手法
20210401
77
逆行列は、連立一次方程式の特殊ケースで求まる
連立一次方程式
LU分解
前進消去
後退代入
20210401
78
逆行列には、ローカルメモリ自己更新
for (j=i+1; j<M; j+=NCHIP*H*RMGRP) { /* 行方向 */
//EMAX5A begin inv_x1 mapdist=0
for (CHIP=0; CHIP<NCHIP; CHIP++) {
for (INIT1=1,LOOP1=RMGRP,rofs=0-M*4; LOOP1--; INIT1=0) { /* stage#0 *//* mapped to FOR() on BR[63][1][0] */
for (INIT0=1,LOOP0=M-(i+1),cofs=0; LOOP0--; INIT0=0) { /* stage#0 *//* mapped to FOR() on BR[63][0][0] */
exe(OP_ADD, &cofs, INIT0?cofs:cofs, EXP_H3210, 4LL, EXP_H3210, 0LL, EXP_H3210, OP_AND, 0x00000000ffffffffLL, OP_NOP, 0LL); /* stage#0 */
exe(OP_ADD, &rofs, rofs, EXP_H3210, INIT0?M*4:0, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); /* stage#0 */
exe(OP_ADD, &oofs, rofs, EXP_H3210, cofs, EXP_H3210, 0LL, EXP_H3210, OP_AND, 0x00000000ffffffffLL, OP_NOP, 0LL); /* stage#1 */
/***************************/
/* + - - - - - - - - - - - */ /* A[p[i]] 先頭行 */ /* 先頭行はi更新まで再利用可能 */
/* | * > > > > > > > > > > */ /* A[p[j]] 次行から引く */ /* 1行をLMMに写像 */
/* | v + - - - - - - - - - */
/* | v | * > > > > > > > > */ /* M/60を収容してi更新までj+=60を繰り返す *//* 行番号比較とcstによる端数制御 */
/* | v | v + - - - - - - - */ /* + CHIP#0 h=0 grp=0 */
/* | v | v - + - - - - - - */ /* + CHIP#0 h=0 grp=1 */
/* | v | v - - + - - - - - */ /* + CHIP#1 h=0 grp=0 */
/* | v | v - - - + - - - - */ /* + CHIP#1 h=0 grp=1 */
/* | v | v - - - - + - - - */ /* + CHIP#0 h=1 grp=0 */
/* | v | v - - - - - + - - */ /* + CHIP#0 h=1 grp=1 */
/* | v | v - - - - - - + - */ /* + CHIP#1 h=1 grp=0 */
/* | v | v - - - - - - - + */ /* + CHIP#1 h=1 grp=1 */
/***************************/ /* 最大60行まで写像可能 */
/* FOLDING時は,少なくとも第0列がFOLDINGであることが必要(conv-c2c仕様) */
/* CEXEにも関わらずSTWRの無意味なLMM入れ換えが発生するため,A[M][*](枠外領域)を使用 */ /* OK exe-loop */
exe(OP_CMP_LT, &cc0, l00[CHIP], EXP_H3210, M, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0); /* stage#1 LD */
mop(OP_LDWR, 1, &BR[2][2][1], top, cofs, MSK_W0, topw, len, 0, 0, NULL, len); /* A[p[i]*M+k] stage#2 | */
mop(OP_LDWR, 1, &BR[2][0][1], d00[CHIP], oofs, MSK_W0, d00w[CHIP], len2,0, 1, NULL, len2); /* A[p[j+h*NCHIP+CHIP]*M+k] stage#2 +-> | */
mop(OP_LDWR, 1, &BR[2][1][1], d00[CHIP], rofs, MSK_W0, d00w[CHIP], len2,0, 1, NULL, len2); /* A[p[j+h*NCHIP+CHIP]*M+k] stage#2 +-> | */
exe(OP_FMS, &AR[2][0], BR[2][0][1], EXP_H3210, BR[2][1][1], EXP_H3210, BR[2][2][1], EXP_H3210, OP_NOP, 0LL, OP_NOP, 0); /* stage#2 | ■■■ | 1.0 */
cex(OP_CEXE, &ex0, 0, 0, 0, cc0, 0xaaaa); /* stage#2 | AR[1] | */
mop(OP_STWR,ex0, &AR[2][0], oofs, d00[CHIP], MSK_D0, d00w[CHIP], len2, 0, 1, NULL, len2); /* stage#2 | + ST v */
#if (H>1) /* *--------- BR[2] */
exe(OP_CMP_LT, &cc1, l01[CHIP], EXP_H3210, M, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0); /* stage#2 LD */
mop(OP_LDWR, 1, &BR[3][2][1], top, cofs, MSK_W0, topw, len, 0, 0, NULL, len); /* A[p[i]*M+k] stage#3 | */
mop(OP_LDWR, 1, &BR[3][0][1], d01[CHIP], oofs, MSK_W0, d01w[CHIP], len2,0, 1, NULL, len2); /* A[p[j+h*NCHIP+CHIP]*M+k] stage#3 +-> | */
mop(OP_LDWR, 1, &BR[3][1][1], d01[CHIP], rofs, MSK_W0, d01w[CHIP], len2,0, 1, NULL, len2); /* A[p[j+h*NCHIP+CHIP]*M+k] stage#3 +-> | */
exe(OP_FMS, &AR[3][0], BR[3][0][1], EXP_H3210, BR[3][1][1], EXP_H3210, BR[3][2][1], EXP_H3210, OP_NOP, 0LL, OP_NOP, 0); /* stage#3 | ■■■ | 1.0 */
cex(OP_CEXE, &ex0, 0, 0, 0, cc1, 0xaaaa); /* stage#3 | AR[2] | */
mop(OP_STWR,ex0, &AR[3][0], oofs, d01[CHIP], MSK_D0, d01w[CHIP], len2, 0, 1, NULL, len2); /* stage#3 | + ST v */
#if (H>2) /* *--------- BR[3] */
if (j+h*NCHIP*RMGRP+CHIP*RMGRP+grp<M)
A[(j+h*NCHIP*RMGRP+CHIP*RMGRP+grp)*M+i+1+k]
-= A[(j+h*NCHIP*RMGRP+CHIP*RMGRP+grp)*M+i]*A[i*M+i+1+k];
20210401
79
条件付きストア機能を使う
exe(OP_CMP_LT, &cc0, l00[CHIP], EXP_H3210, M, EXP_H3210, 0LL,
mop(OP_LDWR, 1, &BR[2][2][1], top, cofs, MSK_W0, topw, len, 0, 0, NULL, len);
mop(OP_LDWR, 1, &BR[2][0][1], d00[CHIP], oofs, MSK_W0, d00w[CHIP], len2,0, 1, NULL, len2);
mop(OP_LDWR, 1, &BR[2][1][1], d00[CHIP], rofs, MSK_W0, d00w[CHIP], len2,0, 1, NULL, len2);
exe(OP_FMS, &AR[2][0], BR[2][0][1], EXP_H3210, BR[2][1][1], EXP_H3210, BR[2][2][1],
cex(OP_CEXE, &ex0, 0, 0, 0, cc0, 0xaaaa );
mop(OP_STWR, ex0, &AR[2][0], oofs, d00[CHIP], MSK_D0, d00w[CHIP], len2, 0, 1, NULL, len2);
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
CPU GPU
Ultimate CGRA w/ high-speed compiler
CGRA for Energy-efficient Cryptography
Beyond-Neuromorphic Systems
Non-Deterministic Computing
20210401
80
ナレータ VOICEVOX:もち子(cv 明日葉よもぎ)
はらぺこエンジニアに贈るCGRAの世界2022
(疎行列計算とソート)
スパコンからIoTまで 省エネ社会に
AI+BCだけじゃない超効率計算手法
20210401
81
疎行列積和
マージソート
1 1.0 2 2.0 3 3.0 11 4.0 12 5.0 13 6.0
配列A
配列B 2 1.0 3 2.0 4 3.0 9 4.0 10 5.0 11 6.0
要素番号と値の組
1 a1 2 a2 3 s3 11 a11 12 a12 13 a13
入力A
入力B 2 b2 3 b3 4 b4 9 b9 10 b10 11 b11
値と付加情報(ポインタなど)の組
疎行列とソートには、デュアルアドレス同調機能が便利
20210401
82
疎行列とソートには、デュアルアドレス同調機能が便利
4段パイプライン浮動小数点演算器+メモリ参照(LD+ST)
⑩+⑪+初回初期値C出力レジスタ⇒演算器入力REG
以降、累算 演算器3段結果⇒演算器入力REG
演算器入力REG⇒演算器初段結果⇒演算器2段結果
⇒演算器3段結果⇒演算器入力REGへ戻る累算リング
4段パイプラインAアドレス計算データフロー
①Aアドレス入力REG⇒②0/8加算出力⇒⑦通過
⇒⑨通過⇒先頭へ戻るアドレス累算リング
4段パイプラインBアドレス計算データフロー
①Bアドレス入力REG⇒②0/8加算出力⇒⑦通過
⇒⑨通過⇒先頭へ戻るアドレス累算リング
4段パイプラインAデータ参照フロー
⑤B組およびA組index比較+0/8加算出力
⇒⑥A先頭オフセット加算結果⇒⑧Aマスク結果
⇒④Aメモリ出力⇒先頭
4段パイプラインBデータ参照フロー
⑤B組およびA組index比較+0/8加算出力
⇒⑥B先頭オフセット加算結果⇒⑧Bマスク結果
⇒③Bメモリ出力⇒先頭
①
②
③ ④
⑤
⑥
⑦
⑧
⑨
⑩ ⑪
⑨
①
② ⑤
⑥
⑦
⑧
①
①
② ②
⑦ ⑦
⑨ ⑨
⑤
⑧
⑤
⑥ ⑥
⑧
④
③
⑩ ⑪
オフセット加算
アドレスマスク操作
読み出し結果 B42 読み出し結果 A00
B,A行列のベースアドレス
C02へのストア
20210401
83
4列多重化CGRAに5本のデータ流を埋め込む
mex(OP_CMPA_LE, &b0[h], INIT0?b:b0[h], INIT0?0:8, BR[r][2][1], BR[r][2][0]);
mex(OP_CMPA_GE, &a0[h][CHIP], INIT0?a[h][CHIP]:a0[h][CHIP], INIT0?0:8, BR[r][2][1], BR[r][2][0]);
mex(OP_CMPA_LE, &b0[h], INIT0?b:b0[h], INIT0?0:8, BR[r][2][1], BR[r][2][0]);
mex(OP_CMPA_GE, &a0[h][CHIP], INIT0?a[h][CHIP]:a0[h][CHIP], INIT0?0:8, BR[r][2][1], BR[r][2][0]);
mop(OP_LDR, 3, &BR[r][2][1], b0[h], bofs, MSK_W1, b, 2*LP*RMGRP, 0, 0, NULL, 2*LP*RMGRP);
mop(OP_LDR, 3, &BR[r][2][0], a0[h][CHIP], bofs, MSK_W0, a[h][CHIP], 2*LP, 0, 0, NULL, 2*LP);
mop(OP_LDR, 3, &BR[r][2][1], b0[h], bofs, MSK_W1, b, 2*LP*RMGRP, 0, 0, NULL, 2*LP*RMGRP);
mop(OP_LDR, 3, &BR[r][2][0], a0[h][CHIP], bofs, MSK_W0, a[h][CHIP], 2*LP, 0, 0, NULL, 2*LP);
mop(OP_LDWR, 1, &c00, c0[h][CHIP], oofs, MSK_W0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP);
mop(OP_LDWR, 1, &c00, c0[h][CHIP], oofs, MSK_W0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP);
exe(OP_CFMA, &c00, INIT0?c00:c00, EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][2][0], EXP_H3210, OP_NOP, 00);
exe(OP_CFMA, &c00, INIT0?c00:c00, EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][2][0], EXP_H3210, OP_NOP, 00);
mop(OP_STWR, 1, &c00, oofs, c0[h][CHIP], MSK_D0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP);
mop(OP_STWR, 1, &c00, oofs, c0[h][CHIP], MSK_D0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP);
20210401
84
4列多重化CGRAに10本のデータ流を埋め込む
20210401
85
void emax6sc_pth_imax_02(struct sc_param *param) {
Ull CHIP, LOOP0=param->LOOP0, LOOP1=param->LOOP1;
Ull INIT1[4], INIT0[4];
Uint uLOOP[4];
for (CHIP=0; CHIP<1; CHIP++) { /* unit2 */
uLOOP[CHIP]=LOOP1*LOOP0;
}
while (1) {
for (CHIP=0; CHIP<1; CHIP++)
if (uLOOP[CHIP]) break;
if (CHIP==1) break;
for (CHIP=0; CHIP<1; CHIP++) {
if (uLOOP[CHIP]==0) continue;
if ((2 && SCBR[1].enq[CHIP]==SCBR[1].deq[CHIP]) || (2<17 && SCBR[2].enq[CHIP]!=SCBR[2].deq[CHIP])) continue;
INIT1[CHIP]=(uLOOP[CHIP]>LOOP1*LOOP0-LOOP0);
INIT0[CHIP]=(uLOOP[CHIP]-(uLOOP[CHIP]/LOOP0*LOOP0)==0);
SCBR[1].deq[CHIP] = 1-SCBR[1].deq[CHIP];
{
SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][0] = SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][6];
SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][3] = SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][2];
}
{ Ull base, offs, adr, mexdist, load64;
static int emax6_unaligned_load_valid;
static Ull emax6_unaligned_load_high;
base = (!(0&1)||INIT0[CHIP]) ? ((0&2)?SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][0]:SCM1[2].b[CHIP][0]) : SCM1[2].awoo[CHIP][0];
offs = eam(1 ? SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][6] : SCM1[2].o[CHIP][0], 12);
mexdist = INIT0[CHIP] ? 0 : 0;
SCM1[2].awoo[CHIP][0] = (Ull)(INIT0[CHIP]?base:SCM1[2].awoo[CHIP][0]);
adr = (Uint)(SCM1[2].awoo[CHIP][0] + offs);
SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][1] = (Ull)*(Uint*)(adr&~3LL)<<32 | (Ull)*(Uint*)(adr&~3LL);
SCM1[2].d[CHIP][0] = SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][1];
}
{ Ull base, offs, adr, mexdist, load64;
static int emax6_unaligned_load_valid;
static Ull emax6_unaligned_load_high;
base = (!(1&1)||INIT0[CHIP]) ? ((1&2)?SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][0]:SCM1[2].b[CHIP][2]) : SCM1[2].awoo[CHIP][2];
offs = eam(1 ? SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][2] : SCM1[2].o[CHIP][2], 13);
mexdist = INIT0[CHIP] ? 0 : 8;
SCM1[2].awoo[CHIP][2] = (Ull)(INIT0[CHIP]?base:SCM1[2].awoo[CHIP][2])+(INIT0[CHIP]?0:((SCM0[2].d[CHIP][2]>>32)!=0xffffffff &&
(SCM1[2].d[CHIP][2]>>32)<=(SCM0[2].d[CHIP][2]>>32))?mexdist:0);
adr = (Uint)(SCM1[2].awoo[CHIP][2] + offs);
load64 = *(Ull*)(adr&~7LL);
if ((adr&7) == 0)
SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][9] = load64;
else if (!emax6_unaligned_load_valid) { /* BR[][][1] */
emax6_unaligned_load_valid = 1;
emax6_unaligned_load_high = load64;
SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][9] = load64 >> (adr&7)*8;
}
else { /* BR[][][0] */
emax6_unaligned_load_valid = 0;
SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][9] = emax6_unaligned_load_high << (8-(adr&7))*8 | load64 >> (adr&7)*8;
}
base = (!(1&1)||INIT0[CHIP]) ? ((1&2)?SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][0]:SCM0[2].b[CHIP][2]) : SCM0[2].awoo[CHIP][2];
offs = eam(1 ? SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][2] : SCM0[2].o[CHIP][2], 12);
mexdist = INIT0[CHIP] ? 0 : 8;
SCM0[2].awoo[CHIP][2] = (Ull)(INIT0[CHIP]?base:SCM0[2].awoo[CHIP][2])+(INIT0[CHIP]?0:((SCM1[2].d[CHIP][2]>>32)!=0xffffffff &&
(SCM1[2].d[CHIP][2]>>32)>=(SCM0[2].d[CHIP][2]>>32))?mexdist:0);
adr = (Uint)(SCM0[2].awoo[CHIP][2] + offs);
load64 = *(Ull*)(adr&~7LL);
if ((adr&7) == 0)
SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][8] = load64;
else if (!emax6_unaligned_load_valid) { /* BR[][][1] */
emax6_unaligned_load_valid = 1;
emax6_unaligned_load_high = load64;
SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][8] = load64 >> (adr&7)*8;
}
else { /* BR[][][0] */
emax6_unaligned_load_valid = 0;
SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][8] = emax6_unaligned_load_high << (8-(adr&7))*8 | load64 >> (adr&7)*8;
}
SCM1[2].d[CHIP][2] = SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][9];
SCM0[2].d[CHIP][2] = SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][8];
}
{ union { Uint i; float f; } f3, f2, f1, f0; Ull t3, t2, t1, t0, ex1, ex2, ex3, ex4, ex5, c1, c0, ex1_outd, ex2_outd;
ex1 = exm(!1||(INIT1[CHIP]&&INIT0[CHIP])||((1&1)&&INIT0[CHIP]) ? SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][1] : SCAR[2].r[CHIP][0], 0);
ex2 = exm(((1&2)&&!INIT0[CHIP]) ? 0 : SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][9], 0);
ex3 = exm(SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][8], 0);
f1.i = (Uint)(ex1);
f2.i = (Uint)(ex2>>32);
f3.i = (Uint)(ex3>>32);
if (f2.i != -1 && f2.i == f3.i) {
f2.i = (Uint)(ex2);
f3.i = (Uint)(ex3);
f0.f = f1.f + (f2.f * f3.f);
}
else {
f0.f = f1.f;
}
t0 = f0.i;
ex1_outd = t0;
ex2_outd = ex1_outd;
SCAR[2].r[CHIP][0] = ex2_outd;
}
{ Ull cs0, cs1, cs2, cs3, cex, base, offs, adr, mexdist;
cex = 3;
base = (!(2&1)||INIT0[CHIP]) ? ((2&2)?SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][0]:SCM0[2].b[CHIP][0]) : SCM0[2].awoo[CHIP][0];
offs = eam(0 ? SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][6] : SCM0[2].o[CHIP][0], 14);
mexdist = INIT0[CHIP] ? 0 : 0;
SCM0[2].awoo[CHIP][0] = (Ull)(INIT0[CHIP]?base:SCM0[2].awoo[CHIP][0]);
adr = (Uint)(SCM0[2].awoo[CHIP][0] + offs);
if (cex &1) *(Uint*)(adr&~3LL) = (1==1? SCAR[2].r[CHIP][0] : SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][6]);
}
uLOOP[CHIP]--;
SCBR[2].enq[CHIP] = 1-SCBR[2].enq[CHIP];
}
}
}
上のIMAXコードは4サイクルで全体を実行
逆コンパイルしC言語に戻すと以下の複雑さ
多機能を無理なくデータパスに収容してこそCGRAは高効率
mex(OP_CMPA_LE, &b0[h], INIT0?b:b0[h], INIT0?0:8, BR[r][2][1], BR[r][2][0]);
mex(OP_CMPA_GE, &a0[h][CHIP], INIT0?a[h][CHIP]:a0[h][CHIP], INIT0?0:8, BR[r][2][1], BR[r][2][0]);
mop(OP_LDR, 3, &BR[r][2][1], b0[h], bofs, MSK_W1, b, 2*LP*RMGRP, 0, 0, NULL, 2*LP*RMGRP);
mop(OP_LDR, 3, &BR[r][2][0], a0[h][CHIP], bofs, MSK_W0, a[h][CHIP], 2*LP, 0, 0, NULL, 2*LP);
mop(OP_LDWR, 1, &c00, c0[h][CHIP], oofs, MSK_W0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP);
exe(OP_CFMA, &c00, INIT0?c00:c00, EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][2][0], EXP_H3210, OP_NOP, 00);
mop(OP_STWR, 1, &c00, oofs, c0[h][CHIP], MSK_D0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP);
IMAXコードと逆コンパイル結果の比較
①
①
② ②
⑦ ⑦
⑨ ⑨
⑤
⑧
⑤
⑥ ⑥
⑧
④
③
⑩ ⑪
オフセット加算
アドレスマスク操作
読み出し結果 B42 読み出し結果 A00
疎行列と同様、読み出し結果の大小関係に従い、
1次元配列内の異なるアドレスA,Bの片側を更新
後続ユニットにアドレスA,Bと、2つの読み出し
データを送り、アドレスとデータの各々の大小関
係に従い、いずれかのデータをストアすることに
より、LogN段のソートのうち、1段分を実現
ソート全体のLogN段のうち、1段分の
ソート結果をローカルメモリにストア
ストア先アドレスは単調増加
同時に後続ユニットが、前回の実行結果を前段の
ローカルメモリから読み出し、LogN段の次段以降
を担当する。全体として、ローカルメモリをダブル
バッファとするパイプライン実行が可能となる。
マージソートの作り方
20210401
86
疎行列と同様、
読み出し結果の
大小関係に従い、
1次元配列内の
異なるアドレス
A,Bの片側を更
新
後続ユニットにアドレスA,Bと、2つの読み出しデータを送り、アドレスとデータの各々の大小関
係に従い、いずれかのデータをストアすることにより、LogN段のソートのうち、1段分を実現
ストア先アドレスは単調増加
ソート全体のLogN段のうち、1段分のソート結果をローカルメモリにストア
アドレスA
アドレスB データB データA
疎行列と同様、
読み出し結果の
大小関係に従い、
1次元配列内の
異なるアドレス
A,Bの片側を更
新
同一物理メモリ上で、計算結果を次に渡す
マージソートのコンパイル結果
20210401
87
おまけ。疎行列圧縮
count0 = 0;
for (row=0; row<M1; row++) {
for (col=0; col<M2; col++) {
if (A32_0[row*M2+col] == 0)
continue;
if (count0 >= M1*M2)
continue;
A32_P[count0].d = A32_0[row*M2+col];
A32_P[count0].x = row*M2+col;
count0++;
}
}
*Bas1P = B32_P-1; /* end of B32_0 */
for (i=0; i<M1; i+=RMGRP) {
r1 = (Ull)(i*M2-1)<<32;
ibase0 = B32_0+i*M2;
itop0 = B32_0+i*M2;
itop1 = itop0+RMGRP*M2;
obase0 = *Bas1P; /* end of B32_0 */
otop1 = otop0;
otop0 = *Bas1P+8; /* top of B32_P */
//with-prefetch/post-drain
//EMAX5A begin imax mapdist=0
for (CHIP=0; CHIP<NCHIP; CHIP++) {
for (INIT1=1,LOOP1=RMGRP,rofs=0; LOOP1--; INIT1=0) {
for (INIT0=1,LOOP0=M2,cofs=0; LOOP0--; INIT0=0) {
mop(OP_LDWR, 1, &r0, ibase0++, 0, MSK_D0, itop0, M2*RMGRP, 0, 0, itop1, M2*RMGRP);
exe(OP_ADD, &r1, r1, EXP_H3210, 0x100000000LL, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0LL);
exe(OP_NOP, &std, r1, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_OR, r0, OP_NOP, 0LL);
exe(OP_CMP_EQ, &cc0, r0, EXP_H1010, 0x00000000LL, EXP_H1010, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0LL);
exe(OP_CMP_EQ, &cc1, r0, EXP_H1010, 0x80000000LL, EXP_H1010, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0LL);
exe(OP_NOP, &cc2, cc0, EXP_H3210, 0, EXP_H3210, 0, EXP_H1010, OP_OR, cc1, OP_NOP, 0LL);
exe(OP_CMOV, &oofs, cc2, EXP_H3210, 0, EXP_H3210, 8, EXP_H3210, OP_NOP, 0, OP_NOP, 0LL);
exe(OP_ADD, &obase0, obase0, EXP_H3210, oofs, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0LL);
mop(OP_STR, 3, &obase0, Bas1P, 0, MSK_D0, Bas1P, 2, 0, 0, NULL, 2);
exe(OP_NOP, &AR[5][0], 0, EXP_H3210, 0, EXP_H3210, 0, EXP_H1010, OP_NOP, 0, OP_NOP, 0LL);
cex(OP_CEXE, &ex0, 0, 0, 0, cc2, 0x0001);
mop(OP_STR, ex0, &std, obase0, 0, MSK_D0, otop0, LP*2*RMGRP, 0, 0, otop1, LP*2*RMGRP);
}
}
}
//EMAX5A end
//EMAX5A drain_dirty_lmm
}
20210401
88
CPU GPU
Ultimate CGRA w/ high-speed compiler
CGRA for Energy-efficient Cryptography
Beyond-Neuromorphic Systems
Non-Deterministic Computing
20210401
89
ナレータ VOICEVOX:もち子(cv 明日葉よもぎ)
はらぺこエンジニアに贈るCGRAの世界2022
(ハッシュ計算とFFTと文字列検索)
スパコンからIoTまで 省エネ社会に
AI+BCだけじゃない超効率計算手法
20210401
90
ハッシュ計算には、面倒な演算が必要
for (i=0; i<ctx->mbuflen; i+=BLKSIZE) { /* 1データ流内の並列実行は不可能. 多数データ流のパイプライン実行のみ */
for (th=0; th<thnum; th++) {
sregs[th*8+0] = state[th*8+0]; sregs[th*8+1] = state[th*8+1]; sregs[th*8+2] = state[th*8+2]; sregs[th*8+3] = state[th*8+3];
sregs[th*8+4] = state[th*8+4]; sregs[th*8+5] = state[th*8+5]; sregs[th*8+6] = state[th*8+6]; sregs[th*8+7] = state[th*8+7];
}
for (j=0; j<BLKSIZE; j+=BLKSIZE/DIV) {
for (th=0; th<thnum; th++) {
a = sregs[th*8+0]; b = sregs[th*8+1]; c = sregs[th*8+2]; d = sregs[th*8+3];
e = sregs[th*8+4]; f = sregs[th*8+5]; g = sregs[th*8+6]; h = sregs[th*8+7];
#if (DIV==4)
t1 = h+EP1(e)+CH(e,f,g)+k[j+ 0]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 0]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+ 1]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 1]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+ 2]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 2]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+ 3]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 3]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+ 4]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 4]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+ 5]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 5]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+ 6]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 6]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+ 7]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 7]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+ 8]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 8]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+ 9]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 9]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+10]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+10]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+11]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+11]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+12]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+12]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+13]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+13]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+14]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+14]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
t1 = h+EP1(e)+CH(e,f,g)+k[j+15]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+15]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2;
#endif
sregs[th*8+0] = a; sregs[th*8+1] = b; sregs[th*8+2] = c; sregs[th*8+3] = d;
sregs[th*8+4] = e; sregs[th*8+5] = f; sregs[th*8+6] = g; sregs[th*8+7] = h;
}
}
for (th=0; th<thnum; th++) {
state[th*8+0] += sregs[th*8+0]; state[th*8+1] += sregs[th*8+1]; state[th*8+2] += sregs[th*8+2]; state[th*8+3] += sregs[th*8+3];
state[th*8+4] += sregs[th*8+4]; state[th*8+5] += sregs[th*8+5]; state[th*8+6] += sregs[th*8+6]; state[th*8+7] += sregs[th*8+7];
}
}
20210401
91
ハッシュ計算には、面倒な演算が必要
case OP_MAJ: /* (((x) & (y))^((x) & (z))^((y) & (z))) */
ex1_outd = (r1&0xffffffff00000000LL) | (((r1 & r2)^(r1 & r3)^(r2 & r3))&0xffffffffLL);
case OP_CH: /* (((x) & (y))^(~(x) & (z))) */
ex1_outd = (r1&0xffffffff00000000LL) | (((r1 & r2)^(~r1 & r3))&0xffffffffLL);
case OP_ROTS: /* hi-32bit #define ROTRIGHT (((a) >> (b)) | ((a) << (32-(b)))) */
t2 = ex1_outd & 0xffffffff00000000LL;
ro10 = r4>>32 & 0xff;
ro11 = r4>>40 & 0xff;
ro12 = r4>>48 & 0xff;
t0 = ex1_outd & 0x00000000ffffffffLL;
ro00 = r4 & 0xff;
ro01 = r4>> 8 & 0xff;
ro02 = r4>>16 & 0xff;
ex2_outd = (((t2>>ro12|t2<<(32-ro12))^(t2>>ro11|t2<<(32-ro11))^(t2>>ro10|t2<<(32-ro10)))&0xffffffff00000000LL)
|(((t0>>ro02|t0<<(32-ro02))^(t0>>ro01|t0<<(32-ro01))^(t0>>ro00|t0<<(32-ro00)))&0x00000000ffffffffLL);
exe(OP_MAJ, &ep0maj, a, EXP_H1010, fb, EXP_H1010, gc, EXP_H1010, OP_ROTS, (2LL<<48)|(13LL<<40)|(22LL<<32). NOP,0);
exe(OP_CH, &ep1ch, e, EXP_H3232, fb, EXP_H3232, gc, EXP_H3232, OP_ROTS, (6LL<<48)|(11LL<<40)|(25LL<<32), NOP,0);
20210401
92
ハッシュ計算のコンパイル結果
20210401
93
FFTには、ダブルバッファリングが必要
BlockEnd = 1;
for (BlockSize=2; BlockSize<=NumSamples; BlockSize<<=1) {
for (i=0; i<NumSamples; i+=BlockSize) {
for (j=i,n=0; n<BlockEnd; j++,n++) {
k = j + BlockEnd;
idx = n + BlockEnd;
tr = art[idx]*RealOut[k] - ait[idx]*ImagOut[k];
ti = art[idx]*ImagOut[k] + ait[idx]*RealOut[k];
RealOut[k] = RealOut[j] - tr;
ImagOut[k] = ImagOut[j] - ti;
RealOut[j] += tr;
ImagOut[j] += ti;
}
}
BlockEnd = BlockSize;
} 1段目 2段目 3段目
20210401
94
FFTのコンパイル結果
20210401
95
文字列検索
void strsearch(int i)
{
char *str = sstr[i];
int len = slen[i];
register size_t shift;
register size_t pos = len - 1;
char *found;
while (pos < clen) {
while (pos < clen && (shift = table[(unsigned char)target[pos]]) > 0)
pos += shift;
if (!shift) {
if (!strncmp(str, &target[pos-len+1], len))
out0[i*clen+(pos-len+1)] = 0xff;
pos++;
} } }
20210401
96
文字列検索
for (i=0; i<snum; i+=OMAP) {
//EMAX5A begin search mapdist=0
for (CHIP=0; CHIP<NCHIP; CHIP++) { //チップ方向は検索対象文書の大きさ方向
for (INIT0=1,LOOP0=loop,dmy=0; LOOP0--; INIT0=0) { //長さは32KB文字まで
/* map#0 */
exe(OP_ADD, &t0[CHIP], t0[CHIP], EXP_H3210, 1LL, EXP_H3210, 0LL, EXP_H3210, OP_AND, 0x0000ffffffffffffLL, OP_NOP, 0LL);
exe(OP_MCAS, &r00, slen0, EXP_H3210, 1, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe(OP_MCAS, &r01, slen0, EXP_H3210, 2, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe(OP_MCAS, &r02, slen0, EXP_H3210, 3, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe(OP_MCAS, &r03, slen0, EXP_H3210, 4, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
mop(OP_LDBR, 1, &BR[1][0][1], t0[CHIP], 0, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi);
mop(OP_LDBR, 1, &BR[1][0][0], t0[CHIP], 1, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi);
mop(OP_LDBR, 1, &BR[1][1][1], t0[CHIP], 2, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi);
mop(OP_LDBR, 1, &BR[1][1][0], t0[CHIP], 3, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi);
mop(OP_LDBR, 1, &BR[1][2][1], t0[CHIP], 4, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi);
mop(OP_LDBR, 1, &BR[1][2][0], t0[CHIP], 5, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi);
mop(OP_LDBR, 1, &BR[1][3][1], t0[CHIP], 6, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi);
mop(OP_LDBR, 1, &BR[1][3][0], t0[CHIP], 7, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi);
exe(OP_CMP_NE, &r16, c00, EXP_H3210, BR[1][0][1], EXP_H3210, 0LL, EXP_H3210, OP_AND, r00, OP_NOP, 0LL); // 1 if unmatch
exe(OP_CMP_NE, &r17, c01, EXP_H3210, BR[1][0][0], EXP_H3210, 0LL, EXP_H3210, OP_AND, r01, OP_NOP, 0LL); // 1 if unmatch
exe(OP_CMP_NE, &r18, c02, EXP_H3210, BR[1][1][1], EXP_H3210, 0LL, EXP_H3210, OP_AND, r02, OP_NOP, 0LL); // 1 if unmatch
exe(OP_CMP_NE, &r19, c03, EXP_H3210, BR[1][1][0], EXP_H3210, 0LL, EXP_H3210, OP_AND, r03, OP_NOP, 0LL); // 1 if unmatch
exe(OP_MCAS, &r04, slen0, EXP_H3210, 5, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe(OP_MCAS, &r05, slen0, EXP_H3210, 6, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe(OP_MCAS, &r06, slen0, EXP_H3210, 7, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe(OP_MCAS, &r07, slen0, EXP_H3210, 8, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
exe(OP_CMP_NE, &r20, c04, EXP_H3210, BR[1][2][1], EXP_H3210, 0LL, EXP_H3210, OP_AND, r04, OP_NOP, 0LL); // 1 if unmatch
exe(OP_CMP_NE, &r21, c05, EXP_H3210, BR[1][2][0], EXP_H3210, 0LL, EXP_H3210, OP_AND, r05, OP_NOP, 0LL); // 1 if unmatch
exe(OP_CMP_NE, &r22, c06, EXP_H3210, BR[1][3][1], EXP_H3210, 0LL, EXP_H3210, OP_AND, r06, OP_NOP, 0LL); // 1 if unmatch
exe(OP_CMP_NE, &r23, c07, EXP_H3210, BR[1][3][0], EXP_H3210, 0LL, EXP_H3210, OP_AND, r07, OP_NOP, 0LL); // 1 if unmatch
exe(OP_ADD3, &r10, r16, EXP_H3210, r17, EXP_H3210, r18, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); //
exe(OP_ADD3, &r11, r19, EXP_H3210, r20, EXP_H3210, r21, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); //
exe(OP_ADD, &r12, r22, EXP_H3210, r23, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); //
exe(OP_ADD3, &r00, r10, EXP_H3210, r11, EXP_H3210, r12, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); //
exe(OP_MCAS, &r31, 0LL, EXP_H3210, r00, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); // FF if match
mop(OP_STBR, 3, &r31, r0[CHIP]++, 0, MSK_D0, r0t[CHIP], dwo, 0, 0, (Ull)NULL, dwo);
/* map#1 */
:
/* map#8 */
:
}
}
//EMAX5A end
//EMAX5A drain_dirty_lmm
}
20210401
97
文字列検索のコンパイル結果
CPU GPU
Ultimate CGRA w/ high-speed compiler
CGRA for Energy-efficient Cryptography
Beyond-Neuromorphic Systems
Non-Deterministic Computing
98
ナレータ VOICEVOX:もち子(cv 明日葉よもぎ)
はらぺこエンジニアに贈るCGRAの世界2022
(高速コンパイラ)
スパコンからIoTまで 省エネ社会に
AI+BCだけじゃない超効率計算手法
20210401
99
FMA C+B*A ⇒ D
Dual Random access
20210401
100
FMA C+B*A ⇒ D
D has location info (same as C)
Sequential updates
20210401
101
FMA C+B*A ⇒ C
Accumulation
20210401
102
コンパイル過程 src/conv-mark/conv-mark の入力
void tone_curve(r, d, t)
unsigned int *r, *d;
unsigned char *t;
{
#if !defined(EMAX5) && !defined(EMAX6)
int j;
for (j=0; j<WD; j++) {
*d = ((t)[*r>>24])<<24 | (t[256+((*r>>16)&255)])<<16 | (t[512+((*r>>8)&255)])<<8;
r++; d++;
}
#else
Ull t1 = t;
Ull t2 = t+256;
Ull t3 = t+512;
Ull BR[16][4][4]; /* output registers in each unit */
Ull r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15;
Ull r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31;
int loop=WD;
//EMAX5A begin tone_curve mapdist=0
while (loop--) {
mop(OP_LDWR, 1, &BR[0][1][1], (Ull)(r++), 0LL, MSK_D0, (Ull)r, 320, 0, 0, (Ull)NULL, 320); /* stage#0 */
mop(OP_LDUBR, 1, &BR[1][1][1], (Ull)t1, BR[0][1][1], MSK_B3, (Ull)t1, 64, 0, 0, (Ull)NULL, 64); /* stage#1 */
mop(OP_LDUBR, 1, &BR[1][2][1], (Ull)t2, BR[0][1][1], MSK_B2, (Ull)t2, 64, 0, 0, (Ull)NULL, 64); /* stage#1 */
mop(OP_LDUBR, 1, &BR[1][3][1], (Ull)t3, BR[0][1][1], MSK_B1, (Ull)t3, 64, 0, 0, (Ull)NULL, 64); /* stage#1 */
exe(OP_MMRG, &r1, BR[1][1][1], EXP_H3210, BR[1][2][1], EXP_H3210, BR[1][3][1], EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL);
mop(OP_STWR, 3, &r1, (Ull)(d++), 0LL, MSK_D0, (Ull)d, 320, 0, 0, (Ull)NULL, 320); /* stage#2 */
}
//EMAX5A end
#endif
}
 filter+rmm.c
20210401
103
コンパイル過程 通常のARM-Cコンパイラの入力 1/3
 filter+rmm-emax6.c ../../src/conv-c2c/emax6.h ../../src/conv-c2c/emax6lib.c
void tone_curve(r, d, t)
unsigned int *r, *d;
unsigned char *t;
{
Ull t1 = t;
Ull t2 = t+256;
Ull t3 = t+512;
Ull BR[16][4][4];
Ull r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31;
int loop=WD;
volatile emax6_conf_tone_curve();
emax6.lmmio = emax6.lmmic;
emax6.lmmic = 1-emax6.lmmic;
emax6.mapdist = 0;
*(Uint*)&emax6.lmmi[0][0][1][emax6.lmmic] = 0x013f0001|(0<<2);
emax6.lmmi[0][0][1][emax6.lmmic].ofs = 0; emax6.lmmi[0][0][1][emax6.lmmic].top = r;
*(Uint*)&emax6.lmmi[0][1][1][emax6.lmmic] = 0x003f0001|(0<<2);
emax6.lmmi[0][1][1][emax6.lmmic].ofs = 0; emax6.lmmi[0][1][1][emax6.lmmic].top = t1;
*(Uint*)&emax6.lmmi[0][1][2][emax6.lmmic] = 0x003f0001|(0<<2);
emax6.lmmi[0][1][2][emax6.lmmic].ofs = 0; emax6.lmmi[0][1][2][emax6.lmmic].top = t2;
*(Uint*)&emax6.lmmi[0][1][3][emax6.lmmic] = 0x003f0001|(0<<2);
emax6.lmmi[0][1][3][emax6.lmmic].ofs = 0; emax6.lmmi[0][1][3][emax6.lmmic].top = t3;
*(Uint*)&emax6.lmmi[0][2][0][emax6.lmmic] = 0x013f0003|(0<<2);
emax6.lmmi[0][2][0][emax6.lmmic].ofs = 0; emax6.lmmi[0][2][0][emax6.lmmic].top = d;
emax6.lmmi_bitmap[0] = 0x0000000000000004LL;
emax6.lmmi_bitmap[1] = 0x0000000000000003LL;
emax6.lmmi_bitmap[2] = 0x0000000000000002LL;
emax6.lmmi_bitmap[3] = 0x0000000000000002LL;
emax6_pre_with_drain_cache();
get_nanosec(NANOS_ARM);
if (emax6.last_conf == emax6_conf_tone_curve) {
emax6.status = STATUS_DRAIN;
emax6_check_lmmi_and_dma(0, 1, 0, 0, 2, 0);/*drain*/
}
get_nanosec(NANOS_DRAIN);
LMMのアドレス範囲情報
必要に応じて前回演算結果の回収
20210401
104
コンパイル過程 通常のARM-Cコンパイラの入力 2/3
if (emax6.last_conf != emax6_conf_tone_curve) {
Dll *dst, *src;
int i,j;
emax6.status = STATUS_CONF;
emax6.last_conf = emax6_conf_tone_curve;
emax6.lastdist = 0;
dst = (Dll*)(((struct reg_ctrl*)emax6.reg_ctrl)->i[0].conf);
src = (Dll*)emax6_conf_tone_curve;
for (i=0; i<sizeof(conf)/sizeof(Dll); i++)
*dst++ = *src++;
for (i=0; i<64; i++) {
for (j=0; j<4; j++)
emax6.lmmi[0][i][j][emax6.lmmio].v = 0;
}
while (((struct reg_ctrl*)emax6.reg_ctrl)->i[0].stat & 0xf0); //LMRING_BUSY
}
get_nanosec(NANOS_CONF);
emax6.status = STATUS_REGV;
((struct reg_ctrl*)emax6.reg_ctrl)->i[0].breg[63][0].br[0] = loop;
((struct reg_ctrl*)emax6.reg_ctrl)->i[0].breg[63][0].br[1] = -1LL;
((struct reg_ctrl*)emax6.reg_ctrl)->i[0].addr[0][1].ea1b = (Ull)r;
((struct reg_ctrl*)emax6.reg_ctrl)->i[0].addr[0][1].ea1o = (Ull)0LL;
((struct reg_ctrl*)emax6.reg_ctrl)->i[0].addr[1][1].ea1b = (Ull)t1;
((struct reg_ctrl*)emax6.reg_ctrl)->i[0].addr[1][2].ea1b = (Ull)t2;
((struct reg_ctrl*)emax6.reg_ctrl)->i[0].addr[1][3].ea1b = (Ull)t3;
((struct reg_ctrl*)emax6.reg_ctrl)->i[0].addr[2][0].ea0b = (Ull)d;
((struct reg_ctrl*)emax6.reg_ctrl)->i[0].addr[2][0].ea0o = (Ull)0LL;
get_nanosec(NANOS_REGV);
emax6.status = STATUS_RANGE;
{struct reg_ctrl *reg_ctrl = emax6.reg_ctrl;
Uint lmmic = emax6.lmmic;
*(Ull*)&(reg_ctrl->i[0].addr[0][1].top)=((Ull)(emax6.lmmi[0][0][1][lmmic].top+*((Ushort*)&emax6.lmmi[0][0][1][lmmic]+1)*sizeof(Uint)+(sizeof(Uint)-1))<<32)|(Ull)(Uint)emax6.lmmi[0][0][1][lm
*(Ull*)&(reg_ctrl->i[0].addr[1][1].top)=((Ull)(emax6.lmmi[0][1][1][lmmic].top+*((Ushort*)&emax6.lmmi[0][1][1][lmmic]+1)*sizeof(Uint)+(sizeof(Uint)-1))<<32)|(Ull)(Uint)emax6.lmmi[0][1][1][lm
*(Ull*)&(reg_ctrl->i[0].addr[1][2].top)=((Ull)(emax6.lmmi[0][1][2][lmmic].top+*((Ushort*)&emax6.lmmi[0][1][2][lmmic]+1)*sizeof(Uint)+(sizeof(Uint)-1))<<32)|(Ull)(Uint)emax6.lmmi[0][1][2][lm
*(Ull*)&(reg_ctrl->i[0].addr[1][3].top)=((Ull)(emax6.lmmi[0][1][3][lmmic].top+*((Ushort*)&emax6.lmmi[0][1][3][lmmic]+1)*sizeof(Uint)+(sizeof(Uint)-1))<<32)|(Ull)(Uint)emax6.lmmi[0][1][3][lm
*(Ull*)&(reg_ctrl->i[0].addr[2][0].top)=((Ull)(emax6.lmmi[0][2][0][lmmic].top+*((Ushort*)&emax6.lmmi[0][2][0][lmmic]+1)*sizeof(Uint)+(sizeof(Uint)-1))<<32)|(Ull)(Uint)emax6.lmmi[0][2][0][lm
}
get_nanosec(NANOS_RANGE);
命令写像が前回と異なる場合は
再写像
AXIIF/PIOによるレジスタ初期化
LMMにアドレス範囲情報書き込み
20210401
105
コンパイル過程 通常のARM-Cコンパイラの入力 3/3
emax6.status = STATUS_LOAD;
emax6_check_lmmi_and_dma(0, 2, emax6.lastdist, 0, 0, 1);/*load*/
emax6_check_lmmi_and_dma(0, 2, emax6.lastdist, 0, 1, 1);/*load*/
emax6_check_lmmi_and_dma(0, 2, emax6.lastdist, 0, 1, 2);/*load*/
emax6_check_lmmi_and_dma(0, 2, emax6.lastdist, 0, 1, 3);/*load*/
get_nanosec(NANOS_LOAD);
((struct reg_ctrl*)emax6.reg_ctrl)->i[0].cmd = 3LL; // EXEC
{struct reg_ctrl *reg_ctrl = emax6.reg_ctrl;
Uint lmmic = emax6.lmmic;
}
emax6.lmmd[2][0] = 0xff>>7;
while (((struct reg_ctrl*)emax6.reg_ctrl)->i[0].stat); //LMRING_BUSY|EXRING_BUSY
get_nanosec(NANOS_EXEC);
asm volatile("b emax6_conf_end_tone_curven"
".align 5n"
".global emax6_conf_tone_curven"
"emax6_conf_tone_curve:n"
" .word 0x031e0003, 0x00000000n"
" .word 0xffff0000, 0x00000000n"
" .word 0x00000000, 0x00000000n"
:
" .word 0xffff0000, 0x00000000n"
" .word 0x00000000, 0x00000000n"
" .word 0x00000000, 0x00000000n"
".global emax6_conf_end_tone_curven"
"emax6_conf_end_tone_curve:n"
);
}
AXIIF/DMAによる
LMMデータ書き込み
AXIIF/PIOによるIMAX起動
演算と同時の次データ転送が
あればDMA起動
UNITのconfiguration情報
ld @(gr1, 0) -> gr2
add gr1, 4 -> gr1
sub gr3, 1 -> gr3, z
VLIW0
add sub
gr1 gr3z
Register File
gr1 4 gr3 1
eag
gr1 4
0 1 2 3 4 5 6
0 0 0 0 0 0 0
0 1 2 3 4 5 6
0 0 0 0 0 0 0
0 1 2 3 4 5 6
0 0 0 0 0 0 0
0 1 2 3 4 5 6
0 0 0 0 0 0 0
0 1 2 3 4 5 6
0 0 0 0 0 0 0
z
0
z
0
z
0
z
0
z
0
gr2
ld
Propagation skip table
gr/cr
Stage
0
1
2
3
4
20210401
106
コンパイルが速いのは、非探索的だから
ld @(gr4, 0) -> gr5
add gr4, 4 -> gr4
bz end
VLIW1
add sub
gr1 gr3z
add
gr4
Register File
gr1 4
gr4 4
gr3 1 gr4
bz
end
eag
eag
gr1 4
gr4 4
0 1 2 3 4 5 6
0 1 1 1 0 0 0
0 1 2 3 4 5 6
0 1 1 1 0 0 0
0 1 2 3 4 5 6
0 0 1 0 0 0 0
0 1 2 3 4 5 6
0 0 0 0 0 0 0
0 1 2 3 4 5 6
0 0 0 0 0 0 0
z
1
z
1
z
0
z
0
z
0
gr5
ld
gr2
ld
Propagation skip table
gr/cr
Stage
0
1
2
3
4
VLIW1
20210401
107
LAPPと同様の非探索的高速コンパイル手法
gr5
ld
gr2
ld
sll gr2, 16 -> gr2
VLIW2
add sub
gr1 gr3z
add
gr4
sll
Register File
gr1 4
gr4 4
16
gr3 1
0 1 2 3 4 5 6
0 1 1 1 1 1 0
0 1 2 3 4 5 6
0 1 1 1 1 1 0
0 1 2 3 4 5 6
0 0 1 0 1 1 0
0 1 2 3 4 5 6
0 0 0 0 0 1 0
0 1 2 3 4 5 6
0 0 0 0 0 0 0
z
1
z
1
z
0
z
0
z
0
gr4
bz
end
eag
eag
gr1 4
gr4 4
Propagation skip table
gr/cr
Stage
0
1
2
3
4
VLIW2
VLIW2
20210401
108
LAPPと同様の非探索的高速コンパイル手法
gr5
ld
gr2
ld
or gr2, gr5 -> gr5
VLIW3
add sub
gr1 gr3z
add
gr4
gr2
Register File
or
gr5
gr1 4
gr4 4
gr3 1
0 1 2 3 4 5 6
0 1 1 1 1 1 0
0 1 2 3 4 5 6
0 1 1 1 1 1 0
0 1 2 3 4 5 6
0 0 1 0 1 1 0
0 1 2 3 4 5 6
0 0 1 0 0 1 0
0 1 2 3 4 5 6
0 0 0 0 0 0 0
z
1
z
1
z
0
z
0
z
0
gr4
bz
end
eag
eag
gr1 4
gr4 4
Propagation skip table
gr/cr
Stage
0
1
2
3
4
sll
16
VLIW3
VLIW3
VLIW3
20210401
109
LAPPと同様の非探索的高速コンパイル手法
gr5
gr2
ld
st, gr5 -> @(gr6, 0)
add gr6, 4 -> gr6
bra loop
VLIW4
add sub
gr1 gr3z
add
gr4
Register File
gr5 gr5
add
gr6
gr1 4
gr4 4
16
gr6
gr6 4
gr6
gr6
gr3 1
0 1 2 3 4 5 6
0 1 1 1 1 1 0
0 1 2 3 4 5 6
0 1 1 1 1 1 0
0 1 2 3 4 5 6
0 0 1 0 1 1 0
0 1 2 3 4 5 6
0 0 1 0 0 1 0
0 1 2 3 4 5 6
0 0 0 0 0 1 0
z
1
z
1
z
0
z
0
z
0
gr4 gr6
bz
bra
end
loop
eag
eag
eag
gr1 4
gr4 4
gr6 0
st
Propagation skip table
gr/cr
Stage
0
1
2
3
4
gr5
ld
gr2
or
sll
VLIW4
VLIW4
VLIW4
VLIW4
20210401
110
LAPPと同様の非探索的高速コンパイル手法
CPU GPU
Ultimate CGRA w/ high-speed compiler
CGRA for Energy-efficient Cryptography
Beyond-Neuromorphic Systems
Non-Deterministic Computing
111
ナレータ VOICEVOX:もち子(cv 明日葉よもぎ)
はらぺこエンジニアに贈るCGRAの世界2022
(超絶技巧3重ループ)
スパコンからIoTまで 省エネ社会に
AI+BCだけじゃない超効率計算手法
20210401
112
3重ループ=2重ループ+マルチIMAX
HOST
演算器はリング構造
メモリネットワークは8並列
20210401
113
2重ループの制御は、ユニット1つで実行
20210401
114
確率的積和演算の2次元データ一括処理
//EMAX5A begin smax2 mapdist=0
for (CHIP=0; CHIP<NCHIP; CHIP++) { /* will be parallelized by multi-chip (M/#chip) */
for (INIT1=1,LOOP1=RMGRP,rofs=(0-IC32)<<32|((0-1LL)&0xffffffff); LOOP1--; INIT1=0) {
for (INIT0=1,LOOP0=IC32/32,cofs=(0-32LL)<<32|((0)&0xffffffff); LOOP0--; INIT0=0) {
① exe(OP_ADD, &cofs, INIT0?cofs:cofs, EXP_H3210, 32LL<<32|0, EXP_H3210, 0, EXP_H3210, OP_AND, 0xffffffffffffffffLL, OP_NOP,0);
② exe(OP_ADD, &rofs, rofs, EXP_H3210, INIT0?IC321:0, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP,0);
③ exe(OP_ADD, &bofs, rofs, EXP_H3210, cofs, EXP_H3210, 0, EXP_H3210, OP_AND, 0xffffffffffffffffLL, OP_NOP,0);
④ exe(OP_ADD, &oofs, rofs, EXP_H3210, cofs, EXP_H3210, 0, EXP_H3210, OP_AND, 0x00000000ffffffffLL, OP_NOP,0);
spike01_core1( 2, 0);
spike01_core1( 3, 1);
spike01_core1( 4, 2);
spike01_core1( 5, 3);
spike01_core1( 6, 4);
spike01_core1( 7, 5);
spike01_core1( 8, 6);
#define spike01_core1(r, s) 
mo4(OP_LDRQ, 1, BR[r][2], b0, bofs, MSK_W1, b, IC32D4RMGRP, 0, 0, NULL, IC32D4RMGRP);
mo4(OP_LDRQ, 1, BR[r][1], a[s][CHIP], cofs, MSK_W1, a[s][CHIP], IC32D4, 0, 0, NULL, IC32D4 );
mop(OP_LDBR, 1, &b00, c0[s][CHIP], oofs, MSK_W0, c[s][CHIP], RMGRPD4, 0, 1, NULL, RMGRPD4 );
ex4(OP_SFMA, &b00, INIT0?b00:b00, EXP_H3210, BR[r][1], EXP_H3210, BR[r][2], EXP_H3210, OP_NOP,0, OP_NOP,0 );
mop(OP_STBR, 1, &b00, oofs, c0[s][CHIP], MSK_D0, c[s][CHIP], RMGRPD4, 0, 1, NULL, RMGRPD4 )
20210401
115
ベイズ推定に使う2次元データ一括処理
//EMAX5A begin x1 mapdist=0
for (INIT1=1,LOOP1=RMGRP,row=0-M*4; LOOP1--; INIT1=0) {
for (INIT0=1,LOOP0=M/W,bofs=0-W*4; LOOP0--; INIT0=0) {
exe(OP_ADD, &bofs, INIT0?bofs:bofs, EXP_H3210, W*4, EXP_H3210, 0, EXP_H3210, OP_AND, 0x00ffffffffLL, OP_NOP,0);
exe(OP_ADD, &row, row, EXP_H3210, INIT0?M*4:0, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP,0);
exe(OP_ADD, &rofs, row, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_AND, 0x00ffffffffLL, OP_NOP,0);
mop(OP_LDWR, 1, &b00, c600, rofs, MSK_W0, c60, M*RMGRP, 0, 1, NULL, M*RMGRP);
exe(OP_ADD, &b00, INIT0?b00:b00, EXP_H3210, PARAM, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP,0);
mop(OP_STWR, 1, &b00, rofs, c600, MSK_D0, c60, M*RMGRP, 0, 1, NULL, M*RMGRP);
20210401
116
疎行列積に使う2次元データ一括処理
//EMAX5A begin imax mapdist=0
for (CHIP=0; CHIP<NCHIP; CHIP++) { /* will be parallelized by multi-chip (M/#chip) */
for (INIT1=1,LOOP1=RMGRP,rofs=(0-LP*8)<<32|((0-4LL)&0xffffffff); LOOP1--; INIT1=0) {
for (INIT0=1,LOOP0=LP,cofs=(0LL)<<32|((0LL)&0xffffffff); LOOP0--; INIT0=0) {
exe(OP_ADD, &rofs, rofs, EXP_H3210, INIT0?(LP*8)<<32|4:0, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP,0);
exe(OP_ADD, &bofs, rofs, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_AND, 0xffffffff00000000LL, OP_NOP,0);
exe(OP_ADD, &oofs, rofs, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_AND, 0x00000000ffffffffLL, OP_NOP,0);
sparse_core1( 2, 0);
sparse_core1( 3, 1); /* H=2 */
sparse_core1( 4, 2);
sparse_core1( 5, 3); /* H=4 */
sparse_core1( 6, 4);
sparse_core1( 7, 5);
sparse_core1( 8, 6);
sparse_core1( 9, 7); /* H=8 */
sparse_core1( 10, 8);
sparse_core1( 11, 9);
sparse_core1( 12, 10);
#define sparse_core1(r, h) 
mex(OP_CMPA_LE, &b0[h],INIT0?b:b0[h],INIT0?0:8,OP_CMPA_GE,&a0[h][CHIP],INIT0?a[h][CHIP]:a0[h][CHIP],INIT0?0:8,0,BR[r][2][1],……);
mop(OP_LDR, 3, &BR[r][2][1], b0[h], bofs, MSK_W1, b, 2*LP*RMGRP, 0, 0, NULL, 2*LP*RMGRP );
mop(OP_LDR, 3, &BR[r][2][0], a0[h][CHIP], bofs, MSK_W0, a[h][CHIP], 2*LP, 0, 0, NULL, 2*LP );
exe(OP_NOP, &AR[r][0], 0, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP,0);
mop(OP_LDWR, 1, &c00, c0[h][CHIP], oofs, MSK_W0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP );
exe(OP_CFMA, &c00, INIT0?c00:c00, EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][2][0], EXP_H3210, OP_NOP, 0, OP_NOP,0);
mop(OP_STWR, 1, &c00, oofs, c0[h][CHIP], MSK_D0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP )
CPU GPU
Ultimate CGRA w/ high-speed compiler
CGRA for Energy-efficient Cryptography
Beyond-Neuromorphic Systems
Non-Deterministic Computing
117
ナレータ VOICEVOX:もち子(cv 明日葉よもぎ)
はらぺこエンジニアに贈るCGRAの世界2022
(HW/SW協調設計)
20210401
118
Templates for IMAX programming
exe(OP_X, &var|&AR[0-63][0-3], s1, e1, s2, e2, s3, e3, OP_Y, s4, OP_Z, s5)
ex4(OP_X, &var|&AR[0-63], s1, e1, s2, e2, s3, e3, OP_Y, s4, OP_Z, s5)
exe(OP_X, &var, INIT0?var:var, e1, s2, e2, s3, e3, OP_Y, s4, OP_Z, s5)
exe(OP_X, &var, var, e1, INIT0?s2:0, e2, s3, e3, OP_Y, s4, OP_Z, s5)
mex(OP MEX2, &s2, INIT0?s20:s2, INIT0?0:expr,
OP MEX1, &s1, INIT0?s10:s1, INIT0?0:expr, limit, BR[0-63][0-3][1], BR[0-63][0-3][0])
cex(OP_CEXE, &ex0-9, c3, c2, c1, c0, 16bit-pattern)
mop(OP_X, ex9-0, &src|&dst, base, offset, mask, top, len, block, force, ptop, plen)
mo4(OP_X, ex9-0, &src|&dst, base, offset, mask, top, len, block, force, ptop, plen)
DMA information
Original C C+IMAX-code Target
(A) Intel-PC Native Intel-emax6lib Intel-CC Intel-CC Algorithm
(B) Intel-PC Simulator ARM+emax6lib ARM-XCC ARM-XCC(cross compiler) Algorithm
(C) Intel-PC Simulator IMAX/PIO Conv-c2c + ARM-XCC IMAX-code
(D) Intel-PC Simulator IMAX/DMA Conv-c2c + ARM-XCC IMAX-code + testbench
(E) Verilog Simulator Vsim + Testbench Verilog
(F) FPGA+Chipscope Vivado + hw_server Real Hardware
(G) ARM-SoC ARM+emax6lib ARM-CC Conv-c2c + ARM-CC Algorithm
(H) ARM-SoC IMAX/PIO Conv-c2c + ARM-CC Hardware w/o DMA
(I) ARM-SoC IMAX/DMA Conv-c2c + ARM-CC Performance
Conv-c2c (IMAX-CC) runs on CentOS/FreeBSD/ARM-SoC
- IMAX-code is translated to IMAX-config + DMA sequence, and embedded in ARM binary.
Simulator (csim) runs on CentOS/FreeBSD
- Register transfer level simulator
- ARMv8, 64cores, 32threads/core, L1+L2cache/core, L2-directory
reorder-buffer, parameterized memory hierarchy
- 64 IMAX, AXI4-IF, test-bench generator
20210401
119
HW/SW codesign
/* SCREEN=WD*HT */
for (row=0; row<HT; row++) {
for (col=0; col<WD; col++) {
pix = in[row*WD+col];
r = t[ pix>>24 ];
g = t[256+((pix>>16)&255)];
b = t[512+((pix>> 8)&255)];
out[row*WD+col]=r<<24 | g<<16 | b<<8;
} }
20210401
120
簡単な tone_curveをC言語で書く
Load →
Store ←
Color map tables
/* SCREEN=WD*HT */
for (row=0; row<HT; row++) {
//EMAX5A begin tone_curve mapdist=0
for (LOOP0=WD, col=-4; LOOP0--;) {
col += 4;
pix = in[row*WD+col/4];
r = t[ pix>>24 ];
g = t[256+((pix>>16)&255)];
b = t[512+((pix>> 8)&255)];
out[row*WD+col/4]=r<<24 | g<<16 | b<<8;
}
//EMAX5A end
}
//EDMAX5A drain_dirty_lmm
20210401
121
IMAXのループ構造記述に合わせる
Load →
Store ←
Color map tables
/* SCREEN=WD*HT */
for (row=0; row<HT; row++) {
for (col=0; col<WD; col++) {
pix = in[row*WD+col];
r = t[ pix>>24 ];
g = t[256+((pix>>16)&255)];
b = t[512+((pix>> 8)&255)];
out[row*WD+col]=r<<24 | g<<16 | b<<8;
} }
Load →
Store ←
Color map tables
/* SCREEN=WD*HT */
for (row=0; row<HT; row++) {
//EMAX5A begin tone_curve mapdist=0
for (LOOP0=WD, col=-4; LOOP0--;) {
col += 4;
mop(OP_LDWR, &pix, in_row_WD, col, MSK_W0, in, WD); //pix = in[row*WD+col/4];
mop(OP_LDUBR, &r, t_r, pix, MSK_B3, t, 256*3/4); //r = t[ pix>>24 ];
mop(OP_LDUBR, &g, t_g, pix, MSK_B2, t, 256*3/4); //g = t[256+((pix>>16)&255)];
mop(OP_LDUBR, &b, t_b, pix, MSK_B1, t, 256*3/4); //b = t[512+((pix>> 8)&255)];
out[row*WD+col/4]=r<<24|g<<16|b<<8;
}
//EMAX5A end
}
//EDMAX5A drain_dirty_lmm
20210401
122
IMAXの高機能関数記述に書き換えながらデバッグする
Load →
Store ←
Color map tables
/* SCREEN=WD*HT */
for (row=0; row<HT; row++) {
//EMAX5A begin tone_curve mapdist=0
for (LOOP0=WD, col=-4; LOOP0--;) {
exe(OP_ADD, &col, col, EXP_H3210, 4, EXP_H3210, 0, EXP_H3210); //col += 4;
mop(OP_LDWR, &pix, in_row_WD, col, MSK_W0, in, WD); //pix = in[row*WD+col/4];
mop(OP_LDUBR, &r, t_r, pix, MSK_B3, t, 256*3/4); //r = t[ pix>>24 ];
mop(OP_LDUBR, &g, t_g, pix, MSK_B2, t, 256*3/4); //g = t[256+((pix>>16)&255)];
mop(OP_LDUBR, &b, t_b, pix, MSK_B1, t, 256*3/4); //b = t[512+((pix>> 8)&255)];
exe(OP_MMRG, &out, r, EXP_H3210, g, EXP_H3210, b, EXP_H3210);
mop(OP_STWR, &out, out_row_WD, col, MSK_W0); //out[row*WD+col/4]=r<<24|g<<16|b<<8;
}
//EMAX5A end
}
//EDMAX5A drain_dirty_lmm
20210401
123
全部書き換えたら逐次実行プログラムとしてデバッグ
Load →
Store ←
Color map tables
20210401
124
データの配置と流れの観点から見直す
Load →
Store ←
Color map tables
/* SCREEN=WD*HT */
for (row=0; row<HT; row++) {
//EMAX5A begin tone_curve mapdist=0
for (LOOP0=WD, col=-4; LOOP0--;) {
exe(OP_ADD, &col, col, EXP_H3210, 4, EXP_H3210, 0, EXP_H3210); //col += 4;
mop(OP_LDWR, &pix, in_row_WD, col, MSK_W0, in, WD); //pix = in[row*WD+col/4];
mop(OP_LDUBR, &r, t_r, pix, MSK_B3, t, 256*3/4); //r = t[ pix>>24 ];
mop(OP_LDUBR, &g, t_g, pix, MSK_B2, t, 256*3/4); //g = t[256+((pix>>16)&255)];
mop(OP_LDUBR, &b, t_b, pix, MSK_B1, t, 256*3/4); //b = t[512+((pix>> 8)&255)];
exe(OP_MMRG, &out, r, EXP_H3210, g, EXP_H3210, b, EXP_H3210);
mop(OP_STWR, &out, out_row_WD, col, MSK_W0); //out[row*WD+col/4]=r<<24|g<<16|b<<8;
}
//EMAX5A end
}
//EDMAX5A drain_dirty_lmm
20210401
125
コンパイル結果
Load →
Store ←
Color map tables
20210401
126
ボードだけ買えば(50万~1650万)CGRA遊べる
20210401
127
HBM2 and VMK version will appear soon
IMAX2: Ultra-speed compilable CGRA 2022/12/XX
First CGRA, based on linear cores (not island-style)
32-unit, 1280-operations/4cycle (768-int32, 256-fp32, 256-media8/16,
512-load/store, 1024-stochastic-fma8, and 128-sparse-matrix)
IMAX2 32 cores 250MHz
1280 operations per 4 cycles
ALVEO-U280/U280
Memory/core: 64KB
Operations/core: 32-load/8-store, quad-sparse-load,
3-cascaded octa-int/media, octa-single-float FMA,
32-stochastic FMA
http://archlab.naist.jp/proj-arm64/fpga/U280-step4000-20221020.img.gz
IMAX2 32 cores 250MHz
1280 operations per 4 cycles
VMK180/VM1802
Memory/core: 64KB
Operations/core: 32-load/8-store, quad-sparse-load,
3-cascaded octa-int/media, octa-single-float FMA,
32-stochastic FMA
http://archlab.naist.jp/proj-arm64/fpga/VMK180-step4000-20221020.img.gz
仕様書、ファイル一式は公開済
20210401
128

More Related Content

Similar to PBL1-v1-200j.pptx

Androidとfpgaを高速fifo通信させちゃう
Androidとfpgaを高速fifo通信させちゃうAndroidとfpgaを高速fifo通信させちゃう
Androidとfpgaを高速fifo通信させちゃうksk sue
 
Adk互換モジュールのbt対応改造
Adk互換モジュールのbt対応改造Adk互換モジュールのbt対応改造
Adk互換モジュールのbt対応改造Reiko Yamashita
 
高位合成友の会@ドワンゴ,2015年12月8日
高位合成友の会@ドワンゴ,2015年12月8日高位合成友の会@ドワンゴ,2015年12月8日
高位合成友の会@ドワンゴ,2015年12月8日貴大 山下
 
ESP32特集の内容紹介
ESP32特集の内容紹介ESP32特集の内容紹介
ESP32特集の内容紹介Kenta IDA
 
GPU on OpenStack - GPUインターナルクラウドのベストプラクティス - OpenStack最新情報セミナー 2017年7月
GPU on OpenStack - GPUインターナルクラウドのベストプラクティス - OpenStack最新情報セミナー 2017年7月GPU on OpenStack - GPUインターナルクラウドのベストプラクティス - OpenStack最新情報セミナー 2017年7月
GPU on OpenStack - GPUインターナルクラウドのベストプラクティス - OpenStack最新情報セミナー 2017年7月VirtualTech Japan Inc.
 
Androidロボットサミットin愛媛
Androidロボットサミットin愛媛Androidロボットサミットin愛媛
Androidロボットサミットin愛媛Kenichi Yoshida
 
ソフトウェア無線入門 ~SDRでハムの世界はどう変わる?~ (2016.9.24)
ソフトウェア無線入門 ~SDRでハムの世界はどう変わる?~ (2016.9.24)ソフトウェア無線入門 ~SDRでハムの世界はどう変わる?~ (2016.9.24)
ソフトウェア無線入門 ~SDRでハムの世界はどう変わる?~ (2016.9.24)Koji Oyama
 
俺のTerraform CI/CD ライフサイクル
俺のTerraform CI/CD ライフサイクル俺のTerraform CI/CD ライフサイクル
俺のTerraform CI/CD ライフサイクルHonMarkHunt
 

Similar to PBL1-v1-200j.pptx (14)

Androidとfpgaを高速fifo通信させちゃう
Androidとfpgaを高速fifo通信させちゃうAndroidとfpgaを高速fifo通信させちゃう
Androidとfpgaを高速fifo通信させちゃう
 
2015圧縮ゼミ
2015圧縮ゼミ2015圧縮ゼミ
2015圧縮ゼミ
 
Adk2012
Adk2012Adk2012
Adk2012
 
ひとりLT大会
ひとりLT大会ひとりLT大会
ひとりLT大会
 
Takep lpc1114-190614
Takep lpc1114-190614Takep lpc1114-190614
Takep lpc1114-190614
 
Adk互換モジュールのbt対応改造
Adk互換モジュールのbt対応改造Adk互換モジュールのbt対応改造
Adk互換モジュールのbt対応改造
 
Ilerpg Study 005
Ilerpg Study 005Ilerpg Study 005
Ilerpg Study 005
 
高位合成友の会@ドワンゴ,2015年12月8日
高位合成友の会@ドワンゴ,2015年12月8日高位合成友の会@ドワンゴ,2015年12月8日
高位合成友の会@ドワンゴ,2015年12月8日
 
ESP32特集の内容紹介
ESP32特集の内容紹介ESP32特集の内容紹介
ESP32特集の内容紹介
 
Pdp11 on-fpga
Pdp11 on-fpgaPdp11 on-fpga
Pdp11 on-fpga
 
GPU on OpenStack - GPUインターナルクラウドのベストプラクティス - OpenStack最新情報セミナー 2017年7月
GPU on OpenStack - GPUインターナルクラウドのベストプラクティス - OpenStack最新情報セミナー 2017年7月GPU on OpenStack - GPUインターナルクラウドのベストプラクティス - OpenStack最新情報セミナー 2017年7月
GPU on OpenStack - GPUインターナルクラウドのベストプラクティス - OpenStack最新情報セミナー 2017年7月
 
Androidロボットサミットin愛媛
Androidロボットサミットin愛媛Androidロボットサミットin愛媛
Androidロボットサミットin愛媛
 
ソフトウェア無線入門 ~SDRでハムの世界はどう変わる?~ (2016.9.24)
ソフトウェア無線入門 ~SDRでハムの世界はどう変わる?~ (2016.9.24)ソフトウェア無線入門 ~SDRでハムの世界はどう変わる?~ (2016.9.24)
ソフトウェア無線入門 ~SDRでハムの世界はどう変わる?~ (2016.9.24)
 
俺のTerraform CI/CD ライフサイクル
俺のTerraform CI/CD ライフサイクル俺のTerraform CI/CD ライフサイクル
俺のTerraform CI/CD ライフサイクル
 

More from NAIST

PBL1-v1-200e.pptx
PBL1-v1-200e.pptxPBL1-v1-200e.pptx
PBL1-v1-200e.pptxNAIST
 
PBL1-v1-100e.pptx
PBL1-v1-100e.pptxPBL1-v1-100e.pptx
PBL1-v1-100e.pptxNAIST
 
PBL1-v1-014j.pptx
PBL1-v1-014j.pptxPBL1-v1-014j.pptx
PBL1-v1-014j.pptxNAIST
 
PBL1-v1-014e.pptx
PBL1-v1-014e.pptxPBL1-v1-014e.pptx
PBL1-v1-014e.pptxNAIST
 
PBL1-v1-013j.pptx
PBL1-v1-013j.pptxPBL1-v1-013j.pptx
PBL1-v1-013j.pptxNAIST
 
PBL1-v1-013e.pptx
PBL1-v1-013e.pptxPBL1-v1-013e.pptx
PBL1-v1-013e.pptxNAIST
 
PBL1-v1-012j.pptx
PBL1-v1-012j.pptxPBL1-v1-012j.pptx
PBL1-v1-012j.pptxNAIST
 
PBL1-v1-012e.pptx
PBL1-v1-012e.pptxPBL1-v1-012e.pptx
PBL1-v1-012e.pptxNAIST
 
PBL1-v1-011j.pptx
PBL1-v1-011j.pptxPBL1-v1-011j.pptx
PBL1-v1-011j.pptxNAIST
 
PBL1-v1-010j.pptx
PBL1-v1-010j.pptxPBL1-v1-010j.pptx
PBL1-v1-010j.pptxNAIST
 
PBL1-v1-009j.pptx
PBL1-v1-009j.pptxPBL1-v1-009j.pptx
PBL1-v1-009j.pptxNAIST
 
PBL1-v1-008j.pptx
PBL1-v1-008j.pptxPBL1-v1-008j.pptx
PBL1-v1-008j.pptxNAIST
 
PBL1-v1-007j.pptx
PBL1-v1-007j.pptxPBL1-v1-007j.pptx
PBL1-v1-007j.pptxNAIST
 
PBL1-v1-006j.pptx
PBL1-v1-006j.pptxPBL1-v1-006j.pptx
PBL1-v1-006j.pptxNAIST
 
PBL1-v1-005j.pptx
PBL1-v1-005j.pptxPBL1-v1-005j.pptx
PBL1-v1-005j.pptxNAIST
 
PBL1-v1-004j.pptx
PBL1-v1-004j.pptxPBL1-v1-004j.pptx
PBL1-v1-004j.pptxNAIST
 
PBL1-v1-003j.pptx
PBL1-v1-003j.pptxPBL1-v1-003j.pptx
PBL1-v1-003j.pptxNAIST
 
PBL1-v1-002j.pptx
PBL1-v1-002j.pptxPBL1-v1-002j.pptx
PBL1-v1-002j.pptxNAIST
 
PBL1-v0-200j.pptx
PBL1-v0-200j.pptxPBL1-v0-200j.pptx
PBL1-v0-200j.pptxNAIST
 

More from NAIST (19)

PBL1-v1-200e.pptx
PBL1-v1-200e.pptxPBL1-v1-200e.pptx
PBL1-v1-200e.pptx
 
PBL1-v1-100e.pptx
PBL1-v1-100e.pptxPBL1-v1-100e.pptx
PBL1-v1-100e.pptx
 
PBL1-v1-014j.pptx
PBL1-v1-014j.pptxPBL1-v1-014j.pptx
PBL1-v1-014j.pptx
 
PBL1-v1-014e.pptx
PBL1-v1-014e.pptxPBL1-v1-014e.pptx
PBL1-v1-014e.pptx
 
PBL1-v1-013j.pptx
PBL1-v1-013j.pptxPBL1-v1-013j.pptx
PBL1-v1-013j.pptx
 
PBL1-v1-013e.pptx
PBL1-v1-013e.pptxPBL1-v1-013e.pptx
PBL1-v1-013e.pptx
 
PBL1-v1-012j.pptx
PBL1-v1-012j.pptxPBL1-v1-012j.pptx
PBL1-v1-012j.pptx
 
PBL1-v1-012e.pptx
PBL1-v1-012e.pptxPBL1-v1-012e.pptx
PBL1-v1-012e.pptx
 
PBL1-v1-011j.pptx
PBL1-v1-011j.pptxPBL1-v1-011j.pptx
PBL1-v1-011j.pptx
 
PBL1-v1-010j.pptx
PBL1-v1-010j.pptxPBL1-v1-010j.pptx
PBL1-v1-010j.pptx
 
PBL1-v1-009j.pptx
PBL1-v1-009j.pptxPBL1-v1-009j.pptx
PBL1-v1-009j.pptx
 
PBL1-v1-008j.pptx
PBL1-v1-008j.pptxPBL1-v1-008j.pptx
PBL1-v1-008j.pptx
 
PBL1-v1-007j.pptx
PBL1-v1-007j.pptxPBL1-v1-007j.pptx
PBL1-v1-007j.pptx
 
PBL1-v1-006j.pptx
PBL1-v1-006j.pptxPBL1-v1-006j.pptx
PBL1-v1-006j.pptx
 
PBL1-v1-005j.pptx
PBL1-v1-005j.pptxPBL1-v1-005j.pptx
PBL1-v1-005j.pptx
 
PBL1-v1-004j.pptx
PBL1-v1-004j.pptxPBL1-v1-004j.pptx
PBL1-v1-004j.pptx
 
PBL1-v1-003j.pptx
PBL1-v1-003j.pptxPBL1-v1-003j.pptx
PBL1-v1-003j.pptx
 
PBL1-v1-002j.pptx
PBL1-v1-002j.pptxPBL1-v1-002j.pptx
PBL1-v1-002j.pptx
 
PBL1-v0-200j.pptx
PBL1-v0-200j.pptxPBL1-v0-200j.pptx
PBL1-v0-200j.pptx
 

PBL1-v1-200j.pptx

  • 1. CPU GPU Ultimate CGRA w/ high-speed compiler CGRA for Energy-efficient Cryptography Beyond-Neuromorphic Systems Non-Deterministic Computing 20210401 1 ナレータ VOICEVOX:もち子(cv 明日葉よもぎ) はらぺこエンジニアに贈るCGRAの世界2022 (ダイジェスト版) スパコンからIoTまで 省エネ社会に AI+BCだけじゃない超効率計算手法
  • 3. Insn.1 Insn.2 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 80-loops ALUALU I-Cache ALU ALU D-Cache Registers I-Cache ALU ALU D-Cache Regs. Regs. D-Cache Insn.1 Insn.2 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 All instructions are executed. I-Cache ALU ALU D-Cache Registers 3 Vect.Insn.1 Vect.Insn.2 Vect.Insn.3 Vect.Insn.4 Vect.Insn.5 Vect.Insn.6 Vect.Insn.7 Vect.Insn.8 Vector Registers Register File 20210401 3 ノイマン型(ぬるま湯)を捨て、非ノイマン型土俵で頭を使えということ "GoogleのTPUにも使われたシストリックアレイアー キテクチャとDeep Learningについて", 富士通研究 所技術講演会, Jul. (2017) "プログラマビリティを維持できる限界に向けて”, SONY本社研究紹介, Mar. (2020) "Deep Learningに向けたApproximate Computingと シストリックアレイアーキテクチャ", 革新的コン ピューティングの研究開発戦略検討会, CRDS/JST, Jul. (2017) "Approximate Computingとシストリックアレイ", ジス クソフト技術講演会, Dec. (2017) "99%メモリなアクセラレータIMAX(In Memory Accelerator eXtension)", CAE計算環境研究会@関 西シスラボ 第8回シンポジウム, Mar. (2017) "Systolic Arrays as The Last Frontiers", Invited talk in IPB Seminar and UI seminar @ Indonesia, Jan. (2019) “IMAX2: A CGRA with FPU+Multithreading+Chiplet", Panel: CGRA and their Opportunities as Application Accelerators, ASAP2021, invited panel, Jul. (2021) “コンピュータ(データセンタ)の消費電力低減策 意見交換会”, LCS/JST, Jul. (2021) "非ノイマン型の世界 -CGRAを含む最近の研究紹 介-", JEITAデバイス技術分科会招待講演, Nov. (2021) "CGRAのJITコンパイル化と高機能化の魔法教え ます", 回路とシステムワークショップ招待講演, Aug. (2022)
  • 5. for { iter=0 iter=1 iter=2 iter=3 iter=4 iter=5 iter=6 iter=7 } Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 VECTOR Insn.1 Insn.1 Insn.1 Insn.1 Insn.1 Insn.1 Insn.1 Insn.1 I-Cache ALU ALU D-Cache / Main Memory Registers EAG V-insn.1 ALU ALU ALU ALU ALU ALU V-insn.2 Insn.2 Insn.2 Insn.2 Insn.2 Insn.2 Insn.2 Insn.2 Insn.2 20210401 5
  • 6. for { iter=0 iter=1 iter=2 iter=3 iter=4 iter=5 iter=6 iter=7 } CGRA Insn.1 Insn.2 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Insn.1 Insn.2 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Insn.1 Insn.2 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Insn.1 Insn.2 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Insn.1 Insn.2 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Insn.1 Insn.2 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Insn.1 Insn.2 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Insn.1 Insn.2 Insn.3 Insn.4 Insn.5 Insn.6 Insn.7 Insn.8 Local Memory Registers EAG ALU ALU Local Memory Registers EAG ALU ALU Local Memory Registers EAG ALU ALU Local Memory Registers EAG ALU ALU Insn.1 Insn.2 Insn.3 Insn.4 Insn.1 Insn.2 Insn.1 Insn.2 Insn.5 Insn.6 Insn.3 Insn.4 Insn.1 Insn.2 Insn.3 Insn.4 Insn.1 Insn.2 Insn.1 Insn.2 Insn.7 Insn.8 Insn.5 Insn.6 Insn.3 Insn.4 Insn.1 Insn.2 Insn.5 Insn.6 Insn.3 Insn.4 Insn.1 Insn.2 Insn.3 Insn.4 Insn.1 Insn.2 Insn.1 Insn.2 20210401 6
  • 7. 20210401 7 Scalar, SIMD and CGRA time I1 L2 VST L2 VLD VLD VFMA I1 L2 VST L2 VLD VLD VFMA I1 L2 VST L2 VLD VLD VFMA I1 L2 VST L2 VLD VLD VFMA MM LD LM MM LD LM FMA LM ST LD LM LD LM FMA LM ST LD LM MM LD LM FMA LM ST LD LM LD LM FMA LM ST LD LM MM LD LM FMA LM ST LD LM LD LM FMA LM ST LD LM MM LD LM FMA LM ST LD LM LD LM FMA LM ST LD LD FMA ST D1 D1 D1 I1 I1 I1 L2 L2 LD LD FMA ST D1 D1 D1 I1 I1 I1 L2 L2 LD LD FMA ST D1 D1 D1 I1 I1 I1 L2 L2 LD LD FMA ST D1 D1 D1 I1 I1 I1 L2 L2 LD LD FMA ST D1 D1 D1 I1 I1 I1 L2 L2 LD LD FMA ST D1 D1 D1 I1 I1 I1 L2 L2 LD LD FMA ST D1 D1 D1 I1 I1 I1 L2 L2 LD LD FMA ST D1 D1 D1 I1 I1 I1 L2 L2 MM I1 I1 I1 I1 VST VST VST VST VFMA VFMA VFMA VFMA VLD VLD VLD VLD VLD VLD VLD VLD MM Scalar (VL=32) Vector1 (VL=256) Vector2 (VL=2048) CGRA (VL=16K)
  • 8. 20210401 8 従来のプログラムは手順を書く A B C D for (i=0; i<128; i++) D[i]=A[i]+B[i]*C[i]; D[256] A[256] B[256] C[256] float A[256],B[256],C[256],D[256]; for (i=0; i<128; i++) D[i+128]=A[i+128]+B[i]*C[i+128]; Main memory
  • 9. D A B C B D A C 20210401 9 キャッシュメモリが頑張る A B C D for (i=0; i<128; i++) D[i]=A[i]+B[i]*C[i]; D[256] A[256] B[256] C[256] for (i=0; i<128; i++) D[i+128]=A[i+128]+B[i]*C[i+128]; Main memory Cache memory
  • 10. 20210401 10 データフローを書くと明示的に分散配置できる D A B C D A B C D A B C Load Ai (top=A,len=64) Load Bi (top=B,len=64) Load Ci (top=C,len=64) Di=Ai+Bi*Ci Store Di (top=D,len=64) Similar to assembly language, but has DMA info. j=i+64; Load Aj (top=A+64,len=64) Load Bi (top=B, len=64) Load Cj (top=C+64,len=64) Dj=Aj+Bi*Cj Store Dj (top=D+64,len=64) k=i+128;Load Ak (top=A+128,len=64) Load Bi (top=B, len=64) Load Ck (top=C+128,len=64) Dk=Ak+Bi*Ck Store Dk (top=D+128,len=64) Can broadcast
  • 11. 1988 VPP 4way VLIW+8elem. Vector My CGRAs began from VLIW+Vector processor F D W C D M M M M M M M M D D M M M M Load pipe Store pipe FPU pipe F D F D Cache lines are shared among heterogeneous multithreads. M M M M M M M M D W M M M M M M M M M M M M M M M M E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E C E E E E M M M M B B B B B B B B B B Vector Length ≤ 2048 dwords ($miss) F D D 2008 LAPP 8way VLIW+32stage Array C2 E E E LD M M M M C1 E E E LD C0 E E E E B B B B B C3 E E E E HW Mapper (8stages) HW Mapper (binary compatible) Vector Length ≤ 1024 words E E E E E E E ST E E E LD E E E LD E E E E E E E ST 2006 OROCHI 9way VLIW+5way SS 20210401 11 Data from all cache ways are passed through array. Location free LD/ST can keep binary compatibility.
  • 13. Start of IMAX 20210401 13 CPUのレジスタファイルに該当 (32bit x 2waySIMD = 64bit幅) CPUの条件判定器、 浮動小数点パイプライン演算器、 (32bit x 2wayFMA = 64bit幅) SAD等メディア演算、 32要素確率的積和演算、 SHA256用ハッシュ計算、 アドレス生成器に該当 CPUのローカルメモリに該当 (64KB) CPUのレジスタファイルに該当 ノイマン型に学ばない非ノ イマン型には、汎用性も未 来もない。 CPUから始めることで、類 似の汎用性を自然に獲得。
  • 14. 4列⇒1列に重畳 20210401 14 4列分のダブルバッファ・ レジスタファイル 4列分をマルチスレッド実行 メモリ空間を最大4分割 (64KB, 32KB, 16KB, 混在) 4列分のダブルバッファ・ レジスタファイル 大部分のCGRAは、浮動小 数点演算器を搭載しない。 浮動小数点累算が、CGRA のパイプライン動作を止め てしまうから。 そこで、マルチスレッディン グの知恵を借りた。 あとで、汎用性向上に役立 つことになる。
  • 20. 40ops/1unit, 2560ops/64units, 10240ops/4chips 20210401 20 load store octa-ld Add/sub/mul And/or/xor Shift +FPU +Media octa-ld Add/sub/mul And/or/xor Shift +FPU +Media For 1st column Double buffer for write for read
  • 25. 論理UNITを4つ並べる、最後には、これが1基の物理UNITになる 20210401 25 R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R
  • 26. さらに縦に並べて全体のデータ流は上から下へ 20210401 26 F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R
  • 27. さらにマルチチップ拡張として、横に増やす 20210401 27 F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R
  • 28. ここで、論理4UNITを物理1UNITに重畳 20210401 28 F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R
  • 29. 演算位置とローカルメモリ位置の同調制御のため、リング構造化 20210401 29 F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R F F A A F F A A F F M M C C M M R R R R
  • 31. メモリバスに応じて並列接続、この図では8万オペレーションを写像 A B C D E H B M 2 A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E A B C D E 2560op x 32 = 81920op 20210401 31
  • 37. 20210401 37 外部メモリとも協調させ、途切れないデータフローを作る C O N F R E G s A D D R Overlapping post-drain, burst-exec, pre-fetch L M M L M M L M M Burst exec. R E G s A D D R L M M L M M L M M Burst exec. C O N F A D D R R E G s Sequential execution L M M L M M L M M Burst exec. A D D R R E G s L M M time L M M L M M Burst exec. PIO/DMA External Memory PIO/DMA External Memory R E G s A D D R L M M L M M L M M Burst exec.
  • 39. 39 ・中島康彦, 木村睦, 張任遠: "制御装置(スパイクメモリ構成方法)", 特願2021- 27859 (2021. 2. 24) ・トランティホン, 中島康彦: "処理要素、その制御方法および制御プログラム、並びに処理装置(BC)", 特願2021-009164 (2021. 1. 22) ・中島康彦, 高前田伸也: "データ処理装置(メモリ内蔵アクセラレータの構成方法)", 中国ZL201680019602 (2020. 12. 11) ・中島康彦: "データ処理装置(高効率アクセラレータ構成方法)", PCT/JP2020/025123 (2020. 6. 26) ・中島康彦, 木村睦, 張任遠: "データ処理装置(メムキャパシタ構成方法)", 特願2020-91392 (2020. 5. 26) ・中島康彦: "データ処理装置(高効率アクセラレータ構成方法)", 特願2019-517698 (2019. 9. 19) ・Yasuhiko Nakashima, Shinya Takamaeda: "Data processing Device", United States Patent 10,275,392 (2019.4.30) ・中島康彦: "データ処理装置(NCHIP制御方法)", 特願2019-121853 (2019. 6. 28) ・Yasuhiko Nakashima, Takashi Nakada: "Data processing Device for Performing a Plurality of Calculation Processes in Parallel", European Patent Application No.09820420.9 (H31. 1. 18) ・中島康彦: "データ処理装置(高効率アクセラレータ構成方法)", PCT/JP2018/018169 (H30. 5. 10) ・中島康彦: "データ処理装置(高効率アクセラレータ構成方法)", 特願2017-96061 (H29. 5. 12) ・Jun Yao, Yasuhiko Nakashima, Tao Wang, Wei Zhang, Zuqi Liu, Shuzhan Bi: "METHOD FOR ACCESSING MEMORY OF MULTI-CORE SYSTEM, RELATED APPARATUS, SYSTEM, AND STORAGE MEDIUM", PCT/CN2017/083523 (2017. 5. 8) ・中島康彦, 高前田伸也: "データ処理装置(メモリ内蔵アクセラレータの構成方法)", PCT/JP2016/061302 (H28. 4. 6) ・中島康彦, 高前田伸也: "データ処理装置(メモリ内蔵アクセラレータの構成方法)", 特願2015-079552 (H27. 4. 8) ・中島康彦: "エミュレーション方式", 特願2013-055660 (H25. 3. 18) ・中島康彦, 姚駿: "データ供給装置及びデータ処理装置", PCT/JP2013/057503 (H25. 3. 15) ・中島康彦, 姚駿: "データ供給装置及びデータ処理装置", 特願2012-061110 (H24. 3. 16) 20210401 39 28nmLSI : 200x performance/area compared with GPGPU 現有最大規模のプロトタイプは10240オペレーション
  • 40. 20210401 40 各種GPUとの比較 Kernel CPU ARMv8 1.2GHz GPU 256core JetsonTX2 1.3GHz DDR4 480Gbps 16nm 43.6mm² CGRA 64core*4 IMAX2 140MHz DDR4 40Gbps [28nm想定 14.6mm² *4] 8nm想定 1.2mm² *4 GPU 3584core GTX1080Ti 1.5GHz GDDR5 3872Gbps 16nm 471mm² GPU 10496core RTX3090 1.4GHz GDDR6X 7490Gbps 8nm 628mm² DDR bandwidth 12 1 97 187 Power 7.5W ARM 0.6W + [31W] 2.7W 250W 350W MM 3160msec 170 16 [3msec] [EDP=284] EDP=30 12 EDP=36K 1.2 EDP=504 CNN 2080msec 280 EDP=588K 23 [4msec] [EDP=505] EDP=53 18 EDP=81K 2.9 EDP=2943 Lightfield 14500msec 1190 EDP=10.6M 754 [126msec] [EDP=501K] EDP=52K 43 EDP=462K 35 EDP=428K Sparse MM 32002 - - 333+469 [134ms] [EDP=567K] EDP=59K Cusparse使用 2044 EDP=1045M Cusparse使用 280 EDP=27.4M Sparse MM 40002 - - 2378+734 [519ms] [EDP=8.51M] EDP=889K Cusparse使用 3492 EDP=3049M Cusparse使用 350 EDP=43.1M
  • 43. 20210401 43 レイアウトはこんな感じ CGRA 64core*4 IMAX2 140MHz DDR4 40Gbps 8nm想定 1.2mm² *4 GPU 10496core RTX3090 1.4GHz GDDR6X 7490Gbps 8nm 628mm² 75%がDP-SRAM https://thinkcomputers.org/renowned-ir-photographer-fritzchens-fritz- shares-die-shots-of-nvidia-3000-series-ga-102-silicon/ DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAMLogic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic DP SRAM Logic External interface DP SRAM
  • 44. IMAX (64units) x 120 modules = 307200 operations / 4 cycles 20210401 44 HBM2 HOST HOST IMAX (1.2mm2/8nm) x 120 modules ≃ 144mm2 ?
  • 45. CPU GPU Ultimate CGRA w/ high-speed compiler CGRA for Energy-efficient Cryptography Beyond-Neuromorphic Systems Non-Deterministic Computing 20210401 45 ナレータ VOICEVOX:もち子(cv 明日葉よもぎ) はらぺこエンジニアに贈るCGRAの世界2022 (画像フィルタ) スパコンからIoTまで 省エネ社会に AI+BCだけじゃない超効率計算手法
  • 46. /* SCREEN=WD*HT */ for (row=0; row<HT; row++) { for (col=0; col<WD; col++) { pix = in[row*WD+col]; r = t[ pix>>24 ]; g = t[256+((pix>>16)&255)]; b = t[512+((pix>> 8)&255)]; out[row*WD+col]=r<<24 | g<<16 | b<<8; } } 20210401 46 簡単な tone_curveをC言語で書く Load → Store ← Color map tables
  • 47. int loop=WD/2; //EMAX5A begin tone_curve mapdist=0 while (loop--) { mop(OP_LDR, &BR[0][1][1], in++, 0LL, MSK_D0, in, WD, 0, 0, NULL, 0); mop(OP_LDBR, &BR[1][1][1], t1, BR[0][1][1], MSK_B3, t, 256*3/4, 0, 0, NULL, 0); mop(OP_LDBR, &BR[1][1][0], t1, BR[0][1][1], MSK_B7, t, 256*3/4, 0, 0, NULL, 0); mop(OP_LDBR, &BR[1][2][1], t2, BR[0][1][1], MSK_B2, t, 256*3/4, 0, 0, NULL, 0); mop(OP_LDBR, &BR[1][2][0], t2, BR[0][1][1], MSK_B6, t, 256*3/4, 0, 0, NULL, 0); mop(OP_LDBR, &BR[1][3][1], t3, BR[0][1][1], MSK_B1, t, 256*3/4, 0, 0, NULL, 0); mop(OP_LDBR, &BR[1][3][0], t3, BR[0][1][1], MSK_B5, t, 256*3/4, 0, 0, NULL, 0); exe(OP_CCAT, &r1, BR[1][1][0], EXP_H3210, BR[1][1][1], EXP_H3210, 0, EXP_H3210,OP_NOP,0,OP_NOP,0); exe(OP_CCAT, &r2, BR[1][2][0], EXP_H3210, BR[1][2][1], EXP_H3210, 0, EXP_H3210,OP_NOP,0,OP_NOP,0); exe(OP_CCAT, &r3, BR[1][3][0], EXP_H3210, BR[1][3][1], EXP_H3210, 0, EXP_H3210,OP_NOP,0,OP_NOP,0); exe(OP_MMRG, &r0, r1, EXP_H3210, r2, EXP_H3210, r3, EXP_H3210,OP_NOP,0,OP_NOP,0); mop(OP_STR, &r0, out++, 0LL, MSK_D0, out, WD, 0, 0, NULL, 0); } //EMAX5A end 20210401 47 2way SIMD版 SIMD Load → SIMD Store ← Color map tables
  • 52. 20210401 52 メディアンフィルタよりも簡単なアンシャープマスク for (row=0; row<HT; row++) { //EMAX5A begin unsharp mapdist=1 for (CHIP=0; CHIP<NCHIP; CHIP++) { /* output channels are parallelized by multi-chip (OC/#chip) */ for (INIT0=1,LOOP0=WD,col=0-4LL; LOOP0--; INIT0=0) { exe(OP_ADD, &col, col, EXP_H3210, 4LL, EXP_H3210, 0, EXP_H3210, OP_AND, 0x00000ffffffffLL, OP_NOP,0); exe(OP_ADD, &in_center, row_center, EXP_H3210, col, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); mop(OP_LDWR, &r1, in_center, -1276, MSK_D0, row_prev, WD, NULL, 0); mop(OP_LDWR, &r2, in_center, -1284, MSK_D0, row_prev, WD, NULL, 0); mop(OP_LDWR, &r5, in_center, -1280, MSK_D0, row_prev, WD, NULL, 0); exe(OP_MAUH, &r11, r1, EXP_B5410, r2, EXP_B5410, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MAUH, &r12, r1, EXP_B7632, r2, EXP_B7632, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); mop(OP_LDWR, &r6, in_center, 4, MSK_D0, row_center, WD, NULL, 0); mop(OP_LDWR, &r7, in_center, -4, MSK_D0, row_center, WD, NULL, 0); mop(OP_LDWR, &r0, in_center, 0, MSK_D0, row_center, WD, NULL, 0); exe(OP_MLUH, &r20, r0, EXP_B5410, 239, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MLUH, &r21, r0, EXP_B7632, 239, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); mop(OP_LDWR, &r3, in_center, 1284, MSK_D0, row_next, WD, row_next_next, WD); mop(OP_LDWR, &r4, in_center, 1276, MSK_D0, row_next, WD, row_next_next, WD); mop(OP_LDWR, &r8, in_center, 1280 , MSK_D0, row_next, WD, row_next_next, WD); exe(OP_MAUH, &r15, r5, EXP_B5410, r6, EXP_B5410, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MAUH, &r16, r5, EXP_B7632, r6, EXP_B7632, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MAUH3, &r11, r3, EXP_B5410, r4, EXP_B5410, r11, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MAUH3, &r12, r3, EXP_B7632, r4, EXP_B7632, r12, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MLUH, &r13, r11, EXP_H3210, 13, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MLUH, &r14, r12, EXP_H3210, 13, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MAUH3, &r15, r7, EXP_B5410, r8, EXP_B5410, r15, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MAUH3, &r16, r7, EXP_B7632, r8, EXP_B7632, r16, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_NOP, &r7, r15, EXP_H3210, 0LL, EXP_H3210, 0, EXP_H3210, OP_OR, 0, OP_SRLM, 2); exe(OP_MLUH, &r17, r15, EXP_H3210, 15, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_NOP, &r8, r16, EXP_H3210, 0LL, EXP_H3210, 0, EXP_H3210, OP_OR, 0, OP_SRLM, 2); exe(OP_MLUH, &r18, r16, EXP_H3210, 15, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MSUH3, &r10, r20, EXP_H3210, r7, EXP_H3210, r17, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MSUH3, &r11, r21, EXP_H3210, r8, EXP_H3210, r18, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MSUH, &r20, r10, EXP_H3210, r13, EXP_H3210, 0, EXP_H3210, OP_OR, 0, OP_SRLM, 7); exe(OP_MSUH, &r21, r11, EXP_H3210, r14, EXP_H3210, 0, EXP_H3210, OP_OR, 0, OP_SRLM, 7); exe(OP_MH2BW, &r31, r21, EXP_H3210, r20, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); mop(OP_STWR, &r31, out_center, col, MSK_D0, out_center, WD, row_prev, WD); } } //EMAX5A end } r1 r5 r2 r7 r0 r6 r4 r8 r3
  • 54. 20210401 54 超解像 for (Y=0; Y<768; Y++) { k = Y*240/768; kfraq = (((Y*240)<<4)/768)&15; for (X=0; X<1024; X++) { l = X*320/1024; lfraq = (((X*320)<<4)/1024)&15;/ out[Y][X] = ((in[k ][l ]>>24&0xff)*r1 + (in[k ][l-1]>>24&0xff)*r2 + (in[k ][l+1]>>24&0xff)*r3 + (in[k-1][l ]>>24&0xff)*r4 + (in[k+1][l ]>>24&0xff)*r5 + (in[k-1][l-1]>>24&0xff)*r6 + (in[k-1][l+1]>>24&0xff)*r7 + (in[k+1][l-1]>>24&0xff)*r8 + (in[k+1][l+1]>>24&0xff)*r9)/256<<24 | ((in[k ][l ]>>16&0xff)*r1 + (in[k ][l-1]>>16&0xff)*r2 + (in[k ][l+1]>>16&0xff)*r3 + (in[k-1][l ]>>16&0xff)*r4 + (in[k+1][l ]>>16&0xff)*r5 + (in[k-1][l-1]>>16&0xff)*r6 + (in[k-1][l+1]>>16&0xff)*r7 + (in[k+1][l-1]>>16&0xff)*r8 + (in[k+1][l+1]>>16&0xff)*r9)/256<<16 | ((in[k ][l ]>> 8&0xff)*r1 + (in[k ][l-1]>> 8&0xff)*r2 + (in[k ][l+1]>> 8&0xff)*r3 + (in[k-1][l ]>> 8&0xff)*r4 + (in[k+1][l ]>> 8&0xff)*r5 + (in[k-1][l-1]>> 8&0xff)*r6 + (in[k-1][l+1]>> 8&0xff)*r7 + (in[k+1][l-1]>> 8&0xff)*r8 + (in[k+1][l+1]>> 8&0xff)*r9)/256<<8; } } K-1 K = Y*240/768 L-1 L = X*320/1024 (X,Y) 1024x768の1画素 (L,K) 320x240画像 kfraq = (((Y*240)<<4)/ 768)&15;/* 4bit */ lfraq = (((X*320)<<4)/1024)&15;/* 4bit */ Y=1 kfraq= 5/16 Y=2 kfraq=10/16 Y=3 kfraq=15/16 Y=4 kfraq= 4/16 Y=5 kfraq= 9/16 X=1 lfraq= 5/16 X=2 lfraq=10/16 X=3 lfraq=15/16 X=4 lfraq= 4/16 X=5 lfraq= 9/16
  • 55. 20210401 55 ステレオマッチング for (row=8; row<240-8; row++) { for (Y=-8; Y<8; Y++) { for (col=8; col<320-8; col++) { for (X=-8; X<8; X++) SAD2[row][col] += sad(L[row+Y][col+X+視差], R[row+Y][col+X]); } } }
  • 56. for (row=-8; row<240-8; row++) { //EMAX5A begin wdifline mapdist=0 for (CHIP=0; CHIP<NCHIP; CHIP++) { for (INIT0=1,LOOP0=320,col=0-4LL; LOOP0--; INIT0=0) { exe(OP_ADD, &col, col, EXP_H3210, 4LL, EXP_H3210, 0, EXP_H3210, OP_AND, 0x00000000ffffffffLL, OP_NOP, 0); exe(OP_ADD, &rofs1, L, EXP_H3210, col, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_ADD, &rofs2, R, EXP_H3210, col, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); mop(OP_LDWR, &r2, rofs1, 0, MSK_D0, L, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r3, rofs1, 4, MSK_D0, L, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r4, rofs1, 8, MSK_D0, L, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r5, rofs1, 12, MSK_D0, L, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r6, rofs2, 0, MSK_D0, R, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r7, rofs2, 4, MSK_D0, R, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r8, rofs2, 8, MSK_D0, R, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r9, rofs2, 12, MSK_D0, R, 320, 0, 0, NULL, 320); exe(OP_MSAD, &r22, r2, EXP_H3210, r6, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); mop(OP_LDWR, &r12, rofs1, 16, MSK_D0, L, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r13, rofs1, 20, MSK_D0, L, 320, 0, 0, NULL, 320); exe(OP_MSAD, &r23, r3, EXP_H3210, r7, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); mop(OP_LDWR, &r14, rofs1, 24, MSK_D0, L, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r15, rofs1, 28, MSK_D0, L, 320, 0, 0, NULL, 320); exe(OP_MSAD, &r24, r4, EXP_H3210, r8, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); mop(OP_LDWR, &r16, rofs2, 16, MSK_D0, R, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r17, rofs2, 20, MSK_D0, R, 320, 0, 0, NULL, 320); exe(OP_MSAD, &r25, r5, EXP_H3210, r9, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); mop(OP_LDWR, &r18, rofs2, 24, MSK_D0, R, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r19, rofs2, 28, MSK_D0, R, 320, 0, 0, NULL, 320); exe(OP_MSSAD, &r12, r22, EXP_H3210, r12, EXP_H3210, r16, EXP_H3210, OP_NOP, 0, OP_NOP, 0); mop(OP_LDWR, &r2, rofs1, 32, MSK_D0, L, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r3, rofs1, 36, MSK_D0, L, 320, 0, 0, NULL, 320); exe(OP_MSSAD, &r13, r23, EXP_H3210, r13, EXP_H3210, r17, EXP_H3210, OP_NOP, 0, OP_NOP, 0); mop(OP_LDWR, &r4, rofs1, 40, MSK_D0, L, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r5, rofs1, 44, MSK_D0, L, 320, 0, 0, NULL, 320); exe(OP_MSSAD, &r14, r24, EXP_H3210, r14, EXP_H3210, r18, EXP_H3210, OP_NOP, 0, OP_NOP, 0); mop(OP_LDWR, &r6, rofs2, 32, MSK_D0, R, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r7, rofs2, 36, MSK_D0, R, 320, 0, 0, NULL, 320); exe(OP_MSSAD, &r15, r25, EXP_H3210, r15, EXP_H3210, r19, EXP_H3210, OP_NOP, 0, OP_NOP, 0); mop(OP_LDWR, &r8, rofs2, 40, MSK_D0, R, 320, 0, 0, NULL, 320); mop(OP_LDWR, &r9, rofs2, 44, MSK_D0, R, 320, 0, 0, NULL, 320); exe(OP_MSSAD, &r22, r12, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MSSAD, &r23, r13, EXP_H3210, r3, EXP_H3210, r7, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MSSAD, &r24, r14, EXP_H3210, r4, EXP_H3210, r8, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MSSAD, &r25, r15, EXP_H3210, r5, EXP_H3210, r9, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MAUH3, &r31, r22, EXP_H3210, r23, EXP_H3210, r24, EXP_H3210, OP_NOP, 0, OP_NOP, 0); exe(OP_MAUH3, &r1, r31, EXP_H3210, r25, EXP_H3210, 0, EXP_H3210, OP_SUMHL,0, OP_NOP, 0); mop(OP_LDWR, &BR[8][0][1], sad2, col, MSK_D0, sad2, 320, 0, 1, NULL, 320); exe(OP_ADD, &AR[8][0], BR[8][0][1], EXP_H3210, r1, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); mop(OP_STWR, &AR[8][0], col, sad2, MSK_D0, sad2, 320, 0, 1, NULL, 320); :のこり15か所のSADにも加算 } } //EMAX5A end } //EMAX5A drain_dirty_lmm 20210401 56 ステレオマッチング
  • 57. CPU GPU Ultimate CGRA w/ high-speed compiler CGRA for Energy-efficient Cryptography Beyond-Neuromorphic Systems Non-Deterministic Computing 20210401 57 ナレータ VOICEVOX:もち子(cv 明日葉よもぎ) はらぺこエンジニアに贈るCGRAの世界2022 (機械学習) スパコンからIoTまで 省エネ社会に AI+BCだけじゃない超効率計算手法
  • 59. GPU: unpack and matrix-multiplication (x9 memory space) 1 -1-1-1 1 -1-1-1 1 1 -1-1-1 1 -1-1-1 1 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 … 0.27 1.3 … 1.27 2.3 … 2.27 : : : : : : 27.0 27.1 27.2 : … : : : 27.3 … 27:27 unpack_patch2col 1.0 1.1 1.1 1.2 1.2 1.3 1.0 1.1 … 1.1 1.2 : 1.2 1.3 … 1:25 2.0 2.1 1.26 2.1 2.2 1.27 2.2 2.3 … 1.25 25.0 :… 1.26 25.1 … 1.27 25.2 25.1 … 25.25 25.2 … 25.26 25.3 … 25.27 … 2.25 26.0 : 2.26 26.1 … 2.27 26.2 26.1 … 26.25 26.2 : 26.26 26.3 … 26:27 : : : 2.2 2.3 … : : : 2.27 3.4 3.5 : : : … 3.27 27.2 : : : 27.3 … 27:27 3x3 26x26 28 28 … … … … : … : : : : 4.5 4.27 4.4 x100 x100 copy 0.0 0.1 … 0.25 0.1 0.2 … 0.26 0.27 … 0.3 0.2 1 -1 -1 -1 1 -1 -1-1 1 C M&A CPU/GPUの畳み込み演算 20210401 59
  • 60. 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 … 0.27 1.3 … 1.27 2.3 … 2.27 : : : : : : 27.0 27.1 27.2 : … : : : 27.3 … 27:27 … … … … : … : : : : 4.5 4.27 4.4 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 … 0.27 1.3 … 1.27 2.3 … 2.27 : : : : … … … … … 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 … 0.27 1.3 … 1.27 2.3 … 2.27 : : : : … … … … … 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 … 0.27 1.3 … 1.27 2.3 … 2.27 : : : : … … … … … -1 -1 1 -1 1 1 1 -1 -1 … 1 -1 … 1 1 … 1 : : : : … … … … … 1 -1 1 -1 1 1 1 -1 -1 … 1 -1 … 1 1 … 1 : : : : … … … … … 1 -1 -1 1 -1 1 1 1 -1 -1 … -1 … 1 1 … 1 : : : : … … … … … 0.0 0.1 -1 1 OCH#0 OCH#1 OCH#2 OCH#0 OCH#1 OCH#2 OCH#0 OCH#1 OCH#2 0.0 0.1 0.2 1.0 1.1 1.2 0.25 1.25 : : : … … … 0.0 0.1 0.2 1.0 1.1 1.2 0.25 1.25 : : : … … … 0.0 0.1 0.2 1.0 1.1 1.2 0.25 1.25 : : : … … … 0.0 0.1 0.2 1.0 1.1 1.2 0.25 1.25 : : : … … … 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 1 -1 -1 -1 1 -1 -1 -1 1 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 … 0.27 1.3 … 1.27 2.3 … 2.27 : : : : : : 27.0 27.1 27.2 : … : : : 27.3 … 27:27 … … … … : … : : : : 4.5 4.27 4.4 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 … 0.27 1.3 … 1.27 2.3 … 2.27 : : : : : : 27.0 27.1 27.2 : … : : : 27.3 … 27:27 … … … … : … : : : : 4.5 4.27 4.4 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 … 0.27 1.3 … 1.27 2.3 … 2.27 : : : : : : 27.0 27.1 27.2 : … : : : 27.3 … 27:27 … … … … : … : : : : 4.5 4.27 4.4 ICH#0 ICH#0 ICH#1 ICH#2 ICH#3 ICH#0 ICH#1 ICH#2 ICH#3 OCH#0 OCH#1 1 1 FMUL FMA ICH#1 ICH#5 54 units Kernel bcast ICH#0 bcast ICH#1 bcast Drain 4 columns 20210401 60 IMAXの畳み込み演算
  • 61. imax() { Ull CHIP; Ull LOOP1, LOOP0; Ull INIT1, INIT0; Ull AR[64][4]; Ull BR[64][4][4]; Ull r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15; Ull r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31; Ull cc0, cc1, cc2, cc3, ex0, ex1; Ull cofs, rofs, oofs, k; for (top=0; top<M1/NCHIP; top+=RMGRP) { /* will be parallelized by multi-chip (M/#chip) */ for (blk=0; blk<L; blk+=H) { typedef struct {Uint i[8]} Ui8; Uint *a0[NCHIP]; Uint *a[H][NCHIP]; Ui8 *b[H], *b0[H], *b1[H], *b2[H], *b3[H]; Ui8 *c0[NCHIP]; Ui8 *c00[NCHIP], *c01[NCHIP], *c02[NCHIP], *c03[NCHIP]; for (k=0; k<H; k++) { b[k] = B+(blk+k)*M2; b0[k] = b[k]; b1[k] = (Uint*)b[k]+2; b2[k] = (Uint*)b[k]+4; b3[k] = (Uint*)b[k]+6; } for (CHIP=0; CHIP<NCHIP; CHIP++) { /* will be parallelized by multi-chip (M/#chip) */ a0[CHIP] = A+(CHIP*M1/NCHIP+top)*L; for (k=0; k<H; k++) a[k][CHIP] = a0[CHIP]+blk+k; c0[CHIP] = C1+(CHIP*M1/NCHIP+top)*M2; c00[CHIP]= (Uint*)c0[CHIP]+0; c01[CHIP]= (Uint*)c0[CHIP]+2; c02[CHIP]= (Uint*)c0[CHIP]+4; c03[CHIP]= (Uint*)c0[CHIP]+6; } //EMAX5A begin mm mapdist=0 /*3*/ for (CHIP=0; CHIP<NCHIP; CHIP++) { /* will be parallelized by multi-chip (M/#chip) */ /*2*/ for (INIT1=1,LOOP1=RMGRP,rofs=(0-L*4)<<32|((0-M2*4)&0xffffffff); LOOP1--; INIT1=0) { /* stage#0 *//* mapped to FOR() on BR[63][1][0] */ /*1*/ for (INIT0=1,LOOP0=M2/W/2,cofs=(0-W*8)<<32|((0-W*8)&0xffffffff); LOOP0--; INIT0=0) { /* stage#0 *//* mapped to FOR() on BR[63][0][0] */ exe(OP_ADD, &cofs, INIT0?cofs:cofs, EXP_H3210, (W*8)<<32|(W*8), EXP_H3210, 0LL, EXP_H3210, OP_AND, 0xffffffffffffffffLL, OP_NOP, 0LL); exe(OP_ADD, &rofs, rofs, EXP_H3210, INIT0?(L*4)<<32|(M2*4):0, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe(OP_ADD, &oofs, rofs, EXP_H3210, cofs, EXP_H3210, 0, EXP_H3210, OP_AND, 0xffffffff, OP_NOP, 0LL); /* stage#1 */ mop(OP_LDR, 3, &BR[1][0][1], (Ull)b0[0], (Ull)cofs, MSK_W1, (Ull)b[0], M2/2, 0, 0, (Ull)NULL, M2/2); /* stage#1 */ mop(OP_LDR, 3, &BR[1][0][0], (Ull)b1[0], (Ull)cofs, MSK_W1, (Ull)b[0], M2/2, 0, 0, (Ull)NULL, M2/2); /* stage#1 */ mop(OP_LDR, 3, &BR[1][1][1], (Ull)b2[0], (Ull)cofs, MSK_W1, (Ull)b[0], M2/2, 0, 0, (Ull)NULL, M2/2); /* stage#1 */ mop(OP_LDR, 3, &BR[1][1][0], (Ull)b3[0], (Ull)cofs, MSK_W1, (Ull)b[0], M2/2, 0, 0, (Ull)NULL, M2/2); /* stage#1 2KB */ mop(OP_LDUWR,1, &BR[1][2][1], (Ull)a[0][CHIP], (Ull)rofs, MSK_W1, (Ull)a0[CHIP], L*RMGRP/2, 0, 0, (Ull)NULL, L*RMGRP/2); /* stage#1 16KB */ exe(OP_FML, &AR[2][0], BR[1][0][1], EXP_H3210, BR[1][2][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); /* stage#2 */ exe(OP_FML, &AR[2][1], BR[1][0][0], EXP_H3210, BR[1][2][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); /* stage#2 */ exe(OP_FML, &AR[2][2], BR[1][1][1], EXP_H3210, BR[1][2][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); /* stage#2 */ exe(OP_FML, &AR[2][3], BR[1][1][0], EXP_H3210, BR[1][2][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); /* stage#2 */ sgemm00_core1( 2, 1, 3); sgemm00_core1( 3, 2, 4); : sgemm00_core1(59, 58, 60); sgemm00_core1(60, 59, 61); sgemm00_final(61, 62); } } } //EMAX5A end } } //EMAX5A drain_dirty_lmm } Just repeating following macros IMAXの行列積 20210401 61
  • 62. #define sgemm00_core1(r, rm1, rp1) mop(OP_LDR, 3, &BR[r][0][1], b0[rm1], cofs, MSK_W1, b[rm1], M2/2, 0, 0, NULL, M2/2); mop(OP_LDR, 3, &BR[r][0][0], b1[rm1], cofs, MSK_W1, b[rm1], M2/2, 0, 0, NULL, M2/2); mop(OP_LDR, 3, &BR[r][1][1], b2[rm1], cofs, MSK_W1, b[rm1], M2/2, 0, 0, NULL, M2/2); mop(OP_LDR, 3, &BR[r][1][0], b3[rm1], cofs, MSK_W1, b[rm1], M2/2, 0, 0, NULL, M2/2); mop(OP_LDUWR,1, &BR[r][2][1], a[rm1][CHIP], rofs, MSK_W1, a0[CHIP], L*RMGRP/2, 0, 0, NULL, L*RMGRP/2); exe (OP_FMA, &AR[rp1][0], AR[r][0], EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][0][1], EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe (OP_FMA, &AR[rp1][1], AR[r][1], EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][0][0], EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe (OP_FMA, &AR[rp1][2], AR[r][2], EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][1][1], EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe (OP_FMA, &AR[rp1][3], AR[r][3], EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][1][0], EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL) #define sgemm00_final(r, rp1) exe(OP_CMP_LT, &cc1, cofs, EXP_H3210, cofslimit1, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe(OP_CMP_LT, &cc2, cofs, EXP_H3210, cofslimit2, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe(OP_CMP_LT, &cc3, cofs, EXP_H3210, cofslimit3, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); mop(OP_LDUWR, 1, &BR[rp1][0][1], c00[CHIP], oofs, MSK_W0, c0[CHIP], Clen, 0, 1, NULL, Clen); mop(OP_LDUWR, 1, &BR[rp1][1][1], c01[CHIP], oofs, MSK_W0, c0[CHIP], Clen, 0, 1, NULL, Clen); mop(OP_LDUWR, 1, &BR[rp1][2][1], c02[CHIP], oofs, MSK_W0, c0[CHIP], Clen, 0, 1, NULL, Clen); mop(OP_LDUWR, 1, &BR[rp1][3][1], c03[CHIP], oofs, MSK_W0, c0[CHIP], Clen, 0, 1, NULL, Clen); exe (OP_FAD, &AR[rp1][0], AR[r][0], EXP_H3210, BR[rp1][0][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe (OP_FAD, &AR[rp1][1], AR[r][1], EXP_H3210, BR[rp1][1][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe (OP_FAD, &AR[rp1][2], AR[r][2], EXP_H3210, BR[rp1][2][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe (OP_FAD, &AR[rp1][3], AR[r][3], EXP_H3210, BR[rp1][3][1], EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); mop(OP_STWR, 1, &AR[rp1][0], oofs, c00[CHIP], MSK_D0, c0[CHIP], Clen, 0, 1, NULL, Clen); cex (OP_CEXE, &ex1, 0, 0, 0, cc1, 0xaaaa); mop(OP_STWR, ex1, &AR[rp1][1], oofs, c01[CHIP], MSK_D0, c0[CHIP], Clen, 0, 1, NULL, Clen); cex (OP_CEXE, &ex2, 0, 0, 0, cc2, 0xaaaa); mop(OP_STWR, ex2, &AR[rp1][2], oofs, c02[CHIP], MSK_D0, c0[CHIP], Clen, 0, 1, NULL, Clen); cex (OP_CEXE, &ex3, 0, 0, 0, cc3, 0xaaaa); mop(OP_STWR, ex3, &AR[rp1][3], oofs, c03[CHIP], MSK_D0, c0[CHIP], Clen, 0, 1, NULL, Clen) One physical (four logical) unit One physical (four logical) unit マクロの中身 Prefetching Length of area Top of area LD/ST offset LD/ST base addr. 20210401 62
  • 63. #define sgemm00_core1 mop(OP_LDUWR, 1, &BR[r][0][1] mop(OP_LDUWR, 1, &BR[r][0][0] mop(OP_LDUWR, 1, &BR[r][1][1] mop(OP_LDUWR, 1, &BR[r][1][0] mop(OP_LDUWR, 1, &BR[r][2][1] exe(OP_FMA, &AR[rp1][0] exe(OP_FMA, &AR[rp1][1] exe(OP_FMA, &AR[rp1][2] exe(OP_FMA, &AR[rp1][3] #define sgemm00_final exe(OP_CMP_LT, &cc1 exe(OP_CMP_LT, &cc2 exe(OP_CMP_LT, &cc3 mop(OP_LDUWR, 1, &BR[rp1][0][1] mop(OP_LDUWR, 1, &BR[rp1][1][1] mop(OP_LDUWR, 1, &BR[rp1][2][1] mop(OP_LDUWR, 1, &BR[rp1][3][1] exe(OP_FAD, &AR[rp1][0], AR[r][0] exe(OP_FAD, &AR[rp1][1], AR[r][1] exe(OP_FAD, &AR[rp1][2], AR[r][2] exe(OP_FAD, &AR[rp1][3], AR[r][3] mop(OP_STWR, 1, &AR[rp1][0] cex(OP_CEXE, &ex1, cc1 mop(OP_STWR, ex1, &AR[rp1][1] cex(OP_CEXE, &ex2, cc2 mop(OP_STWR, ex2, &AR[rp1][2] cex(OP_CEXE, &ex3, cc3 mop(OP_STWR, ex3, &AR[rp1][3] 20210401 63 行列積のコンパイル結果
  • 64. unpack_patch2col(tmp_col:25x[100x24x24] <-- ninput:■100x28x28, ksize, kstride) reshape nhidden:100x[8x24x24] --> tmp_dst:8x[100x24x24] (C1)multiply_float2D(▲g_Ki2h:8x25 <-- tmp_dst:8x[100x24x24], tmp_col:25x[100x24x24]^T) (C2)multiply_float2D(tmp_col:25x[100x24x24] <-- Ki2h:8x25^T, tmp_dst:8x[100x24x24]) pack_col2patch(ninput:■100x28x28 <-- tmp_col:25x[100x24x24], 5, 1) 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 … … 0.27 … … 1.27 … … 2.27 : : : : : : 27.0 27.1 27.2 … … : : : 27.3 … 27:27 28 28 0:23 1:23 2:23 : : … 23:0 23:1 23:2 … … 4.27 23.23 xICx100 24 24 x100x8 tmp_dst ninput (original) g_Ki2h (C1) 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.23 1.23 2.23 : : : 23.0 23.1 23.2 : 23.23 … … … … … 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 1.3 2.3 : : : : 0.4 1.4 2.4 : : : : : 4.4 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 1.3 2.3 : : : : 0.4 1.4 2.4 : : : : : 4.4 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 1.3 2.3 : : : : 0.4 1.4 2.4 : : : : : 4.4 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 1.3 2.3 : : : : 0.4 1.4 2.4 : : : : : 4.4 0.0 0.1 … : : … 0.4 0.5 … 0.23 1.0 1.1 : : : 0:27 1.4 1.5 1.0 1.1 … : : : 1.4 1.5 … 1:23 2.0 2.1 : : : 1.27 2.4 2.5 … 1.23 23.0 :… : : … 1.27 23.4 23.1 … 23.23 : … : 23.5 … 23.27 … 2.23 24.0 : : : … 2.27 24.4 24.1 … 24.23 : : : 24.5 … 24:27 : : : 4.4 4.5 … : : : 4.27 5.4 5.5 : : : … 5.27 27.4 : : : 27.5 … 27:27 5x5 xIC 24x24 x100 tmp_col (reshaped for GPU) copy 5x5xICx8 nhidden 24 x8x100 20210401 64 IMAXの重み用バックプロパゲーション
  • 65. unpack_patch2col(tmp_col:25x[100x24x24] <-- ninput:■100x28x28, ksize, kstride) reshape nhidden:100x[8x24x24] --> tmp_dst:8x[100x24x24] (C1)multiply_float2D(▲g_Ki2h:8x25 <-- tmp_dst:8x[100x24x24], tmp_col:25x[100x24x24]^T) (C2)multiply_float2D(tmp_col:25x[100x24x24] <-- Ki2h:8x25^T, tmp_dst:8x[100x24x24]) pack_col2patch(ninput:■100x28x28 <-- tmp_col:25x[100x24x24], 5, 1) 24 24 x8x100 nhidden Ki2h ninput (C2) 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 1.3 2.3 : : : : 0.4 1.4 2.4 : : : : : 4.4 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 1.3 2.3 : : : : 0.4 1.4 2.4 : : : : : 4.4 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 1.3 2.3 : : : : 0.4 1.4 2.4 : : : : : 4.4 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.3 1.3 2.3 : : : : 0.4 1.4 2.4 : : : : : 4.4 0.0 0.1 0.0 0.2 1.0 1.1 1.2 2.0 2.1 2.2 … … 0.27 … … 1.27 … … 2.27 : : : : : : 27.0 27.1 27.2 … … : : : 27.3 … 27:27 28 28 0:23 1:23 2:23 : : … 23:0 23:1 23:2 … … 4.27 23.23 xICx100 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.23 1.23 2.23 : : : :23.0 23.1 23.2 : 23.23 … … … … … 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.23 1.23 2.23 : : : :23.0 23.1 23.2 : 23.23 … … … … … 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.23 1.23 2.23 : : : :23.0 23.1 23.2 : 23.23 … … … … … 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2 0.23 1.23 2.23 : : : 23.0 23.1 23.2 : 23.23 … … … … … 0.0 0.0 0.1 … : … 0.4 0.5 … 0.23 1.0 1.1 : 1.1 : 0:27 1.4 1.5 1.0 1.1 … 1.1 : : 1.4 1.5 … 1:23 2.0 2.1 : : : 1.27 2.4 2.5 … 1.23 23.0 :… : : … 1.27 23.4 23.1 … 23.23 : … : 23.5 … 23.27 … 2.23 24.0 : : : … 2.27 24.4 24.1 … 24.23 : : : 24.5 … 24:27 : : : 4.4 4.5 … : : : 4.27 5.4 5.5 : : : … 5.27 27.4 : : : 27.5 … 27:27 5x5 xIC 24x24 x100 contribution of pixel/ninput : merge 5x5xICx8 Integration of OC(8) 0.1 tmp_col (reshaped for GPU) 20210401 65 IMAXの入力用バックプロパゲーション
  • 66. 0.50×0.50≒0.20 0000111101 0111110000 0000110000 Multiplier by AND gate 0.50+0.50≒0.50*2 0000111101 0111110000 0101111000 Scaled adder by random selector 20210401 66 ストカスティック積和演算 0.50+0.50=1.00 Adder by population counter Tati Erlina, Yan Chen, Renyuan Zhang and Yasuhiko Nakashima: "An Efficient Time-based Stochastic Computing Circuitry Employing Neuron-MOS", GLSVLSI2019, pp.51-56, May. (2019)
  • 68. CPU GPU Ultimate CGRA w/ high-speed compiler CGRA for Energy-efficient Cryptography Beyond-Neuromorphic Systems Non-Deterministic Computing 20210401 68 ナレータ VOICEVOX:もち子(cv 明日葉よもぎ) はらぺこエンジニアに贈るCGRAの世界2022 (高次数ステンシル計算) スパコンからIoTまで 省エネ社会に AI+BCだけじゃない超効率計算手法
  • 76. CPU GPU Ultimate CGRA w/ high-speed compiler CGRA for Energy-efficient Cryptography Beyond-Neuromorphic Systems Non-Deterministic Computing 20210401 76 ナレータ VOICEVOX:もち子(cv 明日葉よもぎ) はらぺこエンジニアに贈るCGRAの世界2022 (逆行列) スパコンからIoTまで 省エネ社会に AI+BCだけじゃない超効率計算手法
  • 78. 20210401 78 逆行列には、ローカルメモリ自己更新 for (j=i+1; j<M; j+=NCHIP*H*RMGRP) { /* 行方向 */ //EMAX5A begin inv_x1 mapdist=0 for (CHIP=0; CHIP<NCHIP; CHIP++) { for (INIT1=1,LOOP1=RMGRP,rofs=0-M*4; LOOP1--; INIT1=0) { /* stage#0 *//* mapped to FOR() on BR[63][1][0] */ for (INIT0=1,LOOP0=M-(i+1),cofs=0; LOOP0--; INIT0=0) { /* stage#0 *//* mapped to FOR() on BR[63][0][0] */ exe(OP_ADD, &cofs, INIT0?cofs:cofs, EXP_H3210, 4LL, EXP_H3210, 0LL, EXP_H3210, OP_AND, 0x00000000ffffffffLL, OP_NOP, 0LL); /* stage#0 */ exe(OP_ADD, &rofs, rofs, EXP_H3210, INIT0?M*4:0, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); /* stage#0 */ exe(OP_ADD, &oofs, rofs, EXP_H3210, cofs, EXP_H3210, 0LL, EXP_H3210, OP_AND, 0x00000000ffffffffLL, OP_NOP, 0LL); /* stage#1 */ /***************************/ /* + - - - - - - - - - - - */ /* A[p[i]] 先頭行 */ /* 先頭行はi更新まで再利用可能 */ /* | * > > > > > > > > > > */ /* A[p[j]] 次行から引く */ /* 1行をLMMに写像 */ /* | v + - - - - - - - - - */ /* | v | * > > > > > > > > */ /* M/60を収容してi更新までj+=60を繰り返す *//* 行番号比較とcstによる端数制御 */ /* | v | v + - - - - - - - */ /* + CHIP#0 h=0 grp=0 */ /* | v | v - + - - - - - - */ /* + CHIP#0 h=0 grp=1 */ /* | v | v - - + - - - - - */ /* + CHIP#1 h=0 grp=0 */ /* | v | v - - - + - - - - */ /* + CHIP#1 h=0 grp=1 */ /* | v | v - - - - + - - - */ /* + CHIP#0 h=1 grp=0 */ /* | v | v - - - - - + - - */ /* + CHIP#0 h=1 grp=1 */ /* | v | v - - - - - - + - */ /* + CHIP#1 h=1 grp=0 */ /* | v | v - - - - - - - + */ /* + CHIP#1 h=1 grp=1 */ /***************************/ /* 最大60行まで写像可能 */ /* FOLDING時は,少なくとも第0列がFOLDINGであることが必要(conv-c2c仕様) */ /* CEXEにも関わらずSTWRの無意味なLMM入れ換えが発生するため,A[M][*](枠外領域)を使用 */ /* OK exe-loop */ exe(OP_CMP_LT, &cc0, l00[CHIP], EXP_H3210, M, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0); /* stage#1 LD */ mop(OP_LDWR, 1, &BR[2][2][1], top, cofs, MSK_W0, topw, len, 0, 0, NULL, len); /* A[p[i]*M+k] stage#2 | */ mop(OP_LDWR, 1, &BR[2][0][1], d00[CHIP], oofs, MSK_W0, d00w[CHIP], len2,0, 1, NULL, len2); /* A[p[j+h*NCHIP+CHIP]*M+k] stage#2 +-> | */ mop(OP_LDWR, 1, &BR[2][1][1], d00[CHIP], rofs, MSK_W0, d00w[CHIP], len2,0, 1, NULL, len2); /* A[p[j+h*NCHIP+CHIP]*M+k] stage#2 +-> | */ exe(OP_FMS, &AR[2][0], BR[2][0][1], EXP_H3210, BR[2][1][1], EXP_H3210, BR[2][2][1], EXP_H3210, OP_NOP, 0LL, OP_NOP, 0); /* stage#2 | ■■■ | 1.0 */ cex(OP_CEXE, &ex0, 0, 0, 0, cc0, 0xaaaa); /* stage#2 | AR[1] | */ mop(OP_STWR,ex0, &AR[2][0], oofs, d00[CHIP], MSK_D0, d00w[CHIP], len2, 0, 1, NULL, len2); /* stage#2 | + ST v */ #if (H>1) /* *--------- BR[2] */ exe(OP_CMP_LT, &cc1, l01[CHIP], EXP_H3210, M, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0); /* stage#2 LD */ mop(OP_LDWR, 1, &BR[3][2][1], top, cofs, MSK_W0, topw, len, 0, 0, NULL, len); /* A[p[i]*M+k] stage#3 | */ mop(OP_LDWR, 1, &BR[3][0][1], d01[CHIP], oofs, MSK_W0, d01w[CHIP], len2,0, 1, NULL, len2); /* A[p[j+h*NCHIP+CHIP]*M+k] stage#3 +-> | */ mop(OP_LDWR, 1, &BR[3][1][1], d01[CHIP], rofs, MSK_W0, d01w[CHIP], len2,0, 1, NULL, len2); /* A[p[j+h*NCHIP+CHIP]*M+k] stage#3 +-> | */ exe(OP_FMS, &AR[3][0], BR[3][0][1], EXP_H3210, BR[3][1][1], EXP_H3210, BR[3][2][1], EXP_H3210, OP_NOP, 0LL, OP_NOP, 0); /* stage#3 | ■■■ | 1.0 */ cex(OP_CEXE, &ex0, 0, 0, 0, cc1, 0xaaaa); /* stage#3 | AR[2] | */ mop(OP_STWR,ex0, &AR[3][0], oofs, d01[CHIP], MSK_D0, d01w[CHIP], len2, 0, 1, NULL, len2); /* stage#3 | + ST v */ #if (H>2) /* *--------- BR[3] */ if (j+h*NCHIP*RMGRP+CHIP*RMGRP+grp<M) A[(j+h*NCHIP*RMGRP+CHIP*RMGRP+grp)*M+i+1+k] -= A[(j+h*NCHIP*RMGRP+CHIP*RMGRP+grp)*M+i]*A[i*M+i+1+k];
  • 79. 20210401 79 条件付きストア機能を使う exe(OP_CMP_LT, &cc0, l00[CHIP], EXP_H3210, M, EXP_H3210, 0LL, mop(OP_LDWR, 1, &BR[2][2][1], top, cofs, MSK_W0, topw, len, 0, 0, NULL, len); mop(OP_LDWR, 1, &BR[2][0][1], d00[CHIP], oofs, MSK_W0, d00w[CHIP], len2,0, 1, NULL, len2); mop(OP_LDWR, 1, &BR[2][1][1], d00[CHIP], rofs, MSK_W0, d00w[CHIP], len2,0, 1, NULL, len2); exe(OP_FMS, &AR[2][0], BR[2][0][1], EXP_H3210, BR[2][1][1], EXP_H3210, BR[2][2][1], cex(OP_CEXE, &ex0, 0, 0, 0, cc0, 0xaaaa ); mop(OP_STWR, ex0, &AR[2][0], oofs, d00[CHIP], MSK_D0, d00w[CHIP], len2, 0, 1, NULL, len2); 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
  • 80. CPU GPU Ultimate CGRA w/ high-speed compiler CGRA for Energy-efficient Cryptography Beyond-Neuromorphic Systems Non-Deterministic Computing 20210401 80 ナレータ VOICEVOX:もち子(cv 明日葉よもぎ) はらぺこエンジニアに贈るCGRAの世界2022 (疎行列計算とソート) スパコンからIoTまで 省エネ社会に AI+BCだけじゃない超効率計算手法
  • 81. 20210401 81 疎行列積和 マージソート 1 1.0 2 2.0 3 3.0 11 4.0 12 5.0 13 6.0 配列A 配列B 2 1.0 3 2.0 4 3.0 9 4.0 10 5.0 11 6.0 要素番号と値の組 1 a1 2 a2 3 s3 11 a11 12 a12 13 a13 入力A 入力B 2 b2 3 b3 4 b4 9 b9 10 b10 11 b11 値と付加情報(ポインタなど)の組 疎行列とソートには、デュアルアドレス同調機能が便利
  • 83. 4段パイプライン浮動小数点演算器+メモリ参照(LD+ST) ⑩+⑪+初回初期値C出力レジスタ⇒演算器入力REG 以降、累算 演算器3段結果⇒演算器入力REG 演算器入力REG⇒演算器初段結果⇒演算器2段結果 ⇒演算器3段結果⇒演算器入力REGへ戻る累算リング 4段パイプラインAアドレス計算データフロー ①Aアドレス入力REG⇒②0/8加算出力⇒⑦通過 ⇒⑨通過⇒先頭へ戻るアドレス累算リング 4段パイプラインBアドレス計算データフロー ①Bアドレス入力REG⇒②0/8加算出力⇒⑦通過 ⇒⑨通過⇒先頭へ戻るアドレス累算リング 4段パイプラインAデータ参照フロー ⑤B組およびA組index比較+0/8加算出力 ⇒⑥A先頭オフセット加算結果⇒⑧Aマスク結果 ⇒④Aメモリ出力⇒先頭 4段パイプラインBデータ参照フロー ⑤B組およびA組index比較+0/8加算出力 ⇒⑥B先頭オフセット加算結果⇒⑧Bマスク結果 ⇒③Bメモリ出力⇒先頭 ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑨ ① ② ⑤ ⑥ ⑦ ⑧ ① ① ② ② ⑦ ⑦ ⑨ ⑨ ⑤ ⑧ ⑤ ⑥ ⑥ ⑧ ④ ③ ⑩ ⑪ オフセット加算 アドレスマスク操作 読み出し結果 B42 読み出し結果 A00 B,A行列のベースアドレス C02へのストア 20210401 83 4列多重化CGRAに5本のデータ流を埋め込む
  • 84. mex(OP_CMPA_LE, &b0[h], INIT0?b:b0[h], INIT0?0:8, BR[r][2][1], BR[r][2][0]); mex(OP_CMPA_GE, &a0[h][CHIP], INIT0?a[h][CHIP]:a0[h][CHIP], INIT0?0:8, BR[r][2][1], BR[r][2][0]); mex(OP_CMPA_LE, &b0[h], INIT0?b:b0[h], INIT0?0:8, BR[r][2][1], BR[r][2][0]); mex(OP_CMPA_GE, &a0[h][CHIP], INIT0?a[h][CHIP]:a0[h][CHIP], INIT0?0:8, BR[r][2][1], BR[r][2][0]); mop(OP_LDR, 3, &BR[r][2][1], b0[h], bofs, MSK_W1, b, 2*LP*RMGRP, 0, 0, NULL, 2*LP*RMGRP); mop(OP_LDR, 3, &BR[r][2][0], a0[h][CHIP], bofs, MSK_W0, a[h][CHIP], 2*LP, 0, 0, NULL, 2*LP); mop(OP_LDR, 3, &BR[r][2][1], b0[h], bofs, MSK_W1, b, 2*LP*RMGRP, 0, 0, NULL, 2*LP*RMGRP); mop(OP_LDR, 3, &BR[r][2][0], a0[h][CHIP], bofs, MSK_W0, a[h][CHIP], 2*LP, 0, 0, NULL, 2*LP); mop(OP_LDWR, 1, &c00, c0[h][CHIP], oofs, MSK_W0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP); mop(OP_LDWR, 1, &c00, c0[h][CHIP], oofs, MSK_W0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP); exe(OP_CFMA, &c00, INIT0?c00:c00, EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][2][0], EXP_H3210, OP_NOP, 00); exe(OP_CFMA, &c00, INIT0?c00:c00, EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][2][0], EXP_H3210, OP_NOP, 00); mop(OP_STWR, 1, &c00, oofs, c0[h][CHIP], MSK_D0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP); mop(OP_STWR, 1, &c00, oofs, c0[h][CHIP], MSK_D0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP); 20210401 84 4列多重化CGRAに10本のデータ流を埋め込む
  • 85. 20210401 85 void emax6sc_pth_imax_02(struct sc_param *param) { Ull CHIP, LOOP0=param->LOOP0, LOOP1=param->LOOP1; Ull INIT1[4], INIT0[4]; Uint uLOOP[4]; for (CHIP=0; CHIP<1; CHIP++) { /* unit2 */ uLOOP[CHIP]=LOOP1*LOOP0; } while (1) { for (CHIP=0; CHIP<1; CHIP++) if (uLOOP[CHIP]) break; if (CHIP==1) break; for (CHIP=0; CHIP<1; CHIP++) { if (uLOOP[CHIP]==0) continue; if ((2 && SCBR[1].enq[CHIP]==SCBR[1].deq[CHIP]) || (2<17 && SCBR[2].enq[CHIP]!=SCBR[2].deq[CHIP])) continue; INIT1[CHIP]=(uLOOP[CHIP]>LOOP1*LOOP0-LOOP0); INIT0[CHIP]=(uLOOP[CHIP]-(uLOOP[CHIP]/LOOP0*LOOP0)==0); SCBR[1].deq[CHIP] = 1-SCBR[1].deq[CHIP]; { SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][0] = SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][6]; SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][3] = SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][2]; } { Ull base, offs, adr, mexdist, load64; static int emax6_unaligned_load_valid; static Ull emax6_unaligned_load_high; base = (!(0&1)||INIT0[CHIP]) ? ((0&2)?SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][0]:SCM1[2].b[CHIP][0]) : SCM1[2].awoo[CHIP][0]; offs = eam(1 ? SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][6] : SCM1[2].o[CHIP][0], 12); mexdist = INIT0[CHIP] ? 0 : 0; SCM1[2].awoo[CHIP][0] = (Ull)(INIT0[CHIP]?base:SCM1[2].awoo[CHIP][0]); adr = (Uint)(SCM1[2].awoo[CHIP][0] + offs); SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][1] = (Ull)*(Uint*)(adr&~3LL)<<32 | (Ull)*(Uint*)(adr&~3LL); SCM1[2].d[CHIP][0] = SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][1]; } { Ull base, offs, adr, mexdist, load64; static int emax6_unaligned_load_valid; static Ull emax6_unaligned_load_high; base = (!(1&1)||INIT0[CHIP]) ? ((1&2)?SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][0]:SCM1[2].b[CHIP][2]) : SCM1[2].awoo[CHIP][2]; offs = eam(1 ? SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][2] : SCM1[2].o[CHIP][2], 13); mexdist = INIT0[CHIP] ? 0 : 8; SCM1[2].awoo[CHIP][2] = (Ull)(INIT0[CHIP]?base:SCM1[2].awoo[CHIP][2])+(INIT0[CHIP]?0:((SCM0[2].d[CHIP][2]>>32)!=0xffffffff && (SCM1[2].d[CHIP][2]>>32)<=(SCM0[2].d[CHIP][2]>>32))?mexdist:0); adr = (Uint)(SCM1[2].awoo[CHIP][2] + offs); load64 = *(Ull*)(adr&~7LL); if ((adr&7) == 0) SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][9] = load64; else if (!emax6_unaligned_load_valid) { /* BR[][][1] */ emax6_unaligned_load_valid = 1; emax6_unaligned_load_high = load64; SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][9] = load64 >> (adr&7)*8; } else { /* BR[][][0] */ emax6_unaligned_load_valid = 0; SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][9] = emax6_unaligned_load_high << (8-(adr&7))*8 | load64 >> (adr&7)*8; } base = (!(1&1)||INIT0[CHIP]) ? ((1&2)?SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][0]:SCM0[2].b[CHIP][2]) : SCM0[2].awoo[CHIP][2]; offs = eam(1 ? SCBR[1].r[CHIP][SCBR[2].enq[CHIP]][2] : SCM0[2].o[CHIP][2], 12); mexdist = INIT0[CHIP] ? 0 : 8; SCM0[2].awoo[CHIP][2] = (Ull)(INIT0[CHIP]?base:SCM0[2].awoo[CHIP][2])+(INIT0[CHIP]?0:((SCM1[2].d[CHIP][2]>>32)!=0xffffffff && (SCM1[2].d[CHIP][2]>>32)>=(SCM0[2].d[CHIP][2]>>32))?mexdist:0); adr = (Uint)(SCM0[2].awoo[CHIP][2] + offs); load64 = *(Ull*)(adr&~7LL); if ((adr&7) == 0) SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][8] = load64; else if (!emax6_unaligned_load_valid) { /* BR[][][1] */ emax6_unaligned_load_valid = 1; emax6_unaligned_load_high = load64; SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][8] = load64 >> (adr&7)*8; } else { /* BR[][][0] */ emax6_unaligned_load_valid = 0; SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][8] = emax6_unaligned_load_high << (8-(adr&7))*8 | load64 >> (adr&7)*8; } SCM1[2].d[CHIP][2] = SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][9]; SCM0[2].d[CHIP][2] = SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][8]; } { union { Uint i; float f; } f3, f2, f1, f0; Ull t3, t2, t1, t0, ex1, ex2, ex3, ex4, ex5, c1, c0, ex1_outd, ex2_outd; ex1 = exm(!1||(INIT1[CHIP]&&INIT0[CHIP])||((1&1)&&INIT0[CHIP]) ? SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][1] : SCAR[2].r[CHIP][0], 0); ex2 = exm(((1&2)&&!INIT0[CHIP]) ? 0 : SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][9], 0); ex3 = exm(SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][8], 0); f1.i = (Uint)(ex1); f2.i = (Uint)(ex2>>32); f3.i = (Uint)(ex3>>32); if (f2.i != -1 && f2.i == f3.i) { f2.i = (Uint)(ex2); f3.i = (Uint)(ex3); f0.f = f1.f + (f2.f * f3.f); } else { f0.f = f1.f; } t0 = f0.i; ex1_outd = t0; ex2_outd = ex1_outd; SCAR[2].r[CHIP][0] = ex2_outd; } { Ull cs0, cs1, cs2, cs3, cex, base, offs, adr, mexdist; cex = 3; base = (!(2&1)||INIT0[CHIP]) ? ((2&2)?SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][0]:SCM0[2].b[CHIP][0]) : SCM0[2].awoo[CHIP][0]; offs = eam(0 ? SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][6] : SCM0[2].o[CHIP][0], 14); mexdist = INIT0[CHIP] ? 0 : 0; SCM0[2].awoo[CHIP][0] = (Ull)(INIT0[CHIP]?base:SCM0[2].awoo[CHIP][0]); adr = (Uint)(SCM0[2].awoo[CHIP][0] + offs); if (cex &1) *(Uint*)(adr&~3LL) = (1==1? SCAR[2].r[CHIP][0] : SCBR[2].r[CHIP][SCBR[2].enq[CHIP]][6]); } uLOOP[CHIP]--; SCBR[2].enq[CHIP] = 1-SCBR[2].enq[CHIP]; } } } 上のIMAXコードは4サイクルで全体を実行 逆コンパイルしC言語に戻すと以下の複雑さ 多機能を無理なくデータパスに収容してこそCGRAは高効率 mex(OP_CMPA_LE, &b0[h], INIT0?b:b0[h], INIT0?0:8, BR[r][2][1], BR[r][2][0]); mex(OP_CMPA_GE, &a0[h][CHIP], INIT0?a[h][CHIP]:a0[h][CHIP], INIT0?0:8, BR[r][2][1], BR[r][2][0]); mop(OP_LDR, 3, &BR[r][2][1], b0[h], bofs, MSK_W1, b, 2*LP*RMGRP, 0, 0, NULL, 2*LP*RMGRP); mop(OP_LDR, 3, &BR[r][2][0], a0[h][CHIP], bofs, MSK_W0, a[h][CHIP], 2*LP, 0, 0, NULL, 2*LP); mop(OP_LDWR, 1, &c00, c0[h][CHIP], oofs, MSK_W0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP); exe(OP_CFMA, &c00, INIT0?c00:c00, EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][2][0], EXP_H3210, OP_NOP, 00); mop(OP_STWR, 1, &c00, oofs, c0[h][CHIP], MSK_D0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP); IMAXコードと逆コンパイル結果の比較
  • 86. ① ① ② ② ⑦ ⑦ ⑨ ⑨ ⑤ ⑧ ⑤ ⑥ ⑥ ⑧ ④ ③ ⑩ ⑪ オフセット加算 アドレスマスク操作 読み出し結果 B42 読み出し結果 A00 疎行列と同様、読み出し結果の大小関係に従い、 1次元配列内の異なるアドレスA,Bの片側を更新 後続ユニットにアドレスA,Bと、2つの読み出し データを送り、アドレスとデータの各々の大小関 係に従い、いずれかのデータをストアすることに より、LogN段のソートのうち、1段分を実現 ソート全体のLogN段のうち、1段分の ソート結果をローカルメモリにストア ストア先アドレスは単調増加 同時に後続ユニットが、前回の実行結果を前段の ローカルメモリから読み出し、LogN段の次段以降 を担当する。全体として、ローカルメモリをダブル バッファとするパイプライン実行が可能となる。 マージソートの作り方 20210401 86
  • 87. 疎行列と同様、 読み出し結果の 大小関係に従い、 1次元配列内の 異なるアドレス A,Bの片側を更 新 後続ユニットにアドレスA,Bと、2つの読み出しデータを送り、アドレスとデータの各々の大小関 係に従い、いずれかのデータをストアすることにより、LogN段のソートのうち、1段分を実現 ストア先アドレスは単調増加 ソート全体のLogN段のうち、1段分のソート結果をローカルメモリにストア アドレスA アドレスB データB データA 疎行列と同様、 読み出し結果の 大小関係に従い、 1次元配列内の 異なるアドレス A,Bの片側を更 新 同一物理メモリ上で、計算結果を次に渡す マージソートのコンパイル結果 20210401 87
  • 88. おまけ。疎行列圧縮 count0 = 0; for (row=0; row<M1; row++) { for (col=0; col<M2; col++) { if (A32_0[row*M2+col] == 0) continue; if (count0 >= M1*M2) continue; A32_P[count0].d = A32_0[row*M2+col]; A32_P[count0].x = row*M2+col; count0++; } } *Bas1P = B32_P-1; /* end of B32_0 */ for (i=0; i<M1; i+=RMGRP) { r1 = (Ull)(i*M2-1)<<32; ibase0 = B32_0+i*M2; itop0 = B32_0+i*M2; itop1 = itop0+RMGRP*M2; obase0 = *Bas1P; /* end of B32_0 */ otop1 = otop0; otop0 = *Bas1P+8; /* top of B32_P */ //with-prefetch/post-drain //EMAX5A begin imax mapdist=0 for (CHIP=0; CHIP<NCHIP; CHIP++) { for (INIT1=1,LOOP1=RMGRP,rofs=0; LOOP1--; INIT1=0) { for (INIT0=1,LOOP0=M2,cofs=0; LOOP0--; INIT0=0) { mop(OP_LDWR, 1, &r0, ibase0++, 0, MSK_D0, itop0, M2*RMGRP, 0, 0, itop1, M2*RMGRP); exe(OP_ADD, &r1, r1, EXP_H3210, 0x100000000LL, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0LL); exe(OP_NOP, &std, r1, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_OR, r0, OP_NOP, 0LL); exe(OP_CMP_EQ, &cc0, r0, EXP_H1010, 0x00000000LL, EXP_H1010, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0LL); exe(OP_CMP_EQ, &cc1, r0, EXP_H1010, 0x80000000LL, EXP_H1010, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0LL); exe(OP_NOP, &cc2, cc0, EXP_H3210, 0, EXP_H3210, 0, EXP_H1010, OP_OR, cc1, OP_NOP, 0LL); exe(OP_CMOV, &oofs, cc2, EXP_H3210, 0, EXP_H3210, 8, EXP_H3210, OP_NOP, 0, OP_NOP, 0LL); exe(OP_ADD, &obase0, obase0, EXP_H3210, oofs, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0LL); mop(OP_STR, 3, &obase0, Bas1P, 0, MSK_D0, Bas1P, 2, 0, 0, NULL, 2); exe(OP_NOP, &AR[5][0], 0, EXP_H3210, 0, EXP_H3210, 0, EXP_H1010, OP_NOP, 0, OP_NOP, 0LL); cex(OP_CEXE, &ex0, 0, 0, 0, cc2, 0x0001); mop(OP_STR, ex0, &std, obase0, 0, MSK_D0, otop0, LP*2*RMGRP, 0, 0, otop1, LP*2*RMGRP); } } } //EMAX5A end //EMAX5A drain_dirty_lmm } 20210401 88
  • 89. CPU GPU Ultimate CGRA w/ high-speed compiler CGRA for Energy-efficient Cryptography Beyond-Neuromorphic Systems Non-Deterministic Computing 20210401 89 ナレータ VOICEVOX:もち子(cv 明日葉よもぎ) はらぺこエンジニアに贈るCGRAの世界2022 (ハッシュ計算とFFTと文字列検索) スパコンからIoTまで 省エネ社会に AI+BCだけじゃない超効率計算手法
  • 90. 20210401 90 ハッシュ計算には、面倒な演算が必要 for (i=0; i<ctx->mbuflen; i+=BLKSIZE) { /* 1データ流内の並列実行は不可能. 多数データ流のパイプライン実行のみ */ for (th=0; th<thnum; th++) { sregs[th*8+0] = state[th*8+0]; sregs[th*8+1] = state[th*8+1]; sregs[th*8+2] = state[th*8+2]; sregs[th*8+3] = state[th*8+3]; sregs[th*8+4] = state[th*8+4]; sregs[th*8+5] = state[th*8+5]; sregs[th*8+6] = state[th*8+6]; sregs[th*8+7] = state[th*8+7]; } for (j=0; j<BLKSIZE; j+=BLKSIZE/DIV) { for (th=0; th<thnum; th++) { a = sregs[th*8+0]; b = sregs[th*8+1]; c = sregs[th*8+2]; d = sregs[th*8+3]; e = sregs[th*8+4]; f = sregs[th*8+5]; g = sregs[th*8+6]; h = sregs[th*8+7]; #if (DIV==4) t1 = h+EP1(e)+CH(e,f,g)+k[j+ 0]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 0]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+ 1]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 1]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+ 2]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 2]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+ 3]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 3]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+ 4]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 4]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+ 5]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 5]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+ 6]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 6]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+ 7]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 7]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+ 8]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 8]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+ 9]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+ 9]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+10]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+10]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+11]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+11]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+12]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+12]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+13]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+13]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+14]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+14]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; t1 = h+EP1(e)+CH(e,f,g)+k[j+15]+mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE+th*BLKSIZE+j+15]; t2 = EP0(a)+MAJ(a,b,c); h = g; g = f; f = e; e = d+t1; d = c; c = b; b = a; a = t1+t2; #endif sregs[th*8+0] = a; sregs[th*8+1] = b; sregs[th*8+2] = c; sregs[th*8+3] = d; sregs[th*8+4] = e; sregs[th*8+5] = f; sregs[th*8+6] = g; sregs[th*8+7] = h; } } for (th=0; th<thnum; th++) { state[th*8+0] += sregs[th*8+0]; state[th*8+1] += sregs[th*8+1]; state[th*8+2] += sregs[th*8+2]; state[th*8+3] += sregs[th*8+3]; state[th*8+4] += sregs[th*8+4]; state[th*8+5] += sregs[th*8+5]; state[th*8+6] += sregs[th*8+6]; state[th*8+7] += sregs[th*8+7]; } }
  • 91. 20210401 91 ハッシュ計算には、面倒な演算が必要 case OP_MAJ: /* (((x) & (y))^((x) & (z))^((y) & (z))) */ ex1_outd = (r1&0xffffffff00000000LL) | (((r1 & r2)^(r1 & r3)^(r2 & r3))&0xffffffffLL); case OP_CH: /* (((x) & (y))^(~(x) & (z))) */ ex1_outd = (r1&0xffffffff00000000LL) | (((r1 & r2)^(~r1 & r3))&0xffffffffLL); case OP_ROTS: /* hi-32bit #define ROTRIGHT (((a) >> (b)) | ((a) << (32-(b)))) */ t2 = ex1_outd & 0xffffffff00000000LL; ro10 = r4>>32 & 0xff; ro11 = r4>>40 & 0xff; ro12 = r4>>48 & 0xff; t0 = ex1_outd & 0x00000000ffffffffLL; ro00 = r4 & 0xff; ro01 = r4>> 8 & 0xff; ro02 = r4>>16 & 0xff; ex2_outd = (((t2>>ro12|t2<<(32-ro12))^(t2>>ro11|t2<<(32-ro11))^(t2>>ro10|t2<<(32-ro10)))&0xffffffff00000000LL) |(((t0>>ro02|t0<<(32-ro02))^(t0>>ro01|t0<<(32-ro01))^(t0>>ro00|t0<<(32-ro00)))&0x00000000ffffffffLL); exe(OP_MAJ, &ep0maj, a, EXP_H1010, fb, EXP_H1010, gc, EXP_H1010, OP_ROTS, (2LL<<48)|(13LL<<40)|(22LL<<32). NOP,0); exe(OP_CH, &ep1ch, e, EXP_H3232, fb, EXP_H3232, gc, EXP_H3232, OP_ROTS, (6LL<<48)|(11LL<<40)|(25LL<<32), NOP,0);
  • 93. 20210401 93 FFTには、ダブルバッファリングが必要 BlockEnd = 1; for (BlockSize=2; BlockSize<=NumSamples; BlockSize<<=1) { for (i=0; i<NumSamples; i+=BlockSize) { for (j=i,n=0; n<BlockEnd; j++,n++) { k = j + BlockEnd; idx = n + BlockEnd; tr = art[idx]*RealOut[k] - ait[idx]*ImagOut[k]; ti = art[idx]*ImagOut[k] + ait[idx]*RealOut[k]; RealOut[k] = RealOut[j] - tr; ImagOut[k] = ImagOut[j] - ti; RealOut[j] += tr; ImagOut[j] += ti; } } BlockEnd = BlockSize; } 1段目 2段目 3段目
  • 95. 20210401 95 文字列検索 void strsearch(int i) { char *str = sstr[i]; int len = slen[i]; register size_t shift; register size_t pos = len - 1; char *found; while (pos < clen) { while (pos < clen && (shift = table[(unsigned char)target[pos]]) > 0) pos += shift; if (!shift) { if (!strncmp(str, &target[pos-len+1], len)) out0[i*clen+(pos-len+1)] = 0xff; pos++; } } }
  • 96. 20210401 96 文字列検索 for (i=0; i<snum; i+=OMAP) { //EMAX5A begin search mapdist=0 for (CHIP=0; CHIP<NCHIP; CHIP++) { //チップ方向は検索対象文書の大きさ方向 for (INIT0=1,LOOP0=loop,dmy=0; LOOP0--; INIT0=0) { //長さは32KB文字まで /* map#0 */ exe(OP_ADD, &t0[CHIP], t0[CHIP], EXP_H3210, 1LL, EXP_H3210, 0LL, EXP_H3210, OP_AND, 0x0000ffffffffffffLL, OP_NOP, 0LL); exe(OP_MCAS, &r00, slen0, EXP_H3210, 1, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe(OP_MCAS, &r01, slen0, EXP_H3210, 2, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe(OP_MCAS, &r02, slen0, EXP_H3210, 3, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe(OP_MCAS, &r03, slen0, EXP_H3210, 4, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); mop(OP_LDBR, 1, &BR[1][0][1], t0[CHIP], 0, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi); mop(OP_LDBR, 1, &BR[1][0][0], t0[CHIP], 1, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi); mop(OP_LDBR, 1, &BR[1][1][1], t0[CHIP], 2, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi); mop(OP_LDBR, 1, &BR[1][1][0], t0[CHIP], 3, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi); mop(OP_LDBR, 1, &BR[1][2][1], t0[CHIP], 4, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi); mop(OP_LDBR, 1, &BR[1][2][0], t0[CHIP], 5, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi); mop(OP_LDBR, 1, &BR[1][3][1], t0[CHIP], 6, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi); mop(OP_LDBR, 1, &BR[1][3][0], t0[CHIP], 7, MSK_D0, t0t[CHIP], dwi, 0, 0, (Ull)NULL, dwi); exe(OP_CMP_NE, &r16, c00, EXP_H3210, BR[1][0][1], EXP_H3210, 0LL, EXP_H3210, OP_AND, r00, OP_NOP, 0LL); // 1 if unmatch exe(OP_CMP_NE, &r17, c01, EXP_H3210, BR[1][0][0], EXP_H3210, 0LL, EXP_H3210, OP_AND, r01, OP_NOP, 0LL); // 1 if unmatch exe(OP_CMP_NE, &r18, c02, EXP_H3210, BR[1][1][1], EXP_H3210, 0LL, EXP_H3210, OP_AND, r02, OP_NOP, 0LL); // 1 if unmatch exe(OP_CMP_NE, &r19, c03, EXP_H3210, BR[1][1][0], EXP_H3210, 0LL, EXP_H3210, OP_AND, r03, OP_NOP, 0LL); // 1 if unmatch exe(OP_MCAS, &r04, slen0, EXP_H3210, 5, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe(OP_MCAS, &r05, slen0, EXP_H3210, 6, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe(OP_MCAS, &r06, slen0, EXP_H3210, 7, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe(OP_MCAS, &r07, slen0, EXP_H3210, 8, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); exe(OP_CMP_NE, &r20, c04, EXP_H3210, BR[1][2][1], EXP_H3210, 0LL, EXP_H3210, OP_AND, r04, OP_NOP, 0LL); // 1 if unmatch exe(OP_CMP_NE, &r21, c05, EXP_H3210, BR[1][2][0], EXP_H3210, 0LL, EXP_H3210, OP_AND, r05, OP_NOP, 0LL); // 1 if unmatch exe(OP_CMP_NE, &r22, c06, EXP_H3210, BR[1][3][1], EXP_H3210, 0LL, EXP_H3210, OP_AND, r06, OP_NOP, 0LL); // 1 if unmatch exe(OP_CMP_NE, &r23, c07, EXP_H3210, BR[1][3][0], EXP_H3210, 0LL, EXP_H3210, OP_AND, r07, OP_NOP, 0LL); // 1 if unmatch exe(OP_ADD3, &r10, r16, EXP_H3210, r17, EXP_H3210, r18, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); // exe(OP_ADD3, &r11, r19, EXP_H3210, r20, EXP_H3210, r21, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); // exe(OP_ADD, &r12, r22, EXP_H3210, r23, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); // exe(OP_ADD3, &r00, r10, EXP_H3210, r11, EXP_H3210, r12, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); // exe(OP_MCAS, &r31, 0LL, EXP_H3210, r00, EXP_H3210, 0LL, EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); // FF if match mop(OP_STBR, 3, &r31, r0[CHIP]++, 0, MSK_D0, r0t[CHIP], dwo, 0, 0, (Ull)NULL, dwo); /* map#1 */ : /* map#8 */ : } } //EMAX5A end //EMAX5A drain_dirty_lmm }
  • 98. CPU GPU Ultimate CGRA w/ high-speed compiler CGRA for Energy-efficient Cryptography Beyond-Neuromorphic Systems Non-Deterministic Computing 98 ナレータ VOICEVOX:もち子(cv 明日葉よもぎ) はらぺこエンジニアに贈るCGRAの世界2022 (高速コンパイラ) スパコンからIoTまで 省エネ社会に AI+BCだけじゃない超効率計算手法
  • 99. 20210401 99 FMA C+B*A ⇒ D Dual Random access
  • 100. 20210401 100 FMA C+B*A ⇒ D D has location info (same as C) Sequential updates
  • 101. 20210401 101 FMA C+B*A ⇒ C Accumulation
  • 102. 20210401 102 コンパイル過程 src/conv-mark/conv-mark の入力 void tone_curve(r, d, t) unsigned int *r, *d; unsigned char *t; { #if !defined(EMAX5) && !defined(EMAX6) int j; for (j=0; j<WD; j++) { *d = ((t)[*r>>24])<<24 | (t[256+((*r>>16)&255)])<<16 | (t[512+((*r>>8)&255)])<<8; r++; d++; } #else Ull t1 = t; Ull t2 = t+256; Ull t3 = t+512; Ull BR[16][4][4]; /* output registers in each unit */ Ull r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15; Ull r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31; int loop=WD; //EMAX5A begin tone_curve mapdist=0 while (loop--) { mop(OP_LDWR, 1, &BR[0][1][1], (Ull)(r++), 0LL, MSK_D0, (Ull)r, 320, 0, 0, (Ull)NULL, 320); /* stage#0 */ mop(OP_LDUBR, 1, &BR[1][1][1], (Ull)t1, BR[0][1][1], MSK_B3, (Ull)t1, 64, 0, 0, (Ull)NULL, 64); /* stage#1 */ mop(OP_LDUBR, 1, &BR[1][2][1], (Ull)t2, BR[0][1][1], MSK_B2, (Ull)t2, 64, 0, 0, (Ull)NULL, 64); /* stage#1 */ mop(OP_LDUBR, 1, &BR[1][3][1], (Ull)t3, BR[0][1][1], MSK_B1, (Ull)t3, 64, 0, 0, (Ull)NULL, 64); /* stage#1 */ exe(OP_MMRG, &r1, BR[1][1][1], EXP_H3210, BR[1][2][1], EXP_H3210, BR[1][3][1], EXP_H3210, OP_NOP, 0LL, OP_NOP, 0LL); mop(OP_STWR, 3, &r1, (Ull)(d++), 0LL, MSK_D0, (Ull)d, 320, 0, 0, (Ull)NULL, 320); /* stage#2 */ } //EMAX5A end #endif }  filter+rmm.c
  • 103. 20210401 103 コンパイル過程 通常のARM-Cコンパイラの入力 1/3  filter+rmm-emax6.c ../../src/conv-c2c/emax6.h ../../src/conv-c2c/emax6lib.c void tone_curve(r, d, t) unsigned int *r, *d; unsigned char *t; { Ull t1 = t; Ull t2 = t+256; Ull t3 = t+512; Ull BR[16][4][4]; Ull r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31; int loop=WD; volatile emax6_conf_tone_curve(); emax6.lmmio = emax6.lmmic; emax6.lmmic = 1-emax6.lmmic; emax6.mapdist = 0; *(Uint*)&emax6.lmmi[0][0][1][emax6.lmmic] = 0x013f0001|(0<<2); emax6.lmmi[0][0][1][emax6.lmmic].ofs = 0; emax6.lmmi[0][0][1][emax6.lmmic].top = r; *(Uint*)&emax6.lmmi[0][1][1][emax6.lmmic] = 0x003f0001|(0<<2); emax6.lmmi[0][1][1][emax6.lmmic].ofs = 0; emax6.lmmi[0][1][1][emax6.lmmic].top = t1; *(Uint*)&emax6.lmmi[0][1][2][emax6.lmmic] = 0x003f0001|(0<<2); emax6.lmmi[0][1][2][emax6.lmmic].ofs = 0; emax6.lmmi[0][1][2][emax6.lmmic].top = t2; *(Uint*)&emax6.lmmi[0][1][3][emax6.lmmic] = 0x003f0001|(0<<2); emax6.lmmi[0][1][3][emax6.lmmic].ofs = 0; emax6.lmmi[0][1][3][emax6.lmmic].top = t3; *(Uint*)&emax6.lmmi[0][2][0][emax6.lmmic] = 0x013f0003|(0<<2); emax6.lmmi[0][2][0][emax6.lmmic].ofs = 0; emax6.lmmi[0][2][0][emax6.lmmic].top = d; emax6.lmmi_bitmap[0] = 0x0000000000000004LL; emax6.lmmi_bitmap[1] = 0x0000000000000003LL; emax6.lmmi_bitmap[2] = 0x0000000000000002LL; emax6.lmmi_bitmap[3] = 0x0000000000000002LL; emax6_pre_with_drain_cache(); get_nanosec(NANOS_ARM); if (emax6.last_conf == emax6_conf_tone_curve) { emax6.status = STATUS_DRAIN; emax6_check_lmmi_and_dma(0, 1, 0, 0, 2, 0);/*drain*/ } get_nanosec(NANOS_DRAIN); LMMのアドレス範囲情報 必要に応じて前回演算結果の回収
  • 104. 20210401 104 コンパイル過程 通常のARM-Cコンパイラの入力 2/3 if (emax6.last_conf != emax6_conf_tone_curve) { Dll *dst, *src; int i,j; emax6.status = STATUS_CONF; emax6.last_conf = emax6_conf_tone_curve; emax6.lastdist = 0; dst = (Dll*)(((struct reg_ctrl*)emax6.reg_ctrl)->i[0].conf); src = (Dll*)emax6_conf_tone_curve; for (i=0; i<sizeof(conf)/sizeof(Dll); i++) *dst++ = *src++; for (i=0; i<64; i++) { for (j=0; j<4; j++) emax6.lmmi[0][i][j][emax6.lmmio].v = 0; } while (((struct reg_ctrl*)emax6.reg_ctrl)->i[0].stat & 0xf0); //LMRING_BUSY } get_nanosec(NANOS_CONF); emax6.status = STATUS_REGV; ((struct reg_ctrl*)emax6.reg_ctrl)->i[0].breg[63][0].br[0] = loop; ((struct reg_ctrl*)emax6.reg_ctrl)->i[0].breg[63][0].br[1] = -1LL; ((struct reg_ctrl*)emax6.reg_ctrl)->i[0].addr[0][1].ea1b = (Ull)r; ((struct reg_ctrl*)emax6.reg_ctrl)->i[0].addr[0][1].ea1o = (Ull)0LL; ((struct reg_ctrl*)emax6.reg_ctrl)->i[0].addr[1][1].ea1b = (Ull)t1; ((struct reg_ctrl*)emax6.reg_ctrl)->i[0].addr[1][2].ea1b = (Ull)t2; ((struct reg_ctrl*)emax6.reg_ctrl)->i[0].addr[1][3].ea1b = (Ull)t3; ((struct reg_ctrl*)emax6.reg_ctrl)->i[0].addr[2][0].ea0b = (Ull)d; ((struct reg_ctrl*)emax6.reg_ctrl)->i[0].addr[2][0].ea0o = (Ull)0LL; get_nanosec(NANOS_REGV); emax6.status = STATUS_RANGE; {struct reg_ctrl *reg_ctrl = emax6.reg_ctrl; Uint lmmic = emax6.lmmic; *(Ull*)&(reg_ctrl->i[0].addr[0][1].top)=((Ull)(emax6.lmmi[0][0][1][lmmic].top+*((Ushort*)&emax6.lmmi[0][0][1][lmmic]+1)*sizeof(Uint)+(sizeof(Uint)-1))<<32)|(Ull)(Uint)emax6.lmmi[0][0][1][lm *(Ull*)&(reg_ctrl->i[0].addr[1][1].top)=((Ull)(emax6.lmmi[0][1][1][lmmic].top+*((Ushort*)&emax6.lmmi[0][1][1][lmmic]+1)*sizeof(Uint)+(sizeof(Uint)-1))<<32)|(Ull)(Uint)emax6.lmmi[0][1][1][lm *(Ull*)&(reg_ctrl->i[0].addr[1][2].top)=((Ull)(emax6.lmmi[0][1][2][lmmic].top+*((Ushort*)&emax6.lmmi[0][1][2][lmmic]+1)*sizeof(Uint)+(sizeof(Uint)-1))<<32)|(Ull)(Uint)emax6.lmmi[0][1][2][lm *(Ull*)&(reg_ctrl->i[0].addr[1][3].top)=((Ull)(emax6.lmmi[0][1][3][lmmic].top+*((Ushort*)&emax6.lmmi[0][1][3][lmmic]+1)*sizeof(Uint)+(sizeof(Uint)-1))<<32)|(Ull)(Uint)emax6.lmmi[0][1][3][lm *(Ull*)&(reg_ctrl->i[0].addr[2][0].top)=((Ull)(emax6.lmmi[0][2][0][lmmic].top+*((Ushort*)&emax6.lmmi[0][2][0][lmmic]+1)*sizeof(Uint)+(sizeof(Uint)-1))<<32)|(Ull)(Uint)emax6.lmmi[0][2][0][lm } get_nanosec(NANOS_RANGE); 命令写像が前回と異なる場合は 再写像 AXIIF/PIOによるレジスタ初期化 LMMにアドレス範囲情報書き込み
  • 105. 20210401 105 コンパイル過程 通常のARM-Cコンパイラの入力 3/3 emax6.status = STATUS_LOAD; emax6_check_lmmi_and_dma(0, 2, emax6.lastdist, 0, 0, 1);/*load*/ emax6_check_lmmi_and_dma(0, 2, emax6.lastdist, 0, 1, 1);/*load*/ emax6_check_lmmi_and_dma(0, 2, emax6.lastdist, 0, 1, 2);/*load*/ emax6_check_lmmi_and_dma(0, 2, emax6.lastdist, 0, 1, 3);/*load*/ get_nanosec(NANOS_LOAD); ((struct reg_ctrl*)emax6.reg_ctrl)->i[0].cmd = 3LL; // EXEC {struct reg_ctrl *reg_ctrl = emax6.reg_ctrl; Uint lmmic = emax6.lmmic; } emax6.lmmd[2][0] = 0xff>>7; while (((struct reg_ctrl*)emax6.reg_ctrl)->i[0].stat); //LMRING_BUSY|EXRING_BUSY get_nanosec(NANOS_EXEC); asm volatile("b emax6_conf_end_tone_curven" ".align 5n" ".global emax6_conf_tone_curven" "emax6_conf_tone_curve:n" " .word 0x031e0003, 0x00000000n" " .word 0xffff0000, 0x00000000n" " .word 0x00000000, 0x00000000n" : " .word 0xffff0000, 0x00000000n" " .word 0x00000000, 0x00000000n" " .word 0x00000000, 0x00000000n" ".global emax6_conf_end_tone_curven" "emax6_conf_end_tone_curve:n" ); } AXIIF/DMAによる LMMデータ書き込み AXIIF/PIOによるIMAX起動 演算と同時の次データ転送が あればDMA起動 UNITのconfiguration情報
  • 106. ld @(gr1, 0) -> gr2 add gr1, 4 -> gr1 sub gr3, 1 -> gr3, z VLIW0 add sub gr1 gr3z Register File gr1 4 gr3 1 eag gr1 4 0 1 2 3 4 5 6 0 0 0 0 0 0 0 0 1 2 3 4 5 6 0 0 0 0 0 0 0 0 1 2 3 4 5 6 0 0 0 0 0 0 0 0 1 2 3 4 5 6 0 0 0 0 0 0 0 0 1 2 3 4 5 6 0 0 0 0 0 0 0 z 0 z 0 z 0 z 0 z 0 gr2 ld Propagation skip table gr/cr Stage 0 1 2 3 4 20210401 106 コンパイルが速いのは、非探索的だから
  • 107. ld @(gr4, 0) -> gr5 add gr4, 4 -> gr4 bz end VLIW1 add sub gr1 gr3z add gr4 Register File gr1 4 gr4 4 gr3 1 gr4 bz end eag eag gr1 4 gr4 4 0 1 2 3 4 5 6 0 1 1 1 0 0 0 0 1 2 3 4 5 6 0 1 1 1 0 0 0 0 1 2 3 4 5 6 0 0 1 0 0 0 0 0 1 2 3 4 5 6 0 0 0 0 0 0 0 0 1 2 3 4 5 6 0 0 0 0 0 0 0 z 1 z 1 z 0 z 0 z 0 gr5 ld gr2 ld Propagation skip table gr/cr Stage 0 1 2 3 4 VLIW1 20210401 107 LAPPと同様の非探索的高速コンパイル手法
  • 108. gr5 ld gr2 ld sll gr2, 16 -> gr2 VLIW2 add sub gr1 gr3z add gr4 sll Register File gr1 4 gr4 4 16 gr3 1 0 1 2 3 4 5 6 0 1 1 1 1 1 0 0 1 2 3 4 5 6 0 1 1 1 1 1 0 0 1 2 3 4 5 6 0 0 1 0 1 1 0 0 1 2 3 4 5 6 0 0 0 0 0 1 0 0 1 2 3 4 5 6 0 0 0 0 0 0 0 z 1 z 1 z 0 z 0 z 0 gr4 bz end eag eag gr1 4 gr4 4 Propagation skip table gr/cr Stage 0 1 2 3 4 VLIW2 VLIW2 20210401 108 LAPPと同様の非探索的高速コンパイル手法
  • 109. gr5 ld gr2 ld or gr2, gr5 -> gr5 VLIW3 add sub gr1 gr3z add gr4 gr2 Register File or gr5 gr1 4 gr4 4 gr3 1 0 1 2 3 4 5 6 0 1 1 1 1 1 0 0 1 2 3 4 5 6 0 1 1 1 1 1 0 0 1 2 3 4 5 6 0 0 1 0 1 1 0 0 1 2 3 4 5 6 0 0 1 0 0 1 0 0 1 2 3 4 5 6 0 0 0 0 0 0 0 z 1 z 1 z 0 z 0 z 0 gr4 bz end eag eag gr1 4 gr4 4 Propagation skip table gr/cr Stage 0 1 2 3 4 sll 16 VLIW3 VLIW3 VLIW3 20210401 109 LAPPと同様の非探索的高速コンパイル手法
  • 110. gr5 gr2 ld st, gr5 -> @(gr6, 0) add gr6, 4 -> gr6 bra loop VLIW4 add sub gr1 gr3z add gr4 Register File gr5 gr5 add gr6 gr1 4 gr4 4 16 gr6 gr6 4 gr6 gr6 gr3 1 0 1 2 3 4 5 6 0 1 1 1 1 1 0 0 1 2 3 4 5 6 0 1 1 1 1 1 0 0 1 2 3 4 5 6 0 0 1 0 1 1 0 0 1 2 3 4 5 6 0 0 1 0 0 1 0 0 1 2 3 4 5 6 0 0 0 0 0 1 0 z 1 z 1 z 0 z 0 z 0 gr4 gr6 bz bra end loop eag eag eag gr1 4 gr4 4 gr6 0 st Propagation skip table gr/cr Stage 0 1 2 3 4 gr5 ld gr2 or sll VLIW4 VLIW4 VLIW4 VLIW4 20210401 110 LAPPと同様の非探索的高速コンパイル手法
  • 111. CPU GPU Ultimate CGRA w/ high-speed compiler CGRA for Energy-efficient Cryptography Beyond-Neuromorphic Systems Non-Deterministic Computing 111 ナレータ VOICEVOX:もち子(cv 明日葉よもぎ) はらぺこエンジニアに贈るCGRAの世界2022 (超絶技巧3重ループ) スパコンからIoTまで 省エネ社会に AI+BCだけじゃない超効率計算手法
  • 114. 20210401 114 確率的積和演算の2次元データ一括処理 //EMAX5A begin smax2 mapdist=0 for (CHIP=0; CHIP<NCHIP; CHIP++) { /* will be parallelized by multi-chip (M/#chip) */ for (INIT1=1,LOOP1=RMGRP,rofs=(0-IC32)<<32|((0-1LL)&0xffffffff); LOOP1--; INIT1=0) { for (INIT0=1,LOOP0=IC32/32,cofs=(0-32LL)<<32|((0)&0xffffffff); LOOP0--; INIT0=0) { ① exe(OP_ADD, &cofs, INIT0?cofs:cofs, EXP_H3210, 32LL<<32|0, EXP_H3210, 0, EXP_H3210, OP_AND, 0xffffffffffffffffLL, OP_NOP,0); ② exe(OP_ADD, &rofs, rofs, EXP_H3210, INIT0?IC321:0, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP,0); ③ exe(OP_ADD, &bofs, rofs, EXP_H3210, cofs, EXP_H3210, 0, EXP_H3210, OP_AND, 0xffffffffffffffffLL, OP_NOP,0); ④ exe(OP_ADD, &oofs, rofs, EXP_H3210, cofs, EXP_H3210, 0, EXP_H3210, OP_AND, 0x00000000ffffffffLL, OP_NOP,0); spike01_core1( 2, 0); spike01_core1( 3, 1); spike01_core1( 4, 2); spike01_core1( 5, 3); spike01_core1( 6, 4); spike01_core1( 7, 5); spike01_core1( 8, 6); #define spike01_core1(r, s) mo4(OP_LDRQ, 1, BR[r][2], b0, bofs, MSK_W1, b, IC32D4RMGRP, 0, 0, NULL, IC32D4RMGRP); mo4(OP_LDRQ, 1, BR[r][1], a[s][CHIP], cofs, MSK_W1, a[s][CHIP], IC32D4, 0, 0, NULL, IC32D4 ); mop(OP_LDBR, 1, &b00, c0[s][CHIP], oofs, MSK_W0, c[s][CHIP], RMGRPD4, 0, 1, NULL, RMGRPD4 ); ex4(OP_SFMA, &b00, INIT0?b00:b00, EXP_H3210, BR[r][1], EXP_H3210, BR[r][2], EXP_H3210, OP_NOP,0, OP_NOP,0 ); mop(OP_STBR, 1, &b00, oofs, c0[s][CHIP], MSK_D0, c[s][CHIP], RMGRPD4, 0, 1, NULL, RMGRPD4 )
  • 115. 20210401 115 ベイズ推定に使う2次元データ一括処理 //EMAX5A begin x1 mapdist=0 for (INIT1=1,LOOP1=RMGRP,row=0-M*4; LOOP1--; INIT1=0) { for (INIT0=1,LOOP0=M/W,bofs=0-W*4; LOOP0--; INIT0=0) { exe(OP_ADD, &bofs, INIT0?bofs:bofs, EXP_H3210, W*4, EXP_H3210, 0, EXP_H3210, OP_AND, 0x00ffffffffLL, OP_NOP,0); exe(OP_ADD, &row, row, EXP_H3210, INIT0?M*4:0, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP,0); exe(OP_ADD, &rofs, row, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_AND, 0x00ffffffffLL, OP_NOP,0); mop(OP_LDWR, 1, &b00, c600, rofs, MSK_W0, c60, M*RMGRP, 0, 1, NULL, M*RMGRP); exe(OP_ADD, &b00, INIT0?b00:b00, EXP_H3210, PARAM, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP,0); mop(OP_STWR, 1, &b00, rofs, c600, MSK_D0, c60, M*RMGRP, 0, 1, NULL, M*RMGRP);
  • 116. 20210401 116 疎行列積に使う2次元データ一括処理 //EMAX5A begin imax mapdist=0 for (CHIP=0; CHIP<NCHIP; CHIP++) { /* will be parallelized by multi-chip (M/#chip) */ for (INIT1=1,LOOP1=RMGRP,rofs=(0-LP*8)<<32|((0-4LL)&0xffffffff); LOOP1--; INIT1=0) { for (INIT0=1,LOOP0=LP,cofs=(0LL)<<32|((0LL)&0xffffffff); LOOP0--; INIT0=0) { exe(OP_ADD, &rofs, rofs, EXP_H3210, INIT0?(LP*8)<<32|4:0, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP,0); exe(OP_ADD, &bofs, rofs, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_AND, 0xffffffff00000000LL, OP_NOP,0); exe(OP_ADD, &oofs, rofs, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_AND, 0x00000000ffffffffLL, OP_NOP,0); sparse_core1( 2, 0); sparse_core1( 3, 1); /* H=2 */ sparse_core1( 4, 2); sparse_core1( 5, 3); /* H=4 */ sparse_core1( 6, 4); sparse_core1( 7, 5); sparse_core1( 8, 6); sparse_core1( 9, 7); /* H=8 */ sparse_core1( 10, 8); sparse_core1( 11, 9); sparse_core1( 12, 10); #define sparse_core1(r, h) mex(OP_CMPA_LE, &b0[h],INIT0?b:b0[h],INIT0?0:8,OP_CMPA_GE,&a0[h][CHIP],INIT0?a[h][CHIP]:a0[h][CHIP],INIT0?0:8,0,BR[r][2][1],……); mop(OP_LDR, 3, &BR[r][2][1], b0[h], bofs, MSK_W1, b, 2*LP*RMGRP, 0, 0, NULL, 2*LP*RMGRP ); mop(OP_LDR, 3, &BR[r][2][0], a0[h][CHIP], bofs, MSK_W0, a[h][CHIP], 2*LP, 0, 0, NULL, 2*LP ); exe(OP_NOP, &AR[r][0], 0, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP,0); mop(OP_LDWR, 1, &c00, c0[h][CHIP], oofs, MSK_W0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP ); exe(OP_CFMA, &c00, INIT0?c00:c00, EXP_H3210, BR[r][2][1], EXP_H3210, BR[r][2][0], EXP_H3210, OP_NOP, 0, OP_NOP,0); mop(OP_STWR, 1, &c00, oofs, c0[h][CHIP], MSK_D0, c[h][CHIP], RMGRP, 0, 1, NULL, RMGRP )
  • 117. CPU GPU Ultimate CGRA w/ high-speed compiler CGRA for Energy-efficient Cryptography Beyond-Neuromorphic Systems Non-Deterministic Computing 117 ナレータ VOICEVOX:もち子(cv 明日葉よもぎ) はらぺこエンジニアに贈るCGRAの世界2022 (HW/SW協調設計)
  • 118. 20210401 118 Templates for IMAX programming exe(OP_X, &var|&AR[0-63][0-3], s1, e1, s2, e2, s3, e3, OP_Y, s4, OP_Z, s5) ex4(OP_X, &var|&AR[0-63], s1, e1, s2, e2, s3, e3, OP_Y, s4, OP_Z, s5) exe(OP_X, &var, INIT0?var:var, e1, s2, e2, s3, e3, OP_Y, s4, OP_Z, s5) exe(OP_X, &var, var, e1, INIT0?s2:0, e2, s3, e3, OP_Y, s4, OP_Z, s5) mex(OP MEX2, &s2, INIT0?s20:s2, INIT0?0:expr, OP MEX1, &s1, INIT0?s10:s1, INIT0?0:expr, limit, BR[0-63][0-3][1], BR[0-63][0-3][0]) cex(OP_CEXE, &ex0-9, c3, c2, c1, c0, 16bit-pattern) mop(OP_X, ex9-0, &src|&dst, base, offset, mask, top, len, block, force, ptop, plen) mo4(OP_X, ex9-0, &src|&dst, base, offset, mask, top, len, block, force, ptop, plen) DMA information
  • 119. Original C C+IMAX-code Target (A) Intel-PC Native Intel-emax6lib Intel-CC Intel-CC Algorithm (B) Intel-PC Simulator ARM+emax6lib ARM-XCC ARM-XCC(cross compiler) Algorithm (C) Intel-PC Simulator IMAX/PIO Conv-c2c + ARM-XCC IMAX-code (D) Intel-PC Simulator IMAX/DMA Conv-c2c + ARM-XCC IMAX-code + testbench (E) Verilog Simulator Vsim + Testbench Verilog (F) FPGA+Chipscope Vivado + hw_server Real Hardware (G) ARM-SoC ARM+emax6lib ARM-CC Conv-c2c + ARM-CC Algorithm (H) ARM-SoC IMAX/PIO Conv-c2c + ARM-CC Hardware w/o DMA (I) ARM-SoC IMAX/DMA Conv-c2c + ARM-CC Performance Conv-c2c (IMAX-CC) runs on CentOS/FreeBSD/ARM-SoC - IMAX-code is translated to IMAX-config + DMA sequence, and embedded in ARM binary. Simulator (csim) runs on CentOS/FreeBSD - Register transfer level simulator - ARMv8, 64cores, 32threads/core, L1+L2cache/core, L2-directory reorder-buffer, parameterized memory hierarchy - 64 IMAX, AXI4-IF, test-bench generator 20210401 119 HW/SW codesign
  • 120. /* SCREEN=WD*HT */ for (row=0; row<HT; row++) { for (col=0; col<WD; col++) { pix = in[row*WD+col]; r = t[ pix>>24 ]; g = t[256+((pix>>16)&255)]; b = t[512+((pix>> 8)&255)]; out[row*WD+col]=r<<24 | g<<16 | b<<8; } } 20210401 120 簡単な tone_curveをC言語で書く Load → Store ← Color map tables
  • 121. /* SCREEN=WD*HT */ for (row=0; row<HT; row++) { //EMAX5A begin tone_curve mapdist=0 for (LOOP0=WD, col=-4; LOOP0--;) { col += 4; pix = in[row*WD+col/4]; r = t[ pix>>24 ]; g = t[256+((pix>>16)&255)]; b = t[512+((pix>> 8)&255)]; out[row*WD+col/4]=r<<24 | g<<16 | b<<8; } //EMAX5A end } //EDMAX5A drain_dirty_lmm 20210401 121 IMAXのループ構造記述に合わせる Load → Store ← Color map tables /* SCREEN=WD*HT */ for (row=0; row<HT; row++) { for (col=0; col<WD; col++) { pix = in[row*WD+col]; r = t[ pix>>24 ]; g = t[256+((pix>>16)&255)]; b = t[512+((pix>> 8)&255)]; out[row*WD+col]=r<<24 | g<<16 | b<<8; } } Load → Store ← Color map tables
  • 122. /* SCREEN=WD*HT */ for (row=0; row<HT; row++) { //EMAX5A begin tone_curve mapdist=0 for (LOOP0=WD, col=-4; LOOP0--;) { col += 4; mop(OP_LDWR, &pix, in_row_WD, col, MSK_W0, in, WD); //pix = in[row*WD+col/4]; mop(OP_LDUBR, &r, t_r, pix, MSK_B3, t, 256*3/4); //r = t[ pix>>24 ]; mop(OP_LDUBR, &g, t_g, pix, MSK_B2, t, 256*3/4); //g = t[256+((pix>>16)&255)]; mop(OP_LDUBR, &b, t_b, pix, MSK_B1, t, 256*3/4); //b = t[512+((pix>> 8)&255)]; out[row*WD+col/4]=r<<24|g<<16|b<<8; } //EMAX5A end } //EDMAX5A drain_dirty_lmm 20210401 122 IMAXの高機能関数記述に書き換えながらデバッグする Load → Store ← Color map tables
  • 123. /* SCREEN=WD*HT */ for (row=0; row<HT; row++) { //EMAX5A begin tone_curve mapdist=0 for (LOOP0=WD, col=-4; LOOP0--;) { exe(OP_ADD, &col, col, EXP_H3210, 4, EXP_H3210, 0, EXP_H3210); //col += 4; mop(OP_LDWR, &pix, in_row_WD, col, MSK_W0, in, WD); //pix = in[row*WD+col/4]; mop(OP_LDUBR, &r, t_r, pix, MSK_B3, t, 256*3/4); //r = t[ pix>>24 ]; mop(OP_LDUBR, &g, t_g, pix, MSK_B2, t, 256*3/4); //g = t[256+((pix>>16)&255)]; mop(OP_LDUBR, &b, t_b, pix, MSK_B1, t, 256*3/4); //b = t[512+((pix>> 8)&255)]; exe(OP_MMRG, &out, r, EXP_H3210, g, EXP_H3210, b, EXP_H3210); mop(OP_STWR, &out, out_row_WD, col, MSK_W0); //out[row*WD+col/4]=r<<24|g<<16|b<<8; } //EMAX5A end } //EDMAX5A drain_dirty_lmm 20210401 123 全部書き換えたら逐次実行プログラムとしてデバッグ Load → Store ← Color map tables
  • 124. 20210401 124 データの配置と流れの観点から見直す Load → Store ← Color map tables /* SCREEN=WD*HT */ for (row=0; row<HT; row++) { //EMAX5A begin tone_curve mapdist=0 for (LOOP0=WD, col=-4; LOOP0--;) { exe(OP_ADD, &col, col, EXP_H3210, 4, EXP_H3210, 0, EXP_H3210); //col += 4; mop(OP_LDWR, &pix, in_row_WD, col, MSK_W0, in, WD); //pix = in[row*WD+col/4]; mop(OP_LDUBR, &r, t_r, pix, MSK_B3, t, 256*3/4); //r = t[ pix>>24 ]; mop(OP_LDUBR, &g, t_g, pix, MSK_B2, t, 256*3/4); //g = t[256+((pix>>16)&255)]; mop(OP_LDUBR, &b, t_b, pix, MSK_B1, t, 256*3/4); //b = t[512+((pix>> 8)&255)]; exe(OP_MMRG, &out, r, EXP_H3210, g, EXP_H3210, b, EXP_H3210); mop(OP_STWR, &out, out_row_WD, col, MSK_W0); //out[row*WD+col/4]=r<<24|g<<16|b<<8; } //EMAX5A end } //EDMAX5A drain_dirty_lmm
  • 127. 20210401 127 HBM2 and VMK version will appear soon IMAX2: Ultra-speed compilable CGRA 2022/12/XX First CGRA, based on linear cores (not island-style) 32-unit, 1280-operations/4cycle (768-int32, 256-fp32, 256-media8/16, 512-load/store, 1024-stochastic-fma8, and 128-sparse-matrix) IMAX2 32 cores 250MHz 1280 operations per 4 cycles ALVEO-U280/U280 Memory/core: 64KB Operations/core: 32-load/8-store, quad-sparse-load, 3-cascaded octa-int/media, octa-single-float FMA, 32-stochastic FMA http://archlab.naist.jp/proj-arm64/fpga/U280-step4000-20221020.img.gz IMAX2 32 cores 250MHz 1280 operations per 4 cycles VMK180/VM1802 Memory/core: 64KB Operations/core: 32-load/8-store, quad-sparse-load, 3-cascaded octa-int/media, octa-single-float FMA, 32-stochastic FMA http://archlab.naist.jp/proj-arm64/fpga/VMK180-step4000-20221020.img.gz