Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
[go: Go Back, main page]

Mesh Optimization[V]
2/13 メッシュの最適化[VI]/逆襲のMMX





MMXの逆襲





	_asm{

		 // --- 行列をMMXレジスタに読み込む

		 // 16ビットマスク
		 xor   eax,eax
		 mov   eax,0ffffh
		 movd  mm7,eax

		 mov   ax,iTrans_matrix3x3._11
		 movd  mm0,eax
		 pand  mm0,mm7
		 psllq mm0,16
 
		 mov   ax,iTrans_matrix3x3._12
		 movd  mm6,eax
		 pand  mm6,mm7
		 por   mm0,mm6

		 psllq mm0,16
		 mov   ax,iTrans_matrix3x3._13
		 movd  mm6,eax
		 pand  mm6,mm7
		 por   mm0,mm6


		 mov   ax,iTrans_matrix3x3._21
		 movd  mm1,eax
		 pand  mm1,mm7
		 psllq mm1,16
 
		 mov   ax,iTrans_matrix3x3._22
		 movd  mm6,eax
		 pand  mm6,mm7
		 por   mm1,mm6

		 psllq mm1,16
		 mov   ax,iTrans_matrix3x3._23
		 movd  mm6,eax
		 pand  mm6,mm7
		 por   mm1,mm6


 		 mov   ax,iTrans_matrix3x3._31
		 movd  mm2,eax
		 pand  mm2,mm7
		 psllq mm2,16
 
		 mov   ax,iTrans_matrix3x3._32
		 movd  mm6,eax
		 pand  mm6,mm7
		 por   mm2,mm6

		 psllq mm2,16
		 mov   ax,iTrans_matrix3x3._33
		 movd  mm6,eax
		 pand  mm6,mm7
		 por   mm2,mm6


		// mm0 mm1 mm2 ... 3×3行列


		// 頂点をmm3レジスタに読み込む // ループする場合はここから
 		 mov   ax,tx
		 movd  mm3,eax
		 pand  mm3,mm7
		 psllq mm3,16
 
		 mov   ax,ty
		 movd  mm6,eax
		 pand  mm6,mm7
		 por   mm3,mm6
		 psllq mm3,16

		 mov   ax,tz
		 movd  mm6,eax
		 pand  mm6,mm7
		 por   mm3,mm6


		// 行列計算
		pxor    mm5,mm5
		movq   mm4,mm3	// 一段め
		pmullw mm4,mm0
		paddw  mm5,mm4

		movq   mm4,mm3	// 二段め
		pmullw mm4,mm1
		paddw  mm5,mm4

		movq   mm4,mm3	// 三段め
		pmullw mm4,mm2
		paddw  mm5,mm4


		psraw  mm5,8

		movd temp2,mm5
		psrlq mm5,32
		movd temp1,mm5

	}


 このPrejudiceにとって、日付はあってないようなものですが、原則的にはよほどの理由がない限り、アップロードしてから12時間程度は新しい話題を書かないことにしています。

 しかし今日、敢えてその不文律を破るのは、それほどに衝撃的な成果が上がったからです。

 右のコードを見てください。これは完全16ビット精度(中間精度16ビット)で3X3行列を処理するコードです。

 かなり冗長に見えますが、このコードのじつに2/3が行列をMMXレジスタに読み込む作業を(しかもだらだらと)行っているためで、実際にループする部分は後半のほんのわずかなステップです。

 そしてなんと、驚くなかれ、このループ部分は僅か32クロックなのです。
 まだ、なんの工夫も最適化もしていません。少しやったことといえば固定小数点の精度を12ビットから8ビットへ下げたことくらいです。

 32クロックという数字は、昨日とりあげた、浮動小数点を使ったルーチンの166クロックに比べて実に5倍近い速度で、なおかつまだソフトウェア・パイプライン化には手をつけていませんから、さらにコードが増えると仮定しても、少なくとも3倍の速度で計算できることになります。まさにシャア。これからはMMXが赤い彗星となる時代なのです。

 といっても、あまりにも精度が低いのでまだ実験段階ですが、必ずや驚くべき成果が上がるとふんでいます。

 ちなみにこれはごく普通の描画アルゴリズムを使った場合の話ですから、この研究のテーマである「ベクトルによるメッシュアルゴリズムの改善」を加えれば劇的に高速化できるはずです。なにしろMMXではベクトルを加算するのが僅か1クロックで済んでしまうのですから。

 しかし弊害もあります。

 最大のものは、中間精度が16ビットなので、精度が極めて悪いことでしょう。

 しかし、考えてみれば、Quaternionで姿勢を扱うようにすれば、精度などあってないようなものです。むしろ、中間精度を32ビットに底上げするために妙な小細工をしてパイプラインをストールさせてしまうことの方が問題でしょう。

 ということでMMXは使いようによってはまだまだイケルとわかりました。

 とりあえず次回は・・・実際にMMXで描画させるところまで作りたいっすね。