C 如何优化FPU例程

C 如何优化FPU例程,c,optimization,assembly,x86,fpu,C,Optimization,Assembly,X86,Fpu,我有一些c-程序 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;

我有一些c-程序

    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;
   }
c-routine使我的程序循环运行150毫秒,并随之停止 到105毫秒,因此速度更快(尽管无意中使用了c-例程和计算 两个像素的内循环只需要115,我不知道确切的原因 以及如何在asm中展开)

这个asm代码效率不高,我想,我尝试加载所有变量 fpu堆栈(以及循环I load 7之前)加倍为:cre cim 4.0 re im re2 im2 然后在堆栈顶部加载它,并进行交换 用fstp弹出回来,所以我认为它可能没有效率

是否有人可以帮助改进(内部循环之外的值) 这并不重要,但内部循环中的代码非常重要
这里

不要担心
fxch
,在正常情况下它的延迟为0。我会担心
fcomp\fnstsw\sahf
这件事,但这不太好。难道你没有
fcomip
吗?fxch可能很快,但在上面也使用了大量的“fld stN”计算,然后是“fxch N fstp st0”-若要在堆栈计算深处加载值,请将其删除,然后再次将其推回堆栈深处)-也很快吗?-上面的代码似乎在计算它做了什么,但在不必要的加载方面对我来说似乎真的很愚蠢,然后弹出值如果你能够编写一个性能优于现代C编译器的汇编程序,并对你拥有的函数类型进行了充分优化,我会非常惊讶。也许你应该这样做首先投资于体面的C代码?帮助你的编译器帮助你。特别是你将所有变量声明为
static
,这确实会产生反效果,这会对编译器产生很大的限制。摆脱static可以立即改进。更新你的编译器,现代编译器会为此生成SSE2代码。是的,我的编译器能够为循环生成15行的非常密集的SSE代码。这些天你绝对不应该手工做这些事情。
   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