Ce diaporama a bien été signalé.
Le téléchargement de votre SlideShare est en cours. ×

PBL1-v1-011j.pptx

Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Prochain SlideShare
PBL1-v1-008j.pptx
Chargement dans…3
×

Consultez-les par la suite

1 sur 7 Publicité

PBL1-v1-011j.pptx

IMAX3: Amazing Dataflow-Centric CGRA and its Applications
I present this slide to all hungry engineers who are tired of CPU, GPU, FPGA, tensor core, AI core, who want some challenging one with no black box inside, and who want to improve by themselves.

IMAX3: Amazing Dataflow-Centric CGRA and its Applications
I present this slide to all hungry engineers who are tired of CPU, GPU, FPGA, tensor core, AI core, who want some challenging one with no black box inside, and who want to improve by themselves.

Publicité
Publicité

Plus De Contenu Connexe

Publicité

PBL1-v1-011j.pptx

1. 1. CPU GPU Ultimate CGRA w/ high-speed compiler CGRA for Energy-efficient Cryptography Beyond-Neuromorphic Systems Non-Deterministic Computing 1 ナレータ VOICEVOX:もち子(cv 明日葉よもぎ) はらぺこエンジニアに贈るCGRAの世界2022 （11.超絶技巧３重ループ編）
2. 2. 20210401 2 3重ループ＝2重ループ＋マルチアイマックス HOST 演算器はリング構造 メモリネットワークは8並列
3. 3. 20220819 3 2重ループの制御は、ユニット1つで実行
4. 4. 20220819 4 確率的積和演算の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 )
5. 5. 20220819 5 ベイズ推定に使う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);
6. 6. 20220819 6 疎行列積に使う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 )
7. 7. 20220202 7 今回のおさらい

Notes de l'éditeur

