ホームに戻る
乗算を考える
;
; アセンブラ
;
segment .code USE32
global _mmx
_mmx:
push ebp
mov ebp, esp
mov edx, dword [ebp+8]
mov eax, dword [ebp+12]
movq mm0, [edx]
movq mm1, mm0
movq mm2, [eax]
movq mm3, [eax + 8]
movq mm4, [eax + 16]
movq mm5, [eax + 24]
pmaddwd mm2, mm0
pmaddwd mm4, mm1
pmaddwd mm3, mm0
pmaddwd mm5, mm1
movq mm6, mm2
movq mm7, mm4
punpckldq mm6, mm3
punpckldq mm7, mm5
punpckhdq mm2, mm3
punpckhdq mm4, mm5
paddd mm6, mm2
paddd mm7, mm4
packssdw mm6, mm7
movq [edx], mm6
emms
leave
ret
__end__mmx
/*
* C言語
*/
#include <stdio.h>
extern void mmx(short *buf1, short *buf2);
int main()
{
int i;
short buf1[4 + 4];
short buf2[4 * 4 + 4];
short *pbuf1 = (short *)(((unsigned)buf1 + 7) & ~7);
short *pbuf2 = (short *)(((unsigned)buf2 + 7) & ~7);
static short matrix1[4] = {
3, 3, 3, 1
};
static short matrix2[4 * 4] = {
1, 0, 0, 1,
0, 1, 0, 2,
0, 0, 1, 3,
0, 0, 0, 1
};
for(i = 0; i < 4; i++){
pbuf1[i] = matrix1[i];
}
for(i = 0; i < 16; i++){
pbuf2[i] = matrix2[i];
}
mmx(pbuf1, pbuf2);
for(i = 0; i < 4; i++){
printf("%02d ", pbuf1[i]);
}
return 0;
}
このプログラムについて
以下の計算をしています。
|1 0 0 0|
|0 1 0 0|
|x y z w| = |3 3 3 1||0 0 1 0|
|1 2 3 1|
アセンブラのほうは見やすさを優先しているので速度の最適化は試みてません。