Haskell version of ray tracer code is much slower than the original ML

In odd spare moments, I took John Harrops simple ray tracer[1] & made a Haskell version: http://www.kantaka.co.uk/cgi-bin/darcsweb.cgi?r=ray darcs get http://www.kantaka.co.uk/darcs/ray It's pretty much a straight translation into idiomatic Haskell (as far as my Haskell is idiomatic anyway). Unfortunately, it's a lot slower than the ML version, despite turning all the optimisation options up as far as they'll go. Profiling suggests that much of the time is spent in the intersection' function, and that the code is creating (and garbage collecting) an awful lot of (-|) vector subtraction thunks. Trying to make intersection' or ray_sphere stricter (with seq) appears to have no effect whatsoever: the output of -ddump-simpl is unchanged (with the arguments all staying lazy). Am I missing anything obvious? I don't want to carry out herculean code rewriting efforts: that wouldn't really be in the spirit of the thing. cheers, Phil [1] http://www.ffconsultancy.com/languages/ray_tracer/comparison.html -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt

On Thu, 21 Jun 2007 11:55:04 +0100
Philip Armstrong
In odd spare moments, I took John Harrops simple ray tracer[1] & made a Haskell version:
http://www.kantaka.co.uk/cgi-bin/darcsweb.cgi?r=ray
darcs get http://www.kantaka.co.uk/darcs/ray
It's pretty much a straight translation into idiomatic Haskell (as far as my Haskell is idiomatic anyway).
Unfortunately, it's a lot slower than the ML version, despite turning all the optimisation options up as far as they'll go. Profiling suggests that much of the time is spent in the intersection' function, and that the code is creating (and garbage collecting) an awful lot of (-|) vector subtraction thunks. Trying to make intersection' or ray_sphere stricter (with seq) appears to have no effect whatsoever: the output of -ddump-simpl is unchanged (with the arguments all staying lazy).
Am I missing anything obvious? I don't want to carry out herculean code rewriting efforts: that wouldn't really be in the spirit of the thing.
cheers, Phil
[1] http://www.ffconsultancy.com/languages/ray_tracer/comparison.html
With a very minor change (attached), your Haskell ray tracer runs faster than the OCaml version on my machine. There's a bug GHC where it does not recognize -fexcess-precision at the command line, but an OPTIONS_GHC pragma does work correctly. This flag brings runtime from about 60s to 20s on my machine (Core Duo 1.83GHz) -- compared to 25s for the OCaml version. Results (each run twice to avoid OS buffering of the executable): % uname -a Linux localhost 2.6.22-rc4 #5 SMP Tue Jun 19 17:29:36 CDT 2007 i686 Genuine Intel(R) CPU T2400 @ 1.83GHz GenuineIntel GNU/Linux % ghc --version The Glorious Glasgow Haskell Compilation System, version 6.6 % ocamlopt -version 3.09.3 % (time ./hsray) | md5sum ./hsray 20.23s user 0.03s system 98% cpu 20.536 total 63a359e5c388f2004726d83d4337f56b - % (time ./hsray) | md5sum ./hsray 19.74s user 0.07s system 99% cpu 19.907 total 63a359e5c388f2004726d83d4337f56b - % (time ./mlray) | md5sum ./mlray 25.55s user 0.00s system 98% cpu 25.831 total 63a359e5c388f2004726d83d4337f56b - % (time ./mlray) | md5sum ./mlray 25.63s user 0.04s system 98% cpu 25.981 total 63a359e5c388f2004726d83d4337f56b - Cheers, Spencer Janssen
participants (2)
-
Philip Armstrong
-
Spencer Janssen