Vectorized calculation using Matlab
C/C++ static calculation:
Single point calculation
static inline int mandel(float c_re, float c_im, int count)
{
float z_re = c_re, z_im = c_im;
int i;
for (i = 0; i < count; ++i) {
if (z_re * z_re + z_im * z_im > 4.f)
break;
float new_re = z_re*z_re - z_im*z_im;
float new_im = 2.f * z_re * z_im;
z_re = c_re + new_re;
z_im = c_im + new_im;
}
return i;
}
Whole image calculation
void mandelbrotSerial(
float x0, float y0, float x1, float y1,
int width, int height,
int startRow, int totalRows,
int maxIterations,
int output[])
{
float dx = (x1 - x0) / width;
float dy = (y1 - y0) / height;
int endRow = startRow + totalRows;
for (int j = startRow; j < endRow; j++) {
for (int i = 0; i < width; ++i) {
float x = x0 + i * dx;
float y = y0 + j * dy;
int index = (j * width + i);
output[index] = mandel(x, y, maxIterations);
}
}
}
Multi-threaded calculation: divide the entire image into many blocks, start multiple threads, and each thread calculates an independent piece.
typedef struct {
float x0, x1;
float y0, y1;
unsigned int width;
unsigned int height;
int maxIterations;
int* output;
int threadId;
int numThreads;
} WorkerArgs;
extern void mandelbrotSerial(
float x0, float y0, float x1, float y1,
int width, int height,
int startRow, int numRows,
int maxIterations,
int output[]);
//
// workerThreadStart --
//
// Thread entrypoint.
void* workerThreadStart(void* threadArgs) {
WorkerArgs* args = static_cast<WorkerArgs*>(threadArgs);
// TODO: Implement worker thread here.
printf("Hello world from thread %d\n", args->threadId);
return NULL;
}
//
// MandelbrotThread --
//
// Multi-threaded implementation of mandelbrot set image generation.
// Multi-threading performed via pthreads.
void mandelbrotThread(
int numThreads,
float x0, float y0, float x1, float y1,
int width, int height,
int maxIterations, int output[])
{
const static int MAX_THREADS = 32;
if (numThreads > MAX_THREADS)
{
fprintf(stderr, "Error: Max allowed threads is %d\n", MAX_THREADS);
exit(1);
}
pthread_t workers[MAX_THREADS];
WorkerArgs args[MAX_THREADS];
for (int i=0; i<numThreads; i++) {
// TODO: Set thread arguments here.
args[i].threadId = i;
}
// Fire up the worker threads. Note that numThreads-1 pthreads
// are created and the main app thread is used as a worker as
// well.
for (int i=1; i<numThreads; i++)
pthread_create(&workers[i], NULL, workerThreadStart, &args[i]);
workerThreadStart(&args[0]);
// wait for worker threads to complete
for (int i=1; i<numThreads; i++)
pthread_join(workers[i], NULL);
}