Autor: | Wojciech Muła |
---|---|
Dodany: | 14.09.2007 |
Rozkaz haddps wprowadzony w SSE3 działa następująco:
haddps [e, f, g, h], [a, b, c, d] = [a+b, c+d, e+f, g+h] xmm2/mem xmm1 xmm1
Znakomicie ułatwia obliczanie iloczynu skalarnego, a więc także mnożenie wektorów i macierzy 4x4. Przedstawiam przykład równoległego wyznaczania czterech iloczynów skalarnych.
# void sse3_dotprod4(float vec1x4[4*4], float vec2x4[4*4], float result[4]); sse3_dotprod4: mov 4(%esp), %eax # vec1x4 address mov 8(%esp), %edx # vec2x4 address # load 8 vectors # index -> 0 1 2 3 movups 0x00(%eax), %xmm0 # xmm0 := x00 x01 x02 x03 movups 0x00(%edx), %xmm1 # xmm1 := y00 y01 y02 y03 movups 0x10(%eax), %xmm2 # xmm2 := x10 x11 x12 x13 movups 0x10(%edx), %xmm3 # xmm3 := y10 y11 y12 y13 movups 0x20(%eax), %xmm4 # xmm4 := x20 x21 x22 x23 movups 0x20(%edx), %xmm5 # xmm5 := y20 y21 y22 y23 movups 0x30(%eax), %xmm6 # xmm6 := x30 x31 x32 x33 movups 0x30(%edx), %xmm7 # xmm7 := y30 y31 y32 y33 # parallel multiplication mulps %xmm1, %xmm0 # xmm0 := x0*y0 = d00 d01 d02 d03 mulps %xmm3, %xmm2 # xmm2 := x1*y1 = d10 d11 d12 d13 mulps %xmm5, %xmm4 # xmm4 := x2*y2 = d20 d21 d22 d13 mulps %xmm1, %xmm6 # xmm6 := x3*y3 = d30 d31 d32 d33 # horizontal addition haddps %xmm2, %xmm0 # xmm0 := |d00+d01|d02+d03|d10+d11|d12+d13| haddps %xmm6, %xmm4 # xmm4 := |d20+d21|d22+d23|d30+d31|d32+d33| mov 12(%esp), %eax haddps %xmm4, %xmm0 # xmm0 := | dot0 | dot1 | dot2 | dot 3 | # save result movups %xmm0, (%eax) ret