Anúncio
Anúncio

### PBL1-v1-009j.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 （9. ハッシュ計算とFFTと文字列検索編） スパコンからIoTまで 省エネ社会に AI+BCだけじゃない超効率計算手法
2. 20220202 2 ハッシュ計算には、面倒な演算が必要 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]; } }
3. 20220202 3 ハッシュ計算には、面倒な演算が必要 case OP_MAJ: /* (((x) & (y))^((x) & (z))^((y) & (z))) */ ex1_outd = (r1&0xffffffff00000000LL) | (((r1 & r2)^(r1 & r3)^(r2 & r3))&0xffffffffLL); break; case OP_CH: /* (((x) & (y))^(~(x) & (z))) */ ex1_outd = (r1&0xffffffff00000000LL) | (((r1 & r2)^(~r1 & r3))&0xffffffffLL); break; 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); break;
4. 20220202 4 ハッシュ計算には、面倒な演算が必要 for (i=0; i<ctx->mbuflen; i+=BLKSIZE) { /* 1データ流内の並列実行は不可能. 多数データ流のパイプライン実行のみ */ mtop = &mbuf[i/BLKSIZE*MAX_THNUM*BLKSIZE]; for (th=0; th<thnum; th++) { *(Ull*)&sregs[th*8+0] = (Ull)state[th*8+4]<<32|state[th*8+0]; *(Ull*)&sregs[th*8+2] = (Ull)state[th*8+5]<<32|state[th*8+1]; *(Ull*)&sregs[th*8+4] = (Ull)state[th*8+6]<<32|state[th*8+2]; *(Ull*)&sregs[th*8+6] = (Ull)state[th*8+7]<<32|state[th*8+3]; } #define sha256_core1(r, ofs) ¥ exe(OP_NOP, &AR[r][0], 0, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);¥ mop(OP_LDWR, 3, &md, mbase, ofs, MSK_D0, mtop, mlen, 0, 0, mptop, mlen); ¥ exe(OP_MAJ, &ep0maj, a, EXP_H1010, fb, EXP_H1010, gc, EXP_H1010, OP_ROTS, (2LL<<48)|(13LL<<40)|(22LL<<32), OP_NOP, 0);¥ exe(OP_NOP, &AR[r][2], 0, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);¥ mop(OP_LDWR, 3, &kd, kbase, ofs, MSK_D0, ktop, 64, 0, 0, NULL, 64); ¥ exe(OP_CH, &ep1ch, e, EXP_H3232, fb, EXP_H3232, gc, EXP_H3232, OP_ROTS, (6LL<<48)|(11LL<<40)|(25LL<<32), OP_NOP, 0);¥ exe(OP_NOP, &d0, hd, EXP_H1010, 0, EXP_H3210, 0, EXP_H3210, OP_AND, 0xffffffff00000000LL, OP_NOP, 0);¥ exe(OP_ADD, &t2, ep0maj, EXP_H3232, ep0maj, EXP_H1010, 0, EXP_H3210, OP_AND, 0x00000000ffffffffLL, OP_NOP, 0);¥ exe(OP_ADD, &y, kd, EXP_H3210, md, EXP_H3210, 0, EXP_H3210, OP_AND, 0x00000000ffffffffLL, OP_NOP, 0);¥ exe(OP_ADD3, &x, hd, EXP_H3232, ep1ch, EXP_H3232, ep1ch, EXP_H1010, OP_AND, 0x00000000ffffffffLL, OP_NOP, 0);¥ exe(OP_NOP, &hd, gc, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_OR, 0, OP_NOP, 0);¥ exe(OP_NOP, &gc, fb, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_OR, 0, OP_NOP, 0);¥ exe(OP_NOP, &fb, e, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_OR, a, OP_NOP, 0);¥ exe(OP_ADD3, &a, t2, EXP_H3210, x, EXP_H1010, y, EXP_H1010, OP_AND, 0x00000000ffffffffLL, OP_NOP, 0);¥ exe(OP_ADD3, &e, d0, EXP_H3210, x, EXP_H1010, y, EXP_H1010, OP_AND, 0xffffffff00000000LL, OP_NOP, 0) #define sha256_final(r) ¥ exe(OP_NOP, &ea, e, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_OR, a, OP_NOP, 0);¥ mop(OP_STR, 3, &ea, sregs0, th, MSK_W0, sregs, MAX_THNUM*8, 0, 0, NULL, MAX_THNUM*8); ¥ exe(OP_NOP, &AR[r][1], 0, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);¥ mop(OP_STR, 3, &fb, sregs2, th, MSK_W0, sregs, MAX_THNUM*8, 0, 0, NULL, MAX_THNUM*8); ¥ exe(OP_NOP, &AR[r][2], 0, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);¥ mop(OP_STR, 3, &gc, sregs4, th, MSK_W0, sregs, MAX_THNUM*8, 0, 0, NULL, MAX_THNUM*8); ¥ exe(OP_NOP, &AR[r][3], 0, EXP_H3210, 0, EXP_H3210, 0, EXP_H3210, OP_NOP, 0, OP_NOP, 0);¥ mop(OP_STR, 3, &hd, sregs6, th, MSK_W0, sregs, MAX_THNUM*8, 0, 0, NULL, MAX_THNUM*8) for (INIT1=1,LOOP1=DIV,j=0; LOOP1--; INIT1=0,j+=BLKSIZE/DIV*4) { mptop = (LOOP1==0)? mtop+MAX_THNUM*BLKSIZE*4:mtop; /* 最終回のみPLOAD */ //printf("--%08.8x %08.8x %08.8x %08.8x %08.8x %08.8x %08.8x %08.8x¥n", sregs[0*8+0], sregs[0*8+2], sregs[0*8+4], sregs[0*8+6], sregs[0*8+1], sregs[0*8+3], sregs[0*8+5], sregs[0*8+7]); //with-prefetch //EMAX5A begin imax mapdist=0 for (CHIP=0; CHIP<NCHIP; CHIP++) { for (INIT0=1,LOOP0=thnum,th=(0-BLKSIZE*4)<<32|((0-32LL)&0xffffffff); LOOP0--; INIT0=0) { exe(OP_ADD, &th, INIT0?th:th, EXP_H3210, (BLKSIZE*4)<<32|32LL, EXP_H3210, 0, EXP_H3210, OP_AND, 0xffffffffffffffffLL, OP_NOP, 0); /* stage#0 */ exe(OP_NOP, &thm, th, EXP_H3232, 0, EXP_H3210, 0, EXP_H3210, OP_AND, 0x00000000ffffffffLL, OP_NOP, 0); /* stage#1 */ exe(OP_ADD3, &mbase, mtop, EXP_H3210, thm, EXP_H3210, j, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* stage#2 */ mop(OP_LDR, 3, &a, sregs0, th, MSK_W0, sregs, MAX_THNUM*8, 0, 1, NULL, MAX_THNUM*8); /* stage#2 */ mop(OP_LDR, 3, &e, sregs0, th, MSK_W0, sregs, MAX_THNUM*8, 0, 1, NULL, MAX_THNUM*8); /* stage#2 */ exe(OP_ADD3, &kbase, imax_k, EXP_H3210, 0, EXP_H3210, j, EXP_H3210, OP_NOP, 0, OP_NOP, 0); /* stage#2 */ mop(OP_LDR, 3, &fb, sregs2, th, MSK_W0, sregs, MAX_THNUM*8, 0, 1, NULL, MAX_THNUM*8); /* stage#2 */ mop(OP_LDR, 3, &gc, sregs4, th, MSK_W0, sregs, MAX_THNUM*8, 0, 1, NULL, MAX_THNUM*8); /* stage#2 */ mop(OP_LDR, 3, &hd, sregs6, th, MSK_W0, sregs, MAX_THNUM*8, 0, 1, NULL, MAX_THNUM*8); /* stage#2 */ #if (DIV==4) sha256_core1( 3, 0); sha256_core1( 6, 4); sha256_core1( 9, 8); sha256_core1(12, 12); sha256_core1(15, 16); sha256_core1(18, 20); sha256_core1(21, 24); sha256_core1(24, 28); sha256_core1(27, 32); sha256_core1(30, 36); sha256_core1(33, 40); sha256_core1(36, 44); sha256_core1(39, 48); sha256_core1(42, 52); sha256_core1(45, 56); sha256_core1(48, 60); sha256_final(51); #endif } } //EMAX5A end } //EMAX5A drain_dirty_lmm for (th=0; th<thnum; th++) { state[th*8+0] += sregs[th*8+0]; state[th*8+1] += sregs[th*8+2]; state[th*8+2] += sregs[th*8+4]; state[th*8+3] += sregs[th*8+6]; state[th*8+4] += sregs[th*8+1]; state[th*8+5] += sregs[th*8+3]; state[th*8+6] += sregs[th*8+5]; state[th*8+7] += sregs[th*8+7]; } }
5. 20220202 5 ハッシュ計算のコンパイル結果
6. 20220202 6 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段目
8. 20220202 8 FFTのコンパイル結果
9. 20220202 9 文字列検索 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++; } } } orig() { // "search"右端と同じ文字がbufpの右端にあれば手前から全体を比較 // たとえば右端が"r"なら，bufpを2進めてよい "rrrcharch" // ^-x // "rrrch" // xここからあるかも // たとえば右端が"s"なら，bufpを5進めてよい "aaaaaaasearch" // ^----x // xここからあるかも int i; for (i=0; i<snum; i++) { init_search(i); strsearch(i); } return 0; }
10. 20220202 10 文字列検索 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 }
11. 20220202 11 文字列検索のコンパイル結果
12. 20220202 12 今回のおさらい

