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]