0

私はいくつかの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;
   }

それをアセンブリに書き直したいのですが、なんとかそれを書くことができました

   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 ミリ秒に落ちたので、これはより高速です (ただし、内側のループで 2 つのピクセルを計算する巻き戻された c-routine は 115 しかかからず、展開する理由と方法が正確にはわかりません)。それは asm で)

このasmコードは効率的ではないと思います.fpuスタックにすべての変数をロードしようとしました(そしてループの前に7つのダブルをロードしました:cre cim 4.0 re im re2 im2その後、スタック交換の上にそれをロードするtolがありますfstpでポップバックするので、効率的ではないかもしれません

誰かがそれを改善するのを助けることができますか(内側のループの外側の値はあまり重要ではありませんが、内側のループのコードはここで重要です

4

0 に答える 0