トップ «前の日記(2009-03-05) 最新 編集

Second☆自演乙☆Garage


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;
}