Я пишу компилятор, который реализует высокоуровневое описание фрактальной формулы в исполняемом коде.Например, мой файл определения формул начинается следующим образом:
Mandelbrot
z := z^p + c
Burning Ship
z := (|x| + i |y|)^p + c
Я использую методы возмущения, популяризированные SuperFractalThing Кимартина, и использую MPFR для высокоточных опорных орбит.Пока что я излучаю исходный код на C, но он не оптимизирован.
Например, вот выходной внутренний цикл для мощности 3 Burning Ship:
// fx = (v13+(abs((v15*(v15*v15)))+(abs((v15*(v16*v16)))*-3)))
// fy = (v14+((abs((v15*(v15*v16)))*3)+(abs((v16*(v16*v16)))*-1)))
r_sqr_r(v27,v15);
r_mul_rr(v26,v15,v27);
r_abs_r(v26,v26);
r_sqr_r(v29,v16);
r_mul_rr(v28,v15,v29);
r_abs_r(v28,v28);
v11=-3;
r_mul_ri(v27,v28,v11);
r_add_rr(v25,v26,v27);
r_add_rr(v19,v13,v25);
r_mul_rr(v28,v15,v16);
r_mul_rr(v27,v15,v28);
r_abs_r(v27,v27);
v11=3;
r_mul_ri(v26,v27,v11);
r_sqr_r(v28,v16);
r_mul_rr(v27,v16,v28);
r_abs_r(v27,v27);
r_neg_r(v27,v27);
r_add_rr(v25,v26,v27);
r_add_rr(v20,v14,v25);
// v15 = fx
// v16 = fy
r_set_r(v15,v19);
r_set_r(v16,v20);
, который может быть немедленно улучшенповторно связав v15*(v15*v16)
как (v15*v15)*v16
и разделив квадратные значения между строфами (mpfr_sqr
быстрее, чем mpfr_mul
; избегать повторного вычисления - очевидный выигрыш).
Я хочу использоватьПроходы быстрой / небезопасной математической оптимизации LLVM (устранение общих подвыражений, повторная ассоциация и т. Д.), Но с использованием mpfr_t
вместо float
или double
.
У меня была одна идея - использовать одинарную точностьfloat
для представления моего типа с низкой точностью и double
для представления моего типа с высокой точностью.Затем оптимизируйте все это, разберите ИК и реконструируйте его с реальными типами (то есть double
и mpfr_t
).
Кто-нибудь пытался что-то подобное?Что может пойти не так?