如何优化FPU例程

时间:2013-04-14 12:29:40

标签: c optimization assembly x86 fpu

我有一些c-routine

    int n_mandelbrot(double c_im, double c_re, int N_ITER)
    {
      static  double re, im, re2, im2;
      static  int n;

      im2=im=0;
      re2=re=0;

     for(n=0; n<N_ITER; n++)
     {
        im =  (re+re)*im    + c_im;
        re =   re2 - im2    + c_re;
        im2=im*im;
        re2=re*re;
        if ( re2 + im2 > 4.0 ) break;
     }

     return n;
   }

想要将它重写为汇编,我设法写了

   n_mandelbrot_fpu_double: ;; (double cre, double cim, int N_ITER)

   mov   edx, dword [esp+20]  ;; N_ITER
   mov   ecx, 0

   fld        qword [esp+4+0]  ;; cre
   fld        qword [esp+12+0] ;; cim

   fld1
   fadd st0, st0
   fadd st0, st0         ;; 4.0

   fldz              ;; re = 0
   fldz              ;; im  = 0
   fldz              ;; re2 = 0
   fldz              ;; im2 = 0

   mlloopp:

   ;; here
   ;;            im =  (re+re)*im    + c_im;
   ;;            re =   re2 - im2    + c_re;
   ;;            im2=im*im;
   ;;            re2=re*re;
   ;;            if ( re2 + im2 > 4.0 ) break;

   ;; STACK:  cre cim 4.0 re im re2 im2

   fld st3
   fadd st0, st0
   fmul st3
   fadd st6
   fxch st3
   fstp st0

   fld  st1
   fsub st1
   fadd st7
   fxch st4
   fstp st0

   fld st2
   fmul st0, st0
   fxch st1
   fstp st0

   fld st3
   fmul st0, st0
   fxch st2
   fstp st0

   fld    st0
   fadd   st2
   fcomp  st5
   fnstsw ax
   sahf
   ja    mloopout

   inc    ecx
   cmp    ecx,edx
  jb     mlloopp

  mloopout:

  fstp st0
  fstp st0
  fstp st0
  fstp st0
  fstp st0
  fstp st0
  fstp st0

  mov eax, ecx

  ret

c-routine使我的程序循环运行150毫秒并随之丢弃 到105毫秒,所以这更快(虽然计算时未展开的c例程) 内循环中的两个像素只需要115,我不知道为什么 以及如何在asm中展开它

这个asm代码效率不高我认为,我尝试加载所有变量 fpu堆栈(在循环之前我加载7倍于它:cre cim 4.0 re im re2 im2 然后有一个加载它的堆栈交换和 用fstp回弹,所以我认为可能没有效率

有人可以帮助改善它(内循环之外的值) 并不重要,但内循环中的代码很重要 这里

0 个答案:

没有答案