I am recently playing with fractals (nothing serious, just some nice examples for my upcoming Fortran Graphics Library). With fractals involving complex numbers I came across a weird fact: at least in GFortran, complex arithmetic seems to be significantly slower than doing the equivalent calculations using real numbers. For example, consider the following image:
This is a tiny part of the Mandelbrot set (often called “the seahorse” - in fact there is an infinite number of those, lots can be seen in the picture, just smaller ones.) The Fortran program that creates this image is simple enough, and becomes even simpler if I use complex numbers. Just to clarify the concept, I am using either (a) complex numbers with
real64 components, or (b) just
real64 vectors of
dimension(2) to imitate the real and imaginary part of a complex number. The color of each pixel is computed in a loop with up to 6500 iterations (darker color means more iterations were needed.)
Now, I would expect using complex numbers (native in Fortran) to be noticeably faster, since when I am using real numbers I have to do more calculations in each iteration to get the same result. However, it turns out the opposite of what I would expect is true. In all my experiments, using pairs of
real64 numbers is in fact about 2.2 times faster than using complex numbers. I tried many other cases, the “magic number” 2.2 (give or take by a small amount) seems to be persistent everywhere.
The example problem I used here shouts “parallelize me” from afar - which I did, and that does of course reduce the computation time significantly. However complex arithmetic remains more than two times slower - in fact it gets slightly worse, 2.2-2.6 times slower in every case, using the OpenMP-parallelized version of the code.
This example is simple enough to just ignore complex numbers and do the same thing with pairs of real numbers. But imagine a more complicated case, with lots of more sophisticated calculations. Years ago, I was working on a project that everything had to be done in the complex plane, and it was far more complicated than the example I used here. In such a case, using anything but complex numbers was a headache to even thing of.
So I am wondering, did anyone notice such a performance difference? Perhaps using other compilers and/or more complicated calculations than just those needed in fractals? My best bet is that complex numbers are poorly implemented - in GFortran, at least. But I might be wrong here.