2009-03-07
_ [PS3]今更だけどアレ
1月に考えた、ちまたで「トランザム」って言われてるアレの実装例です(俺が言い出したんですけどね)
ちっとも通常の3倍ではありません
ちなみに、こいつはspu_cntbの効果を勘違いしてた失敗作
ワードのビットを全部カウントすると思い込んでました。
sumbを使う必要がありますね
vec_uint4 transpose_sum(sliced_128x32 s) { /* Description: * 128個の32bit乱数値は32本のレジスタ上に1ビット単位で分割して配置されている。 * 合計をするにあたり、cntb命令で1ビット単位でのビット数をカウントし、 * 有効桁6ビットの合計値を得る。 * 階段状に加算していくことで合計値を求める。 */ static const vec_uchar16 pack_lower = { 0x12, 0x13, 0x02, 0x03, 0x16, 0x17, 0x06, 0x07, 0x1A, 0x1B, 0x0A, 0x0B, 0x1E, 0x1F, 0x0E, 0x0F, } /* bit-count(cntb; レイテンシ2)で各ビットの合計をとる */ s.bits0 = spu_cntb(s.bits0); s.bits1 = spu_cntb(s.bits1); s.bits2 = spu_cntb(s.bits2); s.bits3 = spu_cntb(s.bits3); s.bits4 = spu_cntb(s.bits4); s.bits5 = spu_cntb(s.bits5); s.bits6 = spu_cntb(s.bits6); s.bits7 = spu_cntb(s.bits7); s.bits8 = spu_cntb(s.bits8); s.bits9 = spu_cntb(s.bits9); s.bits10 = spu_cntb(s.bits10); s.bits11 = spu_cntb(s.bits11); s.bits12 = spu_cntb(s.bits12); s.bits13 = spu_cntb(s.bits13); s.bits14 = spu_cntb(s.bits14); s.bits15 = spu_cntb(s.bits15); s.bits16 = spu_cntb(s.bits16); s.bits17 = spu_cntb(s.bits17); s.bits18 = spu_cntb(s.bits18); s.bits19 = spu_cntb(s.bits19); s.bits20 = spu_cntb(s.bits20); s.bits21 = spu_cntb(s.bits21); s.bits22 = spu_cntb(s.bits22); s.bits23 = spu_cntb(s.bits23); s.bits24 = spu_cntb(s.bits24); s.bits25 = spu_cntb(s.bits25); s.bits26 = spu_cntb(s.bits26); s.bits27 = spu_cntb(s.bits27); s.bits28 = spu_cntb(s.bits28); s.bits29 = spu_cntb(s.bits29); s.bits30 = spu_cntb(s.bits30); s.bits31 = spu_cntb(s.bits31); /* 攪拌命令を用いた積和算(Odd 24命令)を行う。これで加算のサイクルを短縮する * bits[n] = (bits[n] << 24) * + (bits[n+8] << 16) * + (bits[n+16] << 8) * + bits[n+24] */ s.bits0 = spu_shufb(s.bits16, s.bits0, pack_lower); s.bits1 = spu_shufb(s.bits17, s.bits1, pack_lower); s.bits2 = spu_shufb(s.bits18, s.bits2, pack_lower); s.bits3 = spu_shufb(s.bits19, s.bits3, pack_lower); s.bits4 = spu_shufb(s.bits20, s.bits4, pack_lower); s.bits5 = spu_shufb(s.bits21, s.bits5, pack_lower); s.bits6 = spu_shufb(s.bits22, s.bits6, pack_lower); s.bits7 = spu_shufb(s.bits23, s.bits7, pack_lower); s.bits8 = spu_shufb(s.bits24, s.bits8, pack_lower); s.bits9 = spu_shufb(s.bits25, s.bits9, pack_lower); s.bits10 = spu_shufb(s.bits26, s.bits10, pack_lower); s.bits11 = spu_shufb(s.bits27, s.bits11, pack_lower); s.bits12 = spu_shufb(s.bits28, s.bits12, pack_lower); s.bits13 = spu_shufb(s.bits29, s.bits13, pack_lower); s.bits14 = spu_shufb(s.bits30, s.bits14, pack_lower); s.bits15 = spu_shufb(s.bits31, s.bits15, pack_lower); s.bits0 = spu_shufb(s.bits8, s.bits0, pack_lower); s.bits1 = spu_shufb(s.bits9, s.bits1, pack_lower); s.bits2 = spu_shufb(s.bits10, s.bits2, pack_lower); s.bits3 = spu_shufb(s.bits11, s.bits3, pack_lower); s.bits4 = spu_shufb(s.bits12, s.bits4, pack_lower); s.bits5 = spu_shufb(s.bits13, s.bits5, pack_lower); s.bits6 = spu_shufb(s.bits14, s.bits6, pack_lower); s.bits7 = spu_shufb(s.bits15, s.bits7, pack_lower); /* シフト・加算で1ベクトル(32bit×4)化 */ s.bits0 = spu_slqw(s.bits0, 7); s.bits1 = spu_slqw(s.bits1, 6); s.bits2 = spu_slqw(s.bits2, 5); s.bits3 = spu_slqw(s.bits3, 4); s.bits4 = spu_slqw(s.bits4, 3); s.bits5 = spu_slqw(s.bits5, 2); s.bits6 = spu_slqw(s.bits6, 1); s.bits0 = spu_add(s.bits0, s.bits1); s.bits2 = spu_add(s.bits2, s.bits3); s.bits4 = spu_add(s.bits4, s.bits5); s.bits6 = spu_add(s.bits6, s.bits7); s.bits0 = spu_add(s.bits0, s.bits2); s.bits4 = spu_add(s.bits4, s.bits6); s.bits0 = spu_add(s.bits0, s.bits4); return s.bits0; }
[コメントを書く]
コメントをお寄せ下さい。SPAM対策のため名前にはトリップ(2ch掲示板互換)が必要です。
[TrackBack URL: http://tripper.kousaku.in/tb.rb/20090307]