我已经写了一些x86 asm - 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汇编,我想找一些 上面的优化(纯fpu老asm特别是没有sse 但有点比上面更优化了)
特别是我想知道上面这件事是否有一些蹩脚的编码: 我在fpu堆栈上加载x y z向量然后计数1 / sqrt(x * x + y * y + z * z) 然后再次从ram加载x y z并乘以值然后存储 -
这是次优化吗?我应该尝试加载x y z一次(不是两次) 然后把它保存在fpu堆栈计数上,然后存储到最后?
答案 0 :(得分:1)
您可以完全按照建议操作,只加载x
,y
和z
一次。这似乎可以/应该有所帮助。除此之外,假设你仍然不想使用近似的平方反转法,我认为没有太多机会。
未经测试:
; 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