SlideShare une entreprise Scribd logo
1  sur  12
CPU GPU
Ultimate CGRA w/ high-speed compiler
CGRA for Energy-efficient Cryptography
Beyond-Neuromorphic Systems
Non-Deterministic Computing
1
ナレータ VOICEVOX:もち子(cv 明日葉よもぎ)
はらぺこエンジニアに贈るCGRAの世界2022
(3. 画像フィルタ中級編)
スパコンからIoTまで 省エネ社会に
AI+BCだけじゃない超効率計算手法
Input
pixels
Load
Sort
Select center
Output
4bytes
4bytes
20220202
2
メディアンフィルタを超高速実行する
v-sort v-sort v-sort v-sort
h-sort
h-sort
h-sort
Select max/mid/min value from three 8bits
Select max/min value from two 8bits
20220202
3
新しい3入力演算を考える
20220202
4
画素値のロード・演算・ストアを並べる
20220202
5
演算だけ並べても意味がないと言ったことの意味
LM
LM
LM
LM
Main
Memory
PREFETCH
DRAIN
LM
LM
20220202
6
プログラムに表現する
for (row=0; row<HT; row++) {
//EMAX5A begin median_filter 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, 0x00000000ffffffffLL, OP_NOP, 0);
exe(OP_ADD, &in_center, row_center, EXP_H3210, col, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 1*/ mop(OP_LDWR, &r7, in_center, -1276, MSK_D0, row_prev, WD, NULL, 0);
/* 1*/ mop(OP_LDWR, &r1, in_center, -1280, MSK_D0, row_prev, WD, NULL, 0);
/* 1*/ mop(OP_LDWR, &r5, in_center, -1284, MSK_D0, row_prev, WD, NULL, 0);
/* 4*/ exe(OP_MMIN3, &r17, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 4*/ exe(OP_MMID3, &r11, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 4*/ exe(OP_MMAX3, &r15, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 2*/ mop(OP_LDWR, &r4, in_center, 4, MSK_D0, row_center, WD, NULL, 0);
/* 2*/ mop(OP_LDWR, &r0, in_center, 0, MSK_D0, row_center, WD, NULL, 0);
/* 2*/ mop(OP_LDWR, &r3, in_center, -4, MSK_D0, row_center, WD, NULL, 0);
/* 5*/ exe(OP_MMIN3, &r14, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 5*/ exe(OP_MMID3, &r10, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 5*/ exe(OP_MMAX3, &r13, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 3*/ mop(OP_LDWR, &r8, in_center, 1284, MSK_D0, row_next, WD, row_next_next, WD);
/* 3*/ mop(OP_LDWR, &r2, in_center, 1280, MSK_D0, row_next, WD, row_next_next, WD);
/* 3*/ mop(OP_LDWR, &r6, in_center, 1276, MSK_D0, row_next, WD, row_next_next, WD);
/* 6*/ exe(OP_MMIN3, &r18, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 6*/ exe(OP_MMID3, &r12, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 6*/ exe(OP_MMAX3, &r16, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
:
/*14*/ exe(OP_MMAX, &r8, r14, EXP_H3210, r18, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/*14*/ exe(OP_MMIN, &r5, r15, EXP_H3210, r13, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/*15*/ exe(OP_MMID3, &r31, r5, EXP_H3210, r10, EXP_H3210, r8, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/*16*/ mop(OP_STWR, &r31, out_center, col, MSK_D0, out_center, WD, out_prev, WD);
}
}
//EMAX5A end
}
20220202
7
プログラムに表現する
for (row=0; row<HT; row++) {
//EMAX5A begin median_filter 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, 0x00000000ffffffffLL, OP_NOP, 0);
exe(OP_ADD, &in_center, row_center, EXP_H3210, col, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 1*/ mop(OP_LDWR, &r7, in_center, -1276, MSK_D0, row_prev, WD, NULL, 0);
/* 1*/ mop(OP_LDWR, &r1, in_center, -1280, MSK_D0, row_prev, WD, NULL, 0);
/* 1*/ mop(OP_LDWR, &r5, in_center, -1284, MSK_D0, row_prev, WD, NULL, 0);
/* 4*/ exe(OP_MMIN3, &r17, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 4*/ exe(OP_MMID3, &r11, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 4*/ exe(OP_MMAX3, &r15, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 2*/ mop(OP_LDWR, &r4, in_center, 4, MSK_D0, row_center, WD, NULL, 0);
/* 2*/ mop(OP_LDWR, &r0, in_center, 0, MSK_D0, row_center, WD, NULL, 0);
/* 2*/ mop(OP_LDWR, &r3, in_center, -4, MSK_D0, row_center, WD, NULL, 0);
/* 5*/ exe(OP_MMIN3, &r14, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 5*/ exe(OP_MMID3, &r10, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 5*/ exe(OP_MMAX3, &r13, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 3*/ mop(OP_LDWR, &r8, in_center, 1284, MSK_D0, row_next, WD, row_next_next, WD);
/* 3*/ mop(OP_LDWR, &r2, in_center, 1280, MSK_D0, row_next, WD, row_next_next, WD);
/* 3*/ mop(OP_LDWR, &r6, in_center, 1276, MSK_D0, row_next, WD, row_next_next, WD);
/* 6*/ exe(OP_MMIN3, &r18, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 6*/ exe(OP_MMID3, &r12, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 6*/ exe(OP_MMAX3, &r16, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
:
/*14*/ exe(OP_MMAX, &r8, r14, EXP_H3210, r18, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/*14*/ exe(OP_MMIN, &r5, r15, EXP_H3210, r13, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/*15*/ exe(OP_MMID3, &r31, r5, EXP_H3210, r10, EXP_H3210, r8, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/*16*/ mop(OP_STWR, &r31, out_center, col, MSK_D0, out_center, WD, out_prev, WD);
}
}
//EMAX5A end
}
20220202
8
プログラムに表現する
for (row=0; row<HT; row++) {
//EMAX5A begin median_filter 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, 0x00000000ffffffffLL, OP_NOP, 0);
exe(OP_ADD, &in_center, row_center, EXP_H3210, col, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 1*/ mop(OP_LDWR, &r7, in_center, -1276, MSK_D0, row_prev, WD, NULL, 0);
/* 1*/ mop(OP_LDWR, &r1, in_center, -1280, MSK_D0, row_prev, WD, NULL, 0);
/* 1*/ mop(OP_LDWR, &r5, in_center, -1284, MSK_D0, row_prev, WD, NULL, 0);
/* 4*/ exe(OP_MMIN3, &r17, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 4*/ exe(OP_MMID3, &r11, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 4*/ exe(OP_MMAX3, &r15, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 2*/ mop(OP_LDWR, &r4, in_center, 4, MSK_D0, row_center, WD, NULL, 0);
/* 2*/ mop(OP_LDWR, &r0, in_center, 0, MSK_D0, row_center, WD, NULL, 0);
/* 2*/ mop(OP_LDWR, &r3, in_center, -4, MSK_D0, row_center, WD, NULL, 0);
/* 5*/ exe(OP_MMIN3, &r14, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 5*/ exe(OP_MMID3, &r10, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 5*/ exe(OP_MMAX3, &r13, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 3*/ mop(OP_LDWR, &r8, in_center, 1284, MSK_D0, row_next, WD, row_next_next, WD);
/* 3*/ mop(OP_LDWR, &r2, in_center, 1280, MSK_D0, row_next, WD, row_next_next, WD);
/* 3*/ mop(OP_LDWR, &r6, in_center, 1276, MSK_D0, row_next, WD, row_next_next, WD);
/* 6*/ exe(OP_MMIN3, &r18, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 6*/ exe(OP_MMID3, &r12, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/* 6*/ exe(OP_MMAX3, &r16, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
:
/*14*/ exe(OP_MMAX, &r8, r14, EXP_H3210, r18, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/*14*/ exe(OP_MMIN, &r5, r15, EXP_H3210, r13, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/*15*/ exe(OP_MMID3, &r31, r5, EXP_H3210, r10, EXP_H3210, r8, EXP_H3210, OP_NOP, 0, OP_NOP, 0);
/*16*/ mop(OP_STWR, &r31, out_center, col, MSK_D0, out_center, WD, out_prev, WD);
}
}
//EMAX5A end
}
20220202
9
コンパイル結果
①
⑮
④
②
③
⑤
⑥
⑦
⑧
⑨
⑩
⑪
⑫
⑬
⑭
⑯
LM
LM
LM
LM
PREFETCH
LM
LM
DRAIN
20220202
10
アンシャープマスクはもっと簡単
#define r(p) ((p)>>24)
#define g(p) ((p)>>16 & 255)
#define b(p) ((p)>> 8 & 255)
for (row=0; row<HT; row++) {
for (col=0; col<WD; col++) {
pix0 = in[row][col];
pix1 = in[row-1][col];
pix2 = in[row+1][col];
pix3 = in[row ][col-1];
pix4 = in[row ][col+1];
pix5 = in[row-1][col-1];
pix6 = in[row-1][col+1];
pix7 = in[row+1][col-1];
pix8 = in[row+1][col+1];
// p0: 1.87 = +239/128
// p1234: 0.12 * 4 = -15.25/128
// p5678: 0.10 * 4 = -13/128
r0 = r(pix0); r1 = r(pix1)+r(pix2)+r(pix3)+r(pix4); r2 = r(pix5)+r(pix6)+r(pix7)+r(pix8);
g0 = g(pix0); g1 = g(pix1)+g(pix2)+g(pix3)+g(pix4); g2 = g(pix5)+g(pix6)+g(pix7)+g(pix8);
b0 = b(pix0); b1 = b(pix1)+b(pix2)+b(pix3)+b(pix4); b2 = b(pix5)+b(pix6)+b(pix7)+b(pix8);
rout = (r0 * 239 - r1 * 13 - r2 * 15 - r2/4) >> 7);
gout = (g0 * 239 - g1 * 13 - g2 * 15 - g2/4) >> 7);
bout = (b0 * 239 - b1 * 13 - b2 * 15 - b2/4) >> 7);
out[row][col] = rout<<24 | gout<<16 | bout<<8;
}
}
-0.1 -0.12 -0.1
-0.12 +1.88 -0.12
-0.1 -0.12 -0.1
20220202
11
メディアンフィルタよりも簡単なアンシャープマスク
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
20220202
12
今回のおさらい

Contenu connexe

Similaire à PBL1-v1-003j.pptx

あまぁいRcpp生活
あまぁいRcpp生活あまぁいRcpp生活
あまぁいRcpp生活Masaki Tsuda
 
お前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのかお前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのかKousuke Ebihara
 
ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。Kazuki Onishi
 
発表資料 Fortranを用いた高位合成技術FortRockの開発
発表資料 Fortranを用いた高位合成技術FortRockの開発発表資料 Fortranを用いた高位合成技術FortRockの開発
発表資料 Fortranを用いた高位合成技術FortRockの開発貴大 山下
 
LibreOffice 4 under NetBSD with pkgsrc
LibreOffice 4 under NetBSD with pkgsrcLibreOffice 4 under NetBSD with pkgsrc
LibreOffice 4 under NetBSD with pkgsrcRyo ONODERA
 
仮想記憶入門 BSD-4.3を例題に
仮想記憶入門 BSD-4.3を例題に仮想記憶入門 BSD-4.3を例題に
仮想記憶入門 BSD-4.3を例題にmagoroku Yamamoto
 
PBL1-v1-009j.pptx
PBL1-v1-009j.pptxPBL1-v1-009j.pptx
PBL1-v1-009j.pptxNAIST
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたMITSUNARI Shigeo
 
V6でJIT・部分適用・継続
V6でJIT・部分適用・継続V6でJIT・部分適用・継続
V6でJIT・部分適用・継続7shi
 
HaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミングHaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミングKiwamu Okabe
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)Takeshi Yamamuro
 
Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Fixstars Corporation
 
C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competitionyak1ex
 

Similaire à PBL1-v1-003j.pptx (20)

What is Metasepi?
What is Metasepi?What is Metasepi?
What is Metasepi?
 
Slide
SlideSlide
Slide
 
あまぁいRcpp生活
あまぁいRcpp生活あまぁいRcpp生活
あまぁいRcpp生活
 
お前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのかお前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのか
 
ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。
 
発表資料 Fortranを用いた高位合成技術FortRockの開発
発表資料 Fortranを用いた高位合成技術FortRockの開発発表資料 Fortranを用いた高位合成技術FortRockの開発
発表資料 Fortranを用いた高位合成技術FortRockの開発
 
LibreOffice 4 under NetBSD with pkgsrc
LibreOffice 4 under NetBSD with pkgsrcLibreOffice 4 under NetBSD with pkgsrc
LibreOffice 4 under NetBSD with pkgsrc
 
HPC Phys-20201203
HPC Phys-20201203HPC Phys-20201203
HPC Phys-20201203
 
仮想記憶入門 BSD-4.3を例題に
仮想記憶入門 BSD-4.3を例題に仮想記憶入門 BSD-4.3を例題に
仮想記憶入門 BSD-4.3を例題に
 
PBL1-v1-009j.pptx
PBL1-v1-009j.pptxPBL1-v1-009j.pptx
PBL1-v1-009j.pptx
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみた
 
Rを用いたGIS
Rを用いたGISRを用いたGIS
Rを用いたGIS
 
V6でJIT・部分適用・継続
V6でJIT・部分適用・継続V6でJIT・部分適用・継続
V6でJIT・部分適用・継続
 
HaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミングHaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミング
 
about dakota6.7 gui
about dakota6.7 guiabout dakota6.7 gui
about dakota6.7 gui
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
 
LLVM最適化のこつ
LLVM最適化のこつLLVM最適化のこつ
LLVM最適化のこつ
 
Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門
 
C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
 
Rの高速化
Rの高速化Rの高速化
Rの高速化
 

Plus de NAIST

PBL1-v1-200j.pptx
PBL1-v1-200j.pptxPBL1-v1-200j.pptx
PBL1-v1-200j.pptxNAIST
 
PBL1-v1-200e.pptx
PBL1-v1-200e.pptxPBL1-v1-200e.pptx
PBL1-v1-200e.pptxNAIST
 
PBL1-v1-100j.pptx
PBL1-v1-100j.pptxPBL1-v1-100j.pptx
PBL1-v1-100j.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-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-002j.pptx
PBL1-v1-002j.pptxPBL1-v1-002j.pptx
PBL1-v1-002j.pptxNAIST
 
PBL1-v1-001j.pptx
PBL1-v1-001j.pptxPBL1-v1-001j.pptx
PBL1-v1-001j.pptxNAIST
 
PBL1-v0-200j.pptx
PBL1-v0-200j.pptxPBL1-v0-200j.pptx
PBL1-v0-200j.pptxNAIST
 

Plus de NAIST (16)

PBL1-v1-200j.pptx
PBL1-v1-200j.pptxPBL1-v1-200j.pptx
PBL1-v1-200j.pptx
 
PBL1-v1-200e.pptx
PBL1-v1-200e.pptxPBL1-v1-200e.pptx
PBL1-v1-200e.pptx
 
PBL1-v1-100j.pptx
PBL1-v1-100j.pptxPBL1-v1-100j.pptx
PBL1-v1-100j.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-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-002j.pptx
PBL1-v1-002j.pptxPBL1-v1-002j.pptx
PBL1-v1-002j.pptx
 
PBL1-v1-001j.pptx
PBL1-v1-001j.pptxPBL1-v1-001j.pptx
PBL1-v1-001j.pptx
 
PBL1-v0-200j.pptx
PBL1-v0-200j.pptxPBL1-v0-200j.pptx
PBL1-v0-200j.pptx
 

PBL1-v1-003j.pptx

  • 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 (3. 画像フィルタ中級編) スパコンからIoTまで 省エネ社会に AI+BCだけじゃない超効率計算手法
  • 3. v-sort v-sort v-sort v-sort h-sort h-sort h-sort Select max/mid/min value from three 8bits Select max/min value from two 8bits 20220202 3 新しい3入力演算を考える
  • 6. 20220202 6 プログラムに表現する for (row=0; row<HT; row++) { //EMAX5A begin median_filter 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, 0x00000000ffffffffLL, OP_NOP, 0); exe(OP_ADD, &in_center, row_center, EXP_H3210, col, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 1*/ mop(OP_LDWR, &r7, in_center, -1276, MSK_D0, row_prev, WD, NULL, 0); /* 1*/ mop(OP_LDWR, &r1, in_center, -1280, MSK_D0, row_prev, WD, NULL, 0); /* 1*/ mop(OP_LDWR, &r5, in_center, -1284, MSK_D0, row_prev, WD, NULL, 0); /* 4*/ exe(OP_MMIN3, &r17, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 4*/ exe(OP_MMID3, &r11, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 4*/ exe(OP_MMAX3, &r15, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 2*/ mop(OP_LDWR, &r4, in_center, 4, MSK_D0, row_center, WD, NULL, 0); /* 2*/ mop(OP_LDWR, &r0, in_center, 0, MSK_D0, row_center, WD, NULL, 0); /* 2*/ mop(OP_LDWR, &r3, in_center, -4, MSK_D0, row_center, WD, NULL, 0); /* 5*/ exe(OP_MMIN3, &r14, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 5*/ exe(OP_MMID3, &r10, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 5*/ exe(OP_MMAX3, &r13, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 3*/ mop(OP_LDWR, &r8, in_center, 1284, MSK_D0, row_next, WD, row_next_next, WD); /* 3*/ mop(OP_LDWR, &r2, in_center, 1280, MSK_D0, row_next, WD, row_next_next, WD); /* 3*/ mop(OP_LDWR, &r6, in_center, 1276, MSK_D0, row_next, WD, row_next_next, WD); /* 6*/ exe(OP_MMIN3, &r18, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 6*/ exe(OP_MMID3, &r12, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 6*/ exe(OP_MMAX3, &r16, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0); : /*14*/ exe(OP_MMAX, &r8, r14, EXP_H3210, r18, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /*14*/ exe(OP_MMIN, &r5, r15, EXP_H3210, r13, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /*15*/ exe(OP_MMID3, &r31, r5, EXP_H3210, r10, EXP_H3210, r8, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /*16*/ mop(OP_STWR, &r31, out_center, col, MSK_D0, out_center, WD, out_prev, WD); } } //EMAX5A end }
  • 7. 20220202 7 プログラムに表現する for (row=0; row<HT; row++) { //EMAX5A begin median_filter 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, 0x00000000ffffffffLL, OP_NOP, 0); exe(OP_ADD, &in_center, row_center, EXP_H3210, col, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 1*/ mop(OP_LDWR, &r7, in_center, -1276, MSK_D0, row_prev, WD, NULL, 0); /* 1*/ mop(OP_LDWR, &r1, in_center, -1280, MSK_D0, row_prev, WD, NULL, 0); /* 1*/ mop(OP_LDWR, &r5, in_center, -1284, MSK_D0, row_prev, WD, NULL, 0); /* 4*/ exe(OP_MMIN3, &r17, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 4*/ exe(OP_MMID3, &r11, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 4*/ exe(OP_MMAX3, &r15, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 2*/ mop(OP_LDWR, &r4, in_center, 4, MSK_D0, row_center, WD, NULL, 0); /* 2*/ mop(OP_LDWR, &r0, in_center, 0, MSK_D0, row_center, WD, NULL, 0); /* 2*/ mop(OP_LDWR, &r3, in_center, -4, MSK_D0, row_center, WD, NULL, 0); /* 5*/ exe(OP_MMIN3, &r14, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 5*/ exe(OP_MMID3, &r10, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 5*/ exe(OP_MMAX3, &r13, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 3*/ mop(OP_LDWR, &r8, in_center, 1284, MSK_D0, row_next, WD, row_next_next, WD); /* 3*/ mop(OP_LDWR, &r2, in_center, 1280, MSK_D0, row_next, WD, row_next_next, WD); /* 3*/ mop(OP_LDWR, &r6, in_center, 1276, MSK_D0, row_next, WD, row_next_next, WD); /* 6*/ exe(OP_MMIN3, &r18, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 6*/ exe(OP_MMID3, &r12, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 6*/ exe(OP_MMAX3, &r16, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0); : /*14*/ exe(OP_MMAX, &r8, r14, EXP_H3210, r18, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /*14*/ exe(OP_MMIN, &r5, r15, EXP_H3210, r13, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /*15*/ exe(OP_MMID3, &r31, r5, EXP_H3210, r10, EXP_H3210, r8, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /*16*/ mop(OP_STWR, &r31, out_center, col, MSK_D0, out_center, WD, out_prev, WD); } } //EMAX5A end }
  • 8. 20220202 8 プログラムに表現する for (row=0; row<HT; row++) { //EMAX5A begin median_filter 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, 0x00000000ffffffffLL, OP_NOP, 0); exe(OP_ADD, &in_center, row_center, EXP_H3210, col, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 1*/ mop(OP_LDWR, &r7, in_center, -1276, MSK_D0, row_prev, WD, NULL, 0); /* 1*/ mop(OP_LDWR, &r1, in_center, -1280, MSK_D0, row_prev, WD, NULL, 0); /* 1*/ mop(OP_LDWR, &r5, in_center, -1284, MSK_D0, row_prev, WD, NULL, 0); /* 4*/ exe(OP_MMIN3, &r17, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 4*/ exe(OP_MMID3, &r11, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 4*/ exe(OP_MMAX3, &r15, r7, EXP_H3210, r1, EXP_H3210, r5, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 2*/ mop(OP_LDWR, &r4, in_center, 4, MSK_D0, row_center, WD, NULL, 0); /* 2*/ mop(OP_LDWR, &r0, in_center, 0, MSK_D0, row_center, WD, NULL, 0); /* 2*/ mop(OP_LDWR, &r3, in_center, -4, MSK_D0, row_center, WD, NULL, 0); /* 5*/ exe(OP_MMIN3, &r14, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 5*/ exe(OP_MMID3, &r10, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 5*/ exe(OP_MMAX3, &r13, r4, EXP_H3210, r0, EXP_H3210, r3, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 3*/ mop(OP_LDWR, &r8, in_center, 1284, MSK_D0, row_next, WD, row_next_next, WD); /* 3*/ mop(OP_LDWR, &r2, in_center, 1280, MSK_D0, row_next, WD, row_next_next, WD); /* 3*/ mop(OP_LDWR, &r6, in_center, 1276, MSK_D0, row_next, WD, row_next_next, WD); /* 6*/ exe(OP_MMIN3, &r18, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 6*/ exe(OP_MMID3, &r12, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* 6*/ exe(OP_MMAX3, &r16, r8, EXP_H3210, r2, EXP_H3210, r6, EXP_H3210, OP_NOP, 0, OP_NOP, 0); : /*14*/ exe(OP_MMAX, &r8, r14, EXP_H3210, r18, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /*14*/ exe(OP_MMIN, &r5, r15, EXP_H3210, r13, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /*15*/ exe(OP_MMID3, &r31, r5, EXP_H3210, r10, EXP_H3210, r8, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /*16*/ mop(OP_STWR, &r31, out_center, col, MSK_D0, out_center, WD, out_prev, WD); } } //EMAX5A end }
  • 10. 20220202 10 アンシャープマスクはもっと簡単 #define r(p) ((p)>>24) #define g(p) ((p)>>16 & 255) #define b(p) ((p)>> 8 & 255) for (row=0; row<HT; row++) { for (col=0; col<WD; col++) { pix0 = in[row][col]; pix1 = in[row-1][col]; pix2 = in[row+1][col]; pix3 = in[row ][col-1]; pix4 = in[row ][col+1]; pix5 = in[row-1][col-1]; pix6 = in[row-1][col+1]; pix7 = in[row+1][col-1]; pix8 = in[row+1][col+1]; // p0: 1.87 = +239/128 // p1234: 0.12 * 4 = -15.25/128 // p5678: 0.10 * 4 = -13/128 r0 = r(pix0); r1 = r(pix1)+r(pix2)+r(pix3)+r(pix4); r2 = r(pix5)+r(pix6)+r(pix7)+r(pix8); g0 = g(pix0); g1 = g(pix1)+g(pix2)+g(pix3)+g(pix4); g2 = g(pix5)+g(pix6)+g(pix7)+g(pix8); b0 = b(pix0); b1 = b(pix1)+b(pix2)+b(pix3)+b(pix4); b2 = b(pix5)+b(pix6)+b(pix7)+b(pix8); rout = (r0 * 239 - r1 * 13 - r2 * 15 - r2/4) >> 7); gout = (g0 * 239 - g1 * 13 - g2 * 15 - g2/4) >> 7); bout = (b0 * 239 - b1 * 13 - b2 * 15 - b2/4) >> 7); out[row][col] = rout<<24 | gout<<16 | bout<<8; } } -0.1 -0.12 -0.1 -0.12 +1.88 -0.12 -0.1 -0.12 -0.1
  • 11. 20220202 11 メディアンフィルタよりも簡単なアンシャープマスク 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

Notes de l'éditeur

  1. 様々なアプリケーションを取りあげて、アイマックスのポテンシャルを説明するシリーズです。第3回は、メディアンフィルタからはじめる、画像ステンシル計算です。
  2. まず、メディアンフィルタと呼ぶ画像処理をとりあげます。写真のうえが元画像、下が処理結果です。メディアンフィルタは、3かける3領域の色成分、RGBを明るさ順に並べて、中央のあたいを計算結果とすることで、輪郭をぼかすことなく、色だけをぼかすことができる便利な画像フィルタです。例えば、輪郭抽出の前処理に使います。ただし、明るさ順に並べ替える作業が必要なので、かなりの計算量が必要です。したのプログラムはC言語で書いてあります。3かける3領域から9個の画素値を取り出します。そして、各々8ビットのRGB成分ごとに比較をして、並べ替えていきます。ここではバブルソートを使っています。隣どうしを比べて、逆順なら入れ換えることを繰り返すだけです。クイックソートのように、より高速なアルゴリズムもありますが、要素数が9しかないし、まん中のあたいが求まった時点で、残りを打ち切るので、これで十分です。6行目と7行目に2重ループがありますね。ループの中の比較と入れ換え処理が、8、9、10行目です。この3行が、合計8+7+6+5+4の合計30回繰り返されます。これでようやく1つの出力画素が求まります。でも、これをアイマックスに実装すると、なんと、毎サイクル、複数の出力画素が求まります。単なるアンシャープマスクなら、90パーセントのエンジニアが1秒で思いつくでしょうけどね。ソートが必要なメディアンフィルタを同速で実現できるのは、0.01パーセントのエンジニアだけです。
  3. 前の例では、2重ループを使って並べ替えました。しかし、CGRAを使うには、ループを使わないソート方法を考えて、単純なパイプライン処理に変形しなければなりません。そこで、8ビット単位に大小比較して、指定した順番のあたいを出力する、5つの基本操作を新たに作ります。マックス3ABCは,3つの画素値、各々4バイトを入力とし、3つの赤成分、各8ビットから最大値、3つの緑成分から同じく最大値、3つの青成分から同じく最大値を出力します。同様に、ミッド3ABCはちゅうかんち、ミン3ABCは最小値を出力します。マックス2ABCと、ミン2ABCは、2つの画素値を入力とし、Cは無視します。これらを使うと、2重ループを使わずにすみます。このプログラムでは、3行目で、9個の画素値をr0からr8に取り出しています。4、5、6行目が図、aに対応しています。まず、縦に3画素ずつまとめます。r5とr1とr7をマックス3、ミッド3、ミン3に与えると、最大値、ちゅうかんち、最小値が計算できます。これを改めてr5とr1とr7に代入すると、3つの画素の並べ替えが完了です。同様に、r3とr0とr4も並べ替えます。さらに、r6とr2とr8を並べ替えます。これで、9個の画素値を図、aの関係に並べ替えることができました。次は、横に3画素ずつまとめます。r5とr3とr6をマックス3、ミッド3、ミン3に与えて並べ替えます。同様に、r1とr0とr2、r7とr4とr8を並べ替えます。結果、図、bの関係に並べ替えができました。さて、この時点で何がわかるでしょうか。aの時点で、上の3つの画素値は、各グループで最大です。そして、下の3つの画素値は、各グループで最小です。bでは、3つの最大値の中の最大値、つまり全体の中での最大値が右上すみに移動します。同様に、3つの最小値の中の最小値、つまり全体の中での最小値が左下すみに移動します。最後に欲しいのは、全体の中の中間値なので、右上すみと左下すみのあたいは捨てることができます。以上を繰り返すと、最大値と最小値が順に捨てられて、最後のgに到達します。画素値が3つだけ残っているので、18行目でミッド3を実行して、ちゅうかんちr0を取り出します。この方法を考えたのが2008年、教科書にしたのが2012年です。
  4. この図は、さっきのプログラムを機械語命令に書き換えて並べたものです。マックス、ミッド、ミンは、3入力演算器を使って1命令で実行できます。aからgは、前の図の各状態に対応しています。ループ構造がなくなって、データがうえから下に流れるように、機械語命令が並んでいます。この機械語命令列は、横1列を1つのVLIWにまとめることができます。ということは、1つの出力画素が、わずか16命令で求まることになります。そして、CGRAの場合、全ての機械語命令を、2次元構造に配置された多数のALUに一度にセットできます。うえから水のようにデータを流し込むと、下から、途切れなく出力画素が生成されます。つまり、VLIWの16倍速になりました。さらに、複数組をCGRAにセットすれば、毎サイクル、複数の出力画素が求まります。ほら、アイマックスを使えば、簡単にできそうです。
  5. 簡単と言いましたが、ここまでは、誰でも思いつくレベルです。アイマックスの特長は、さらに、演算と、外部メモリからのデータ供給と、結果の追い出しをパイプライン処理できる点にあります。1から3行目のロード命令には、画像の各行に対応する入力データをそれぞれ格納する、ローカルメモリを連結します。そして、次の4行目に、次データ供給のためのDMA機能を連結します。16行目のストア命令には、演算結果を格納するローカルメモリを連結し、前の15行目に、データ書き戻しのためのDMA機能を連結します。これで、主記憶を含めたパイプラインの完成です。
  6. 方針が決まったら、プログラムを書いていきます。主記憶を含めたパイプライン動作を、簡単にプログラムに表現できる点が、アイマックスのすごいところです。ほとんどのエンジニアには、ただの呪文にしかみえないでしょうけどね。実際には、シスクよりも高機能な機械語命令が並んでいるだけで、普通のレベルです。慣れた言語で適当に書いて、1時間のコンパイル時間を何度も無駄にするか、頭を使って、ターンアラウンドタイムを10秒にするか、まあ、個人のレベルに応じて選ぶだけの話です。無理な人は、頑張る必要はありません。0.01パーセントが対象というのは、そういうことです。 さて、exe関数ひとつが、論理ユニットの、5入力、3段パイプライン演算器に対応します。第1ステージには、メディア演算を含む3入力算術演算、第2ステージには1入力を加えた論理演算、第3ステージには1入力を加えたシフト演算があり、合計5入力の演算ができます。また、第1ステージの3入力は、64ビットレジスタのどの部分を使うかを指定できます。H3210は、4つの16ビットをそのまま使うことを意味します。64ビット全部使うという、普通の指定です。青文字の部分は、論理演算やシフト演算の場所ですが、今は使わないので、ノップが並んでいます。
  7. では、本題です。ここで注目すべきは、演算ではなく、赤文字の部分です。まず、2行目を見てください。今まで、おまじないのように、マップディスト0と書いてありましたが、このプログラムでは、マップディスト1と書いてあります。これは、アイマックスの一連の実行が終わったら、ローカルメモリは触らずに、機能の写像位置を1段進めることを意味します。どういうことでしょうか。以前に、効率を上げるには、ローカルメモリの内容を極力再利用して、外部メモリを使わないのが良いと言いました。3かける3といった固定枠をずらしながら計算を進める、ステンシル計算と呼ぶ計算方法では、1行分の処理が終わったら、注目位置を下に1ぎょうずらせて、同じことを繰り返します。つまり、さっき使った、2行目と3行目のデータは、次の実行では、新たな1行目と2行目のデータとして再利用することができ、まだない3行目を、外部メモリから、次のローカルメモリに継ぎ足せばよいことになります。アイマックスには、機能の写像位置のみをずらす機能があって、これを使う場合に、マップディストに0以外のあたいを指定します。 前に、Mop関数が、高機能ロードストアに該当すると説明しました。先頭から順に、オペコード、読み書きレジスタ、ベースアドレス、オフセット、オフセットマスク、そして、使う主記憶領域の先頭アドレスとワード数でした。ロード関数を見ると、先頭アドレスに、ロウプレブ、ロウセンター、ロウネクストと書いてあります。それぞれ、注目している3かける3領域の、うえ、中央、したのぎょうの先頭です。そして、行頭に番号3がついた3つのロード関数では、さらに、ロウネクストネクストというアドレスが追加されています。 現在の実行に必要な1行目のデータは、ロウプレブ、2行目のデータは、ロウセンター、3行目のデータは、ロウネクストです。そして、未来の3行目に該当する4行目のデータが、ロウネクストネクストです。もう、わかりましたね。3行分のデータがローカルメモリに揃っている状態で、計算を開始し、同時に、4行目のデータを外部メモリから供給します。計算が終わって、機能の写像位置をしたにずらすと、2行目から4行目には、次の計算に必要なデータが、すでに揃っている状態になります。必要なデータ領域を指定する。そして、コンパイラが考えて、DMAをスケジューリングする。ここが、アイマックスコンパイラの肝です。
  8. ストアについても同様です。行頭に番号16がついたストア関数が、演算結果をローカルメモリに格納します。そして、次の計算のために機能の写像位置が下にずれると、演算結果は、1つうえのローカルメモリにずれて見えます。これを、次の計算と同時に主記憶に追い出すことで、全体のパイプライン処理を行います。ストア関数では、アウトプレブという、1つ前のストア先領域を指定しておくことで、コンパイラが適切なDMAを生成します。 ところで、もし、プログラマが、ロウネクストネクストや、アウトプレブのアドレスを間違えていたら、何が起こるでしょう。アイマックスは、何が指定されていても、現在の各ローカルメモリの担当範囲を覚えていて、どのみち、計算開始前に、DMAが必要かどうかをチェックします。間違えていても、DMAが余計に起動されるだけで、結果がおかしくなることはありません。また、実行後、ロード、演算、ストアの実行時間内訳を表示できるので、思ったほど速くならない場合は、どこが遅いのかを確認できます。キャッシュメモリがないので、全体の実行時間は、簡単に予測でき、チューニングがうまくできていれば、予測通りの性能が出ます。データフローの設計が正しければ、チューニングに終わりが見えないといったことは、原理的にありえません。
  9. これが、コンパイル結果です。ひとくみの計算に、14ユニットを使うので、64ユニット構成のアイマックスには、4組を写像できます。つまり、毎サイクル4つの出力が得られます。数字は、VLIW命令の番号と同じです。まる1とまる2とまる3に、画像の各ぎょうが格納されていて、計算結果が、まる16のローカルメモリに入ります。演算しながら、プリフェッチとドレインが動作します。演算器も、外部メモリバスも、フル稼働している状態です。
  10. 次は、アンシャープマスクです。アンシャープマスクは、色の境界をくっきりさせる効果があります。メディアンフィルタの高速化方法を理解したら、アンシャープマスクは、おもちゃに見えることでしょう。同じように、C言語から始めます。二重ループがあって、中に、3かける3画素に対する計算がかいてあります。中心画素には、1.88を掛けて、上下左右には、マイナス0.12を掛けて、斜め四隅には、マイナス0.1を掛けて、全部を合計するだけです。単純ですが、RGBの各成分ごとに計算するので、計算量はそれなりにあります。もちろん、まじめに浮動小数点演算をする必要はなくて、整数演算に置き換えることができます。
  11. ロード、演算、ストアの流れや、プリフェッチ、ドレインの指定は、メディアンフィルタと全く同じです。MAUHは、64ビットレジスタに対して16ビット加算を4つ、MLUHは、64ビットレジスタに対して11ビット乗算を4つという具合に、メディア演算を使っている点が異なるだけです。様々な整数演算の種類については、アイマックスの仕様書を見てください。また、エッジ検出も同じように書くことができます。似たようなプログラムなので、そろそろ飽きてきたことと思います。具体的に知りたい人は、アイマックス仕様書のサンプルプログラムを見てください。
  12. 今回は、マップディストを使って、機能の写像位置をずらすことで、ローカルメモリを再利用する考え方、そして、外部メモリも含めたパイプライン処理、また、アイマックスコンパイラのDMA機能について説明しました。では、今回はここまでです。おつかれさま。