1

x86 asm - 3 つの float のベクトルを正規化する fpu ルーチン - をいくつか作成しました。

    _asm_normalize10:; Function begin
    push    ebp                                     ; 002E _ 55
    mov     ebp, esp                                ; 002F _ 89. E5
    mov     eax, dword [ebp+8H]                     ; 0031 _ 8B. 45, 08
    fld     dword [eax]                             ; 0034 _ D9. 00
    fmul    st0, st(0)                              ; 0036 _ DC. C8
    fld     dword [eax+4H]                          ; 0038 _ D9. 40, 04
    fmul    st0, st(0)                              ; 003B _ DC. C8
    fld     dword [eax+8H]                          ; 003D _ D9. 40, 08
    fmul    st0, st(0)                              ; 0040 _ DC. C8
    faddp   st1, st(0)                              ; 0042 _ DE. C1
    faddp   st1, st(0)                              ; 0044 _ DE. C1
    fsqrt                                           ; 0046 _ D9. FA
    fld1                                            ; 0048 _ D9. E8
    fdivrp  st1, st(0)                              ; 004A _ DE. F1
    fld     dword [eax]                             ; 004C _ D9. 00
    fmul    st(0), st1                              ; 004E _ D8. C9
    fstp    dword [eax]                             ; 0050 _ D9. 18
    fld     dword [eax+4H]                          ; 0052 _ D9. 40, 04
    fmul    st(0), st1                              ; 0055 _ D8. C9
    fstp    dword [eax+4H]                          ; 0057 _ D9. 58, 04
    fld     dword [eax+8H]                          ; 005A _ D9. 40, 08
    fmulp   st1, st(0)                              ; 005D _ DE. C9
    fstp    dword [eax+8H]                          ; 005F _ D9. 58, 08
    pop     ebp                                     ; 0062 _ 5D
    ret                                             ; 0063 _ C3
    ; _asm_normalize10 End of function

[これは私のコードです ;-) 動作し、私によってテストされました]

私はx86アセンブリをあまり知りません。上記の最適化を見つけたいと思います(特にsseなしの純粋なfpu古いasmですが、上記よりも多少最適化されています)

特に、上記のコードに不完全なコーディングがあるのではないかと思います: fpu スタックに xyz ベクトルをロードし、1/sqrt(x*x+y*y+z*z) をカウントしてから、RAM から xyz を再度ロードし、値を掛けます。お店 -

これは部分最適化であり、xyz を 1 回だけ (2 回ではなく) ロードしてから、fpu スタック カウントに保持してから最後に保存する必要がありますか?

4

1 に答える 1

1

あなたが提案したことを正確に実行して load x、一yzだけ実行できます。役立つ/役立つはずのようです。それとは別に、近似逆平方根トリックをまだ使用したくないと仮定すると、何かの機会はあまりないと思います。

未検証:

; load everything
fld dword [eax]
fld dword [eax+4]
fld dword [eax+8]
; square and add
fld st(2)
fmul st(0), st(0)
                  ; (see diagram 1 for fpu stack)
fld st(2)
fmul st(0), st(0)
                  ; (see diagram 2 for fpu stack)
faddp st(1), st(0)
                  ; (see diagram 3 for fpu stack)
fld st(1)
fmul st(0), st(0)
faddp st(1), st(0)
                  ; (see diagram 4 for fpu stack)
; calculate inverse sqrt
fsqrt
fld1
fdivrp st(1), st(0)
; scale
fmul st(1), st(0)
fmul st(2), st(0)
fmulp st(3), st(0)
; store
fstp dword [eax+8]
fstp dword [eax+4]
fstp dword [eax]

図 1:

st3: x
st2: y
st1: z
st0: x * x

図 2:

st4: x
st3: y
st2: z
st1: x * x
st0: y * y

図 3:

st3: x
st2: y
st1: z
st0: x * x + y * y

図 4:

st3: x
st2: y
st1: z
st0: x * x + y * y + z * z
于 2012-08-18T14:08:23.470 に答える