Skip the sqrt() call in abs() and do
abs(z) < 4
Here are my changes
Code:
#include <stdio.h>
#include <math.h>
// Get the number of processor clock ticks
// This is for gcc3.x compiler only, if you have some
// other compiler, you need something else here
#define RDTSC(llptr) { \
__asm__ __volatile__ ( \
"rdtsc" \
: "=A" (llptr) ); }
typedef struct complex Complex;
struct complex {
double real;
double imag;
};
#define size 1000
#define limit 1000
// if your compiler supports inline functions, then try it
#define HAS_INLINE /*inline*/
int pix[size][size];
// use pointers
HAS_INLINE Complex mult(const Complex *a, const Complex *b)
{
Complex res;
res.real = a->real * b->real - a->imag * b->imag;
res.imag = a->real * b->imag + a->imag * b->real;
return res;
}
// use pointers
HAS_INLINE Complex add(const Complex *a, const Complex *b)
{
Complex res;
res.real = a->real + b->real;
res.imag = a->imag + b->imag;
return res;
}
// don't do sqrt()
// instead of sqrt(x) < 2, do x < 4
HAS_INLINE double Cabs(const Complex *a)
{
return a->real * a->real + a->imag * a->imag;
}
int pixval(double xx, double yy)
{
Complex z = { 0, 0 };
Complex c;
int j;
c.real = yy;
c.imag = xx;
for (j = 0; j < limit && Cabs(&z) < 4; j += 1) {
Complex t = mult( &z, &z);
z = add( &t, &c);
}
return j / 20;
}
void fillpix(double x0, double y0, double xinc, double yinc)
{
int x, y;
double xd, yd;
for (x = 0, xd = x0; x < size; ++x, xd += xinc ) {
for (y = 0, yd = y0 ; y < size; ++y, yd += yinc ) {
// mathematically, multiplication is repeated addition
// computationally, it isn't due to small errors caused by
// floating point numbers being approximations
// this leads to some small differences in the results
#if 1
pix[x][y] = pixval( xd, yd ); // about 1% quicker than repeated multiply
#else
pix[x][y] = pixval( x0 + x * xinc, y0 + y * yinc );
#endif
}
}
}
int main()
{
unsigned long long t1, t2;
int x, y;
RDTSC(t1);
fillpix(-2.0, -2.0, 4.0 / size, 4.0 / size);
RDTSC(t2);
fprintf( stderr, "time=%lld\n", t2-t1 );
for (y = 0; y < size; y += (size / 20)) {
for (x = 0; x < size; x += (size / 50))
printf("%c", ' ' + pix[y][x]);
printf("\n");
}
return 0;
}
On my machine, I got these results
your code: time=46645352892
my code: time=23917603812