Thursday, 3 February 2011

Last words on my simple ray tracer

Eventually I decided to publish some results for my simple raytracer project. It's kind of an endless project that might bring very interesting developments when starting to dig into complicated matters like using triangle meshes and accelerating structures. Although, I decided to put this on hold for the time being, as I managed to reach the initial goals for this project:
  • Improve my knowledge of C# and .NET
  • Learn the basics of ray tracing techniques
  • Push the basic algorithms to their best in C#
  • Make use of all the available cores on a machine to speed up the raytracing process.


I haven't yet set up a website where people could download my projects from, so in the meantime, if you are interested in more details, or you want to take a look at the code, please send me an email and I'll get back to you as soon as possible.
So, as I said, one of the main goals was to maximize the usage of the available cores to perform the raytracing. Even if the raytracer is not very complex, I dedicated a good effort in making the prototype application very interactive, in order to allow me to quickly test the implementation on different scenes, with different parameters, but especially using a different number of cores to perform the computation. The following graph summarizes the results:


I run my tests on a machine with a i7-930 processor. It has 4 cores, taking advantage of the Intel hyperthreading technology, the total number of hardware cores goes up to 8. The x-axis represents the number of worker threads, the y-axis the average time to raytrace the test scene in milliseconds. Each average was computed on a set of 10 executions.
Without too much surprise, being the raytracing an embarrassingly parallel problem, increasing the number of worker threads, improves the performance significantly. When the number of threads is '0', all the work is performed on the main application threads and the raytracing process is completely serial. The best result is obtained with 4 worker threads, while is quite evident that adding worker threads over the number of physical cores is not much beneficial.
I'm not completely satisfied with these results, because I know that it could be done better. The 'pure' serial cost of presenting the image on a bitmap is around 2ms, pretty much negligible, so, given a cost of around 330ms with no worker threads, I would expect to see respectively around 165ms, 110ms, 85ms for 1, 2 and 3 workers.
More accurate measurements would be necessary to confirm my impression that the behavior is not close to the ideal performance because of a combination of the following reasons:
  • The scheduler has a considerable overhead, using a queue shared between the threads and synchronized with mutexes.
  • Although I tried to minimize the memory allocations while the raytracing is computed, C# is a very dynamic language and it is very difficult to have a full control on the memory usage and the memory is clearly a shared resource that introduces additional hidden synchronization.
  • The improvement seen with the introduction of the 4th worker is likely explained by the fact that main thread has some additional work to do to process UI events while the workers perform the rendering.
There is a lot of potential for improvements and maybe some day I'll go back to the project to try out some ideas.

Sunday, 16 January 2011

Time flies!

Wow, it's been quite a long time since the last (and actually only) post! I've been so busy with so many life changes that I left several projects unfinished and almost forgot about this blog and all the good intentions I had when I started it. Well, anyways, it's time for a restart and maybe this time things will go a bit better.
I currently live in San Francisco and work for a small middleware company. Being in the cradle of technology is of course a great stimulus for the brain... let's see if I can get some momentum from being here!

Sunday, 14 December 2008

Playing around with Ray Tracing


In the last couple of days I've been experimenting with ray-tracing a little bit.
I started from a simple wikipedia introduction from here and because this was supposed to be a fun programming exercise, I went into coding as soon as possible.
I chose to use c# just to speed up the development and XNA just to avoid to write another math library (XNA comes with a nice Vector library). I know that .NET/c# is not probably the best choice in term of performance, but at this stage I just wanted to focus on the algorithm.
Anyway, the above picture is the first interesting result I got. 5 spheres and two directional light sources, with ambient, diffuse and specular effects. I also implemented the tracing recursion (just 1 level in the picture, but the code is generic) and shadow rays.
The code is pretty straightforward at this stage: for every pixel on the screen, throw a ray from the view point through the image plane and get the intersection with the closest object. The ray cast information is used to:
  • compute a shadow ray against all the light sources in the scene (easy for directional lights, the only supported type atm)
  • if the point is not in shadow, compute the diffuse and specular contribution
  • if the requested recursion level is not reached, compute a reflection ray and trace it against the scene.
And that's it! It was quite simple so far: the ray-sphere and ray-plane analythical intersections don't require very complex math and the shading algorithms are quite basics. I used the good lighthouse3d glsl tutorial as a reference, here. Of course, ray tracing is an incredibly complex topic and this is just a sort of "hello world"! The matter is really fascinating me, so I hope I can find some time to start implementing some more complex aspect of the topic. I would also like to release some code soon!

Coding experiments

Here I am,
I finally started a blog, yet another programming blog. I work in the games industry, usually on complex and long term projects, and I don't have much spare time to learn tools/languages and technologies that I don't usually work on in the office. For this reason, I will jump around different topics, and probably I won't manage to publish anything very interesting and complete, but I'll try to post something from time time!