私はいくつかの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でポップバックするので、効率的ではないかもしれません
誰かがそれを改善するのを助けることができますか(内側のループの外側の値はあまり重要ではありませんが、内側のループのコードはここで重要です