Not a Julia set!

Following my previous post, I put together a primitive Mandelbrot explorer.  Rambling through the Mandelbrot landscape, I found this:

Ceci n


It resembles a slice of the Julia set.  But the Julia set is contained within a boundary, while somewhere in this image there is a filament leading the rest of the Mandelbrot set outside the frame.  As I’ve not implemented coordinate tracking, I’m unlikely ever to find it again. :p

(Update: It’s a Julia island.  Maybe I should try reading the Wikipedia articles that I link to…)

The program is written in C, using SDL for graphics.  SDL is straightforward enough.  I know our SC2 mod uses it, but that’s always been abstracted away by UQM code.  (Learning SDL should save me from having to write Python and/or libpng renderers for my other simulations.)

It’s not particularly efficient — yet :).  I enabled OpenMP for the loops, but it’s not clear how much that helps.  It renders things in “blinds”, i.e. lines 0, 20, 40, … 1, 21, 41, …; updating the displaying and checking user input between each set.  When OpenMP allocates the indexes (0, 20, …, 1060) to each task, I believe it uses contiguous partitions.  This means that if, for instance, the top half the image is emptier than the bottom half, the threads handling that part will take longer to complete, while the others finish early.  For an efficient and even rendering, we want something like:

  1. In this frame (i.e. between display updates), choose some fraction of the pixels to render.
  2. Partition that fraction into jobs, and allocate them to threads.
  3. Since some pixels take longer than others, distribute them evenly (or use a work list with more jobs than threads).

The technique that springs to mind is to treat the pixels as a linear array of size N.  To render in n frames, choose every n‘th pixel for this frame i.  With k jobs, out of the chosen pixels, assign every k‘th pixel to thread j.

int num_pixels = width*height;
int num_jobs = omp_get_num_threads();
int pixels_per_job = (int) ceil((double) num_pixels / num_frames / num_jobs);
if (frame < num_frames)
{
    int j;
    #pragma omp parallel for
    for (j = 0; j < num_jobs; j++)
    {
        int i;
        for (i = 0; i < pixels_per_job; i++)
        {
            int a = (i * num_jobs + j) * num_frames + frame;
            if (a < num_pixels)
            {
                int x = a % width;
                int y = a / width;
                do_pixel(x, y);
            }
        }
    }
    frame++;
}

Slightly messy since I’d like like to use OpenMP but I also want a bit more control about how it partitions the indexes of the loop.  Not tested yet…

(A small rant about MSVC — it’s a PITA getting even a simple C project to compile.  First there are complaints about undefined _main symbols; then there’s the need to download a 350 MB SDK just to get a few kb of OpenMP libraries.  Would you believe people actually rave about how MSVC “just works”!)

This entry was posted in Programming, Science and tagged , , , , . Bookmark the permalink.

2 Responses to Not a Julia set!

  1. Pingback: Tracing a fractal outline | EJRH

  2. Pingback: Minor hardware improvements and plans | EJRH

Leave a comment