Tuesday, November 10, 2009

A Multi-threaded Go Raytracer


Above is the output of the raytracer. Below is a diagnostic mode showing which goroutines raytraced which section of the screen. Each goroutine has its own color to outline the pixels it traces:



I wrote a simple multi-threaded ray tracer in Google's new "go" language. It's an adaptation of Flying Frog Consultancy's Raytracer.

It runs single-threaded about 1/2 the speed of a comparable C++ version. I guess the C++ version benefits from a more optimizing compiler and the ability to inline small functions.

Compared to ordinary C/C++, the Go version was easier to multithread.

On my dual-core Macbook Pro I get an 1.80x speedup when running with GOMAXPROCS > 1:

$ GOMAXPROCS=1 time ./gotrace
1.52 real 1.50 user 0.01 sys
$ GOMAXPROCS=2 time ./gotrace
0.82 real 1.50 user 0.01 sys
$ GOMAXPROCS=3 time ./gotrace
0.81 real 1.50 user 0.01 sys

On an eight-core, 16 Hyperthread HP Z600 running Ubuntu 9.10, (with the source code changed to use 16 goroutines instead of the default 8 goroutines) I get a 5.8x speedup:

$ GOMAXPROCS=1 time ./gotrace
1.05user 0.01system 0:01.06elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+1544outputs (0major+2128minor)pagefaults 0swaps
$ GOMAXPROCS=16 time ./gotrace
1.32user 0.00system 0:00.18elapsed 702%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+1544outputs (0major+2190minor)pagefaults 0swaps

Source code gotracer.zip


4 comments:

erste said...

just tried it on my first gen macbook with 32 bit.
works great! thanks for the code

MacBook:gotracer sebi$ GOMAXPROCS=1 time ./gotrace
4.98 real 4.96 user 0.02 sys
MacBook:gotracer sebi$ GOMAXPROCS=2 time ./gotrace
2.60 real 4.96 user 0.02 sys
MacBook:gotracer sebi$ GOMAXPROCS=3 time ./gotrace
2.60 real 4.96 user 0.03 sys

Jack Palevich said...

Neat! Glad you liked it.

Byron said...

I managed to improve the speed by about 60% ( on a single core ), bringing the rendering speed down from 2.0s to 1.3s.

Also I noticed that go gets sluggishly slow if pointers are used for the vector math, I could even nail down a single function that will cut the speed in half.

As I intend to post it on the mailing list, and data needs to exchanged, I created a project on gitorious: http://gitorious.org/gotracer.

I mentioned your name everywhere, hoping to make sure authorship is clear. If you truly dislike that please let me know and we will figure out a solution :).

Kind Regards.

Jack Palevich said...

No worries, I intended the code to be open sourced, so you're free to develop it any way you like. Glad to hear it inspired you to write some good go code!