carmack在asm中的invsqrt

时间:2012-08-19 15:08:59

标签: c optimization assembly x86 fpu

Hullo,我对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例程

(生成的代码远非最优化的东西 - 将fpu与整数混合 操作,也许有意识的人会进行一些改进会大大改善它。)

如何进行optymized?

编辑:

回答@harold

有一个改进:

  • 1.0 / sqrt(100.0)在我的旧机器上需要140个周期

  • InvSqrt - c版本 - 需要44个周期(虽然准确度并不令人惊叹)

  • 在asm下面的ansver与c版本相同,需要29个周期

(测量可能有些近似但是看起来很好IMO,  由rtdsc 1000x for循环完成,然后产生140000/1000 = 140个循环 29000/1000 = 29周期等等)

1 个答案:

答案 0 :(得分:3)

许多进出内存的动作并非真的有必要。这可能不是太多的改进(特别是与首先没有做到这一点并仅仅使用SSE相比)。

未经测试:

; i = 0x5f3759df - (reinterpret_cast<int32>(number) >> 1)
mov eax, dword ptr [ebp+8]
sar eax,1
mov edx, 0x5f3759df
sub edx, eax
mov dword ptr [ebp-4], edx
; y = reinterpret_cast<float>(i)
fld dword ptr [ebp-4]
; x2 = numer * 0.5f
fld dword ptr [ebp+8]
fmul dword ptr [half]
; (x2 * y) * y
fmul st(0), st(1)
fmul st(0), st(1)
; 1.5f - (stuff)
fld dword ptr [threehalfs]
fsubrp st(1), st(0)
; y * (stuff)
fmulp st(1), st(0)

它不应该太难以遵循,但如果你需要它我会制作一些堆栈图。