ホーム 道しるべ 憩いの広場 濃緑空間 濃緑研の日記

ペアリング最適化II
ホーム ] 上へ ] 普通に時間測定 ] ループ展開・時間測定 ] ペアリング最適化I ] [ ペアリング最適化II ] x86FPUとの比較 ] 3DNow!SISDと比較 ] 配列演算総括 ]

 

最適化Iに比べいくぶん(数パーセント)高速になりました。

mtrx(float a[4], float b[4][4], float c[4])
{
    _asm{
        mov         edi,a             // edi = 配列a[0]のアドレス

        movq    mm0,[edi]         // mm0:                 a[1]:             a[0]
        mov         ebx,b             // ebx = 配列b[0][0]のアドレス

        movq    mm1,[edi+8]         // mm1:                 a[3]:             a[2]
        mov         ecx,c             // ecx = 配列c[0]のアドレス

        movq    mm2,[ebx]         // mm2:             b[0]b[1]:         b[0]b[0]

        pfmul    (m2,m0)             // mm2:     a[1]*b[0]b[1]: a[0]*b[0]b[0]
        movq    mm3,[ebx+8]         // mm3:             b[0]b[3]:         b[0]b[2]

        pfmul    (m3,m1)             // mm3:     a[3]*b[0]b[3]: a[2]*b[0]b[2]
        movq    mm4,[ebx+16]     // mm4:             b[1]b[1]:         b[1]b[0]

        pfadd    (m2,m3)             // mm2:
        movq    mm5,[ebx+24]     // mm5:             b[1]b[3]:         b[1]b[2]

        pfmul    (m4,m0)             // mm4:     a[1]*b[1]b[1]: a[0]*b[1]b[0]
        pfacc    (m2,m2)             // mm2:     a[3]*b[0]b[3]+a[2]*b[0]b[2]+a[1]*b[0]b[1]+a[0]*b[0]b[0]

        pfmul    (m5,m1)             // mm4:     a[3]*b[1]b[3]: a[2]*b[1]b[2]
        movq    mm6,[ebx+32]     // mm6:             b[2]b[1]:         b[2]b[0]

        pfadd    (m4,m5)             // mm4:
        movq    mm7,[ebx+40]     // mm7:             b[2]b[3]:         b[2]b[2]

        pfacc    (m4,m4)             // mm4:     a[3]*b[1]b[3]+a[2]*b[1]b[2]+a[1]*b[1]b[1]+a[0]*b[1]b[0]
        pfmul    (m6,m0)             // mm6:     a[1]*b[2]b[1]: a[0]*b[2]b[0]

        pfmul    (m7,m1)             // mm7:     a[3]*b[2]b[3]: a[2]*b[2]b[2]
        movq    mm2,[ebx+48]     // mm2:             b[3]b[1]:         b[3]b[0]

        pfadd    (m6,m7)             // mm6:
        movq    mm3,[ebx+56]     // mm3:             b[3]b[3]:         b[3]b[2]

        pfacc    (m6,m7)             // mm6:     a[3]*b[2]b[3]+a[2]*b[2]b[2]+a[1]*b[2]b[1]+a[0]*b[2]b[0]
        movd    [ecx],mm2         // c[i] = mm2

        pfmul    (m2,m0)             // mm2:     a[1]*b[3]b[1]: a[0]*b[3]b[0]
        movd    [ecx+4],mm4         // c[1] = mm4

        pfmul    (m3,m1)             // mm3:     a[3]*b[3]b[3]: a[2]*b[3]b[2]
        movd    [ecx+8],mm6         // c[2] = mm6

        pfadd    (m2,m3)             // mm2:
        pfacc    (m2,m2)             // mm2:     a[3]*b[3]b[3]+a[2]*b[3]b[2]+a[1]*b[3]b[1]+a[0]*b[3]b[0]
        movd    [ecx+12],mm2     // c[3] = mm2
    }
}