你好,我对asm没有太多经验,我想在汇编中重写carmack的倒平方根c例程
; float InvSqrt (float x){
;
@173:
push ebp
mov ebp,esp
add esp,-8
;
; float xhalf = 0.5f*x;
;
fld dword ptr [@174]
fmul dword ptr [ebp+8]
fstp dword ptr [ebp-4]
;
; int i = *(int*)&x;
;
mov eax,dword ptr [ebp+8]
mov dword ptr [ebp-8],eax
;
; i = 0x5f3759df - (i>>1);
;
mov edx,dword ptr [ebp-8]
sar edx,1
mov ecx,1597463007
sub ecx,edx
mov dword ptr [ebp-8],ecx
;
; x = *(float*)&i;
;
mov eax,dword ptr [ebp-8]
mov dword ptr [ebp+8],eax
;
; x = x*(1.5f - xhalf*x*x);
;
fld dword ptr [ebp-4]
fmul dword ptr [ebp+8]
fmul dword ptr [ebp+8]
fsubr dword ptr [@174+4]
fmul dword ptr [ebp+8]
fstp dword ptr [ebp+8]
;
; return x;
;
fld dword ptr [ebp+8]
;
; }
;
@176:
@175:
pop ecx
pop ecx
pop ebp
ret
这是编译器生成的,但我想对其进行优化并重写为 asm 例程
(生成的此代码远非最佳 i 事物 - 将 fpu 与整数运算混合,也许有意识的人重新编写会大大改善它)
如何优化?
编辑:
至于回答@harold
有一个改进:
1.0/sqrt(100.0) 在我的旧机器上需要 140 个周期
InvSqrt - c 版本 - 需要 44 个周期(尽管准确度并不惊人)
asm 中的 ansver 与 c 版本相同,需要 29 个周期
(测量值可能有些近似,但 IMO 总体上似乎没问题,由 rtdsc 1000x for loop 完成,然后产生 140000/1000 = 140cycles 29000/1000 = 29cycles 等等)