Mais conteúdo relacionado

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だけじゃない超効率計算手法
  2. 20210401 2 20180716 2 電力需要の60%が情報機器 実効為替レートが低下し CPU/GPUが買えない未来 AIもクラウドもスパコンも 増やせない未来 CO2が減らないSociety 5.0 電力需要の10%が情報機器 非ノイマン型を 自給・輸出する未来 身の丈に合ったAIとスパコン と電力消費 低炭素社会 202X年 ノイマン型の段階的削減!?
  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)
  4. 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
  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.
  12. ただし、ノイマン型に学ばない非ノイマン型には、汎用性も未来もない 20210401 12 例えば、FPGAを真似ただけのCGRAは、コンパイルに1時間 これをコンピュータと呼ぶのは無理がある プログラムやデータの変換に長時間がかかる 新原理非ノイマン型に存在価値はない
  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 のパイプライン動作を止め てしまうから。 そこで、マルチスレッディン グの知恵を借りた。 あとで、汎用性向上に役立 つことになる。
  15. Slave型外部IF 20210401 15 演算しながら、次データを 4列分の空間へ自律的受信 256bit/cycle 演算しながら、 HOSTの読み出しDMAに対し、 自律的に読み出し合流 256bit/cycle 次のUNITへ 豪華な外部メモリIFは、大 電力消費の主犯。 貧弱なメモリIFでも高性能 を出せるように頭を使う。 Slave型かつ自律アドレス フィルタにより、ブロード キャストやギャザを自然に 実現。 データ入れ替えはコンパイ ラが判断し最適化。
  16. 20210401 16 Folding機能 CPUの通常データパスに該当
  17. 20210401 17 Dual port導入 8ワードロードx4、2ワードロードx8、 2ワードロードx4⇒演算x4⇒ストアx4 を収容 メモリ空間は最大4分割 ダブルバッファとしても利用
  18. 20210401 18 伝搬レジスタ 物理4本、論理16本の UNIT間バイパスによる データ伝搬
  19. 20210401 19 アドレス同調機構 疎行列の圧縮、 圧縮済疎行列どうしの行列積、 マージソートに対応
  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
  21. 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
  22. 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
  23. 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
  24. ノイマン型に学んだ論理UNITを並べていく 20210401 24 F F A A F F A A F F M M C C M M R R R R R
  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
  30. 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
  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
  32. HOST 20210401 32 演算ネットワークとメモリネットワーク 演算器はリング構造 メモリネットワークは8並列
  33. 20210401 33 論理的プログラミングモデルは4列 ⇒ 物理構造は1列
  34. 20210401 34 非ノイマン型で重要なのは、演算器を並べることではない 書き込み後にロード or 書き込みながらロード
  35. 20210401 35 いかに、データフローを途切れなく埋め込むか ストア後に読み出す or ストアしながら読み出す
  36. 20210401 36 CGRA的パイプライン処理に加え、上位のパイプライン処理も重要 LogN個のUNITを使い、 O(N)のマージソート O(N)のFFT 結果をストアしながら、前回結果を読み出す(double buffering)
  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.
  38. 演算器とローカルメモリのサンドイッチ構造により様々な応用 More complicated memory access for light field, graph, string search, AI, … 20210401 38
  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
  41. Top-down approach 20210401 41 HBM2 HOST HOST I/O I/O FFT CONV MM SORT SpMM
  42. Multilevel pipelining 20210401 42 HBM2
  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
  48. 20210401 48 2way SIMD版 CCATが増えた ロード数が3から6に増えた
  49. Input pixels Load Sort Select center Output 4bytes 4bytes 20210401 49 メディアンフィルタを超高速実行する
  50. 20210401 50 演算だけ並べても意味がないと言ったことの意味 LM LM LM LM Main Memory PREFETCH DRAIN LM LM
  51. 20210401 51 コンパイル結果 ① ⑮ ④ ② ③ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑯ LM LM LM LM PREFETCH LM LM DRAIN
  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
  53. 20210401 53 フレーム補間
  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だけじゃない超効率計算手法
  58. 20210401 58 機械学習=トレーニング+インファレンス
  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)
  67. 20210401 67 IMAXのストカスティック積和演算
  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だけじゃない超効率計算手法
  69. 20210401 69 様々なステンシル計算
  70. 20210401 70 FD6の写像 青枠:x方向に並ぶロード 紫 :y方向に並ぶロード 赤枠:z方向に並ぶロード
  71. 20210401 71 FD6の写像 FD6
  72. 20210401 72 FD6の写像
  73. 20210401 73 ライトフィールド画像処理 Refocus All in Focus Perspective Shift
  74. 20210401 74 ライトフィールド画像処理
  75. 20210401 75 ライトフィールド画像処理 レンダリング 距離画像生成
  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だけじゃない超効率計算手法
  77. 20210401 77 逆行列は、連立一次方程式の特殊ケースで求まる 連立一次方程式 LU分解 前進消去 後退代入
  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 値と付加情報(ポインタなど)の組 疎行列とソートには、デュアルアドレス同調機能が便利
  82. 20210401 82 疎行列とソートには、デュアルアドレス同調機能が便利
  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);
  92. 20210401 92 ハッシュ計算のコンパイル結果
  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段目
  94. 20210401 94 FFTのコンパイル結果
  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 }
  97. 20210401 97 文字列検索のコンパイル結果
  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だけじゃない超効率計算手法
  112. 20210401 112 3重ループ=2重ループ+マルチIMAX HOST 演算器はリング構造 メモリネットワークは8並列
  113. 20210401 113 2重ループの制御は、ユニット1つで実行
  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
  125. 20210401 125 コンパイル結果 Load → Store ← Color map tables
  126. 20210401 126 ボードだけ買えば(50万~1650万)CGRA遊べる
  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
  128. 仕様書、ファイル一式は公開済 20210401 128