• 様々なアプリケーションを取りあげて、アイマックスのポテンシャルを説明するシリーズです。第11回は、これまでのアプリケーションに登場した、マニアックな、でも、たぶん、誰が考えてもそうなる、スーパーシスクならではの3重ループの仕掛けについて説明します。
• さて、CGRAは、バースト演算前に、命令写像とレジスタ初期化を必要とします。なるべくバースト演算を長くし、起動オーバヘッドを減らしたいところです。しかし，バースト演算の時間は、ローカルメモリに格納可能なデータ量により決まります。また、ローカルメモリ容量には、パイプライン演算器の動作周波数を落さない上限があります。経験的に、３ステージからなる、単精度、浮動小数点演算パイプラインと釣り合うローカルメモリは、64キロバイト程度です。かつてのベクトル演算機構も、ベクトルレジスタ1本あたり、最大16キロバイト程度でした。64キロバイトを、格納できるワード数で割った16キロサイクルが、バースト演算時間の上限となります。ライトフィールド画像処理では、入力が8K画像のため、1行でも、ローカルメモリを十分使い切ることができます。しかし、行列積や畳み込み演算は、列数だけをバースト演算に対応させると、とても短かくなります。そこで、列方向だけでなく、ぎょう方向にも連続してバースト演算できる仕組みが必要になります。アイマックスは、多重ループ一括実行機能により、一度の起動で３重ループを実行し、起動オーバヘッドを削減します。前に説明したように、アイマックスの外部メモリインタフェースは8並列、演算器はリング構造です。3重ループ構造のプログラムは、最外ループが、マルチチップに対応付けられます。そして、内側の2重ループが、チップ内処理に対応付けられます。
• では、2重ループを実行する様子をみていきます。うえは、畳み込み演算、冒頭部分のCコードです。左下は、プログラミングモデルである、4列構成への写像の様子です。プログラムの第2行から第5行が、4列に写像されています。第4行の、イニット0ハテナの部分は、イニット0が1の場合、つまり、さいうちループが始まる時に、colを初期値であるマイナス４に戻す記述です。C言語としては無意味に見えますが、ユニットに、変数初期化のタイミングを伝えます。この記述により、アイマックスの動作と、C言語としての動作を完全に一致させることができます。ループ0が、バースト演算に関与する最内ループカウンタです。レジスタに初期値、Mマイナス2が設定された後は、毎サイクル、自己ループによりデクリメントされ、結果が非0の場合は、隣に写像された、ループ1のデクリメントちを0に維持します。ループ0が0に到達すると、ループ0の左側ソースに、再度、Mマイナス2を設定し、ループ1の右側ソースを、マイナス1に切り替えて、ループ1をデクリメントします。さらに、colの左側ソースに再度マイナス4を設定し、rowの右側ソースをMかける4に切り替えて、rowを加算し、ループ1のイタレーションが1つ進みます。ループ0とループ1が共に0になると、バースト演算が停止します。右下の図は、列方向マルチスレッディング、適用後の、物理ユニットの動作です。全ての制御を1つのユニットが行います。
• これは、機械学習編で登場した、ストカスティック積和演算、SFMAによる行列積です。赤文字が内側の2重ループです。ループ1の回転数は、RMGRPです。付随するぎょう方向変数、rofsの初期値は、上位32ビットがマイナスIC32、下位32ビットがマイナス1です。rofsの上位32ビットは、入力配列Bのぎょう方向のオフセットアドレス、下位32ビットは、出力配列Cのオフセットアドレスに対応します。SIMD演算器を使って、一度にアドレス計算します。同じように、最内ループ0の回転数は、IC32わる32、付随する列方向変数、cofsの初期値は、上位32ビットがマイナス32、下位32ビットがゼロです。Cofsの上位32ビットは、入力配列Aの列方向のオフセットアドレスです。下位32ビットは使いません。ここまでが、1つの物理ユニットに属する、2つの論理ユニットが担当します。そして、まる1とまる2は、のこり2つの論理ユニットが担当します。まる1は、最内ループ0の先頭でcofsを初期値に戻し、それ以外は、上位32ビットに32を加算します。まる2は、最内ループ0の先頭で、rofsの上位32ビットにIC32、下位32ビットに1を加算します。そして、まる3とまる4は、次の物理ユニットが担当し、まる1とまる2の結果を加算して、bofsとoofsを求めます。この結果、bofsの上位32ビットは、配列Bの要素位置、cofsの上位32ビットは、配列Aの要素位置、oofsの下位32ビットは、結果を格納する配列Cの要素位置になります。oofsは、青字部分のロードと、紫のストアに使用されます。ベースとオフセットを入れ替えているのは、前のユニットから2つのアドレス生成器に入力できるデータパスが、2つしかない制約に合わせるためです。このように、上位32ビットと、下位32ビットをうまく組み合わせることで、論理ユニットを節約しながら、2重ループのアドレス計算を行います。ところで、緑のSFMAにも、イニット0ハテナがあります。これは、さいうちループが始まる時に、累算の初期値をメモリ内容に戻す記述です。C言語としては無意味に見えますが、ユニットに、累算初期化のタイミングを伝えます。どうです、複雑な制御を、C言語としても、CGRAとしても意味を正しく伝える。これが、超絶技巧3重ループです。
• 同じような構造が、ベイズ推定でも役に立ちます。緑のADDにも、イニット0ハテナがあります。これも、さいうちループが始まる時に、累算の初期値をメモリ内容に戻す記述です。
• そ行列積にもあります。緑のCFMAにも、イニット0ハテナがあります。
• 今回は、アイマックスの超絶技巧３重ループ編でした。なんでそうなっているのか、よくわからなかったかもしれませんが、それは、どうすれば、たくさんのSIMDユニットが同時に動くCGRAと、順番に実行されるC言語プログラムとで、同じ計算をさせられるのか、自分で考えていないからです。自分で考えると、誰が考えても、たぶん、同じ仕組みになります。では、今回はここまで。おつかれさま。