Parallel rendering with OpenMP.
authorClaude Heiland-Allen <claude@mathr.co.uk>
Sat, 21 Dec 2013 04:22:55 +0000 (04:22 +0000)
committerClaude Heiland-Allen <claude@mathr.co.uk>
Sat, 21 Dec 2013 04:22:55 +0000 (04:22 +0000)
commit9dfc508d2c4af17bcd951c419487411ebca4b8d7
treea0197b318d1bb3f6e183a00a1f75cbb34c31ac4f
parent706785ce2684df3c7bae5caaa92885fcfef14300
Parallel rendering with OpenMP.

Modern computers have increasing numbers of CPU cores.  So far our
program only uses one.  The OpenMP system uses compiler ``pragmas''
to annotate the program, letting the compiler know which parts can
be parallelized safely.  We couldn't use this before when we were
outputting pixels as they were being calculated, because the order
would be jumbled: some pixels might take longer to compute because
they needed more iterations to escape.  By collecting all the
results in memory and only then writing the image, we can now add
a pragma in our render() function and the required compiler flag to
the Makefile.

We parallelize the outermost loop, because parallism adds some
overhead for synchronisation, and the inner loop might not perform
enough real work to offset the increased overheads.  Benchmarking
the resulting program is quite pleasing:

    $ time for exp in $(seq -w 0 15)
      do
        ./render \
          -1.759937295271429505091916757 \
           0.012591790526496335594898047 \
          2e-${exp} 2 > ${exp}-render.ppm
      done
    real    3m51.435s
    user    3m50.862s
    sys     0m0.452s
    $ make
    $ time for exp in $(seq -w 0 15)
      do
        ./render \
          -1.759937295271429505091916757 \
           0.012591790526496335594898047 \
          2e-${exp} 2 > ${exp}-render.ppm
      done
    real    1m12.379s
    user    3m25.829s
    sys     0m0.308s
    $

On a quad-core machine, this tiny change makes the rendering finish
in a quarter of the real (wall clock) time.
Makefile
mandelbrot_imp.c