As an exercise to learn how to optimize Julia code for performance, I adapted from C++ to Julia a popular raytracing “book” (Ray Tracing In One Weekend by Peter Shirley) into a Pluto.jl notebook. Hopefully this will attract some other newcomers to Julia. (I plan to use this to advertise Julia’s benefits at AMD, where I work.)
My initial implementation ran very slowly, but by eliminating some of my earlier newbie mistakes, then using StaticArrays, Float32, @btime and
--track-allocation=user, I eliminated most of the heap allocations and I think I can soon get pretty close to the performance of a SIMD-optimized C++ implementation.
As a comparison, currently, it takes ~4.1 hours to
render(scene_random_spheres(), t_cam1, 1920, 1000). I read that someone got their SIMD-optimized, multi-threaded CPU-only C++ implementation to run a very similar command in ~1 hour, on a system that is probably comparable with mine. (I plan to eventually run their code to get more precise measurements.) My version isn’t optimized for SIMD and it’s still single-threaded, and processes rays 1-by-1. I also haven’t implemented the BVH (Bounding Volume Hierarchy) raytracing acceleration structure that was likely implemented in that C++ version. So there’s still lots of space for CPU-side optimization. Finally, in the long run I hope to also try to execute on GPU, and also make a version that uses Vulkan raytracing.
If any of you expert can take a look and recommend ways to clean-up the code while maintaining (or improving?) performance, I welcome your suggestions. I’d like this project to grow into an example of how to get good performance on graphics problems with Julia.