Upgrading the Swift 1.2 version of the orbitals project brought some new performance challenges.
I revisit a post by David Steuber, which benchmarked C and Swift generating a 2880x2880 pixel Mandelbrot with 4000 iterations per pixel. C killed Swift.
In C vs Swift 1.2, David concludes
The major take away on this is that Swift is not C or C++. For high performance computing, code has to be structured differently.
David acknowledges the Swift version is quite different from the C implemetation, which allocates an array for each pixel. Worse still, this array grows dynamically as it iterates 4000 times, per pixel.
Baseline
The C version will serve as our baseline. Using -Ofast
1 it completed in about 20.5 seconds.
orbitals 20.50s user 0.03s system 99% cpu 20.541 total
Swift
I restructured the Swift code so it was semantically equivalent to the C implementation, meaning that it used fixed arrays and a single core. Using the default compiler optimizations, it completed in just under 43 seconds.
orbitals-swift 42.67s user 0.12s system 100% cpu 42.768 total
Enabling -whole-module-optimization
dropped the runtime to 37.5 seconds. Adding -Ounchecked
reduced it a further 9 seconds to complete in 28.5 seconds.
orbitals-swift 28.35s user 0.11s system 100% cpu 28.446 total
Tip
Swift 2.2 was used for this post
1 -flto
hurt performance, hence limiting to the -Ofast
option ↩