### Notas do Editor

1. 様々なアプリケーションを取りあげて、アイマックスのポテンシャルを説明するシリーズです。第9回は、ハッシュ計算と、FFTと、文字列検索です。
2. ハッシュ計算には、ローテートや排他論理和がたくさん使われます。これは、SHA256です。個々の演算は簡単ですが、とにかく、演算の数がとても多いです。右うえの図は、ハッシュ計算専用ハードウェアです。専用ハードウェアなら、電力効率を最大化できます。でも、半導体を作るコストが、とても高くなっているので、開発費を回収するためには、少し違った用途にも使える必要があります。ある程度、プログラムで機能を変更できる必要があるということです。この点、CGRAは、CPUと専用ハードウェアの中間にあります。
3. さっきのプログラムが使っていた、MAJ、CH、EP0の実体は、この計算です。ローテートと、排他論理和の、かたまりであることがわかります。そもそも、ハッシュ計算というのは、なるべく元のデータの情報量を減らさずに、原型をとどめなくなるまで、ミキサーにかける作業です。だから、情報量がなるべく減らない、ローテートと、排他論理和をたくさん使います。
4. 普通のCPUでは、ローテートに1命令、論理演算に1命令を使うので、とても時間がかかります。一方、アイマックスは、ハッシュ計算を高密度に実行するために、5入力演算器の初段に、MAJとCH、2段目に、ROTSハードウェアを持っています。赤字部分が、MAJとROTS、CHとROTSを組み合わせている記述です。最初のCプログラムの赤字部分、1行を実行するのに、3個の物理ユニットを使うので、64ユニットには、16行分を写像できます。ちょうど、最初のプログラムと同じ構造になります。
5. コンパイル結果です。5入力演算器が、総動員されていることがわかります。
6. 次は、FFTです。時系列データから、周波数成分を取り出すのに便利です。上の図は、計算結果の例です。横軸が周波数です。特定の周波数のところに、波形のピークが来ています。FFTのコードは、シンプルです。右の図のように、バタフライ演算とよぶ、ログN段の、規則的な積和演算を繰り返します。ただし、データの参照順は、ステージが進むにつれて、変化していきます。さて、前に説明したマージソートでは、ローカルメモリのダブルバッファリング機能による、2レベルパイプライン処理を使いました。FFTでも、ログN段に対して、同じ機能を使います。
7. アイマックスのコードです。青字部分は、乗数をロードしている部分です。そして、赤字部分は、ストアとロードが組になっています。コンパイラは、ローカルメモリの領域長が0であることを検出して、ダブルバッファリング機能に写像します。4096要素のFFTの写像に、52ユニットを使っています。
8. コンパイル結果です。FFTでも、5入力演算器が、総動員されていることがわかります。
9. 最後は、文字列検索です。これは、CPUのコードです。
10. これが、アイマックスのコードです。MCASは、コンペアアンドセットです。第1オペランドが第2オペランドより小さければ0、それ以外はFFを代入します。これをマスクとして使い、一般的な1ワード比較命令を、文字列比較機能として使っています。このように、普通にC言語でプログラムできるだけでは、CGRAを使いこなすことはできません。柔軟かつ大胆な発想が必要です。エンジニアの0.01％ということです。
11. コンパイル結果です。文字列検索でも、5入力演算器が、総動員されていることがわかります。
12. 今回は、ブロックチェインにつかわれるハッシュ計算と、FFTと、文字列検索を題材に、いろいろ説明しました。では、今回はここまでです。おつかれさま。
Anúncio