[Haskell-cafe] announce: Glome.hs raytracer

Derek Elkins derek.a.elkins at gmail.com
Wed Mar 26 18:09:45 EDT 2008

On Wed, 2008-03-26 at 14:45 -0700, Don Stewart wrote:
> jsnow:
> > I have recently posted a haskell port of my ocaml raytracer, Glome:
> > 
> > http://syn.cs.pdx.edu/~jsnow/glome/
> > 
> > It supports spheres and triangles as base primitives, and is able to 
> > parse files in the NFF format used by the standard procedural database 
> > (http://tog.acm.org/resources/SPD/).  It uses a bounding interval 
> > heirarchy acceleration structure, so it can render fairly complicated 
> > scenes in a reasonable amount of time.  Shadows and reflections are 
> > supported, but not specular highlights or refraction.
> > 
> > It's still slower than the ocaml version, but at least they're in the 
> > same ballpark (and a good part of that difference may be inefficiencies 
> > in my BIH traversal).  I would welcome any advice on making it go faster 
> > or use less memory.
> > 
> > I compile the program with "ghc Glome.hs --make -fasm -O2 -threaded 
> > -fglasgow-exts -funbox-strict-fields -fbang-patterns -fexcess-precision 
> > -optc-ffast-math -optc-O2 -optc-mfpmath=sse -optc-msse2".  (I assume the 
> > -optc options don't do anything unless you compile via C.)
> > 
> > Here are some of my current concerns:
> > 
> > -Multi-core parallelism is working, but not as well as I'd expect: I get 
> > about a 25% reduction in runtime on two cores rather than 50%.  I split 
> > the default screen size of 512x512 into 16 blocks, and run "parMap" on 
> > those blocks with a function that turns the screen coordinates of that 
> > block into a list of (x,y,r,g,b) tuples that get drawn as pixels to the 
> > screen through OpenGL by the original thread.
> > 
> > -Memory consumption is atrocious: 146 megs to render a scene that's a 
> > 33k ascii file.  Where does it all go?  A heap profile reports the max 
> > heap size at a rather more reasonable 500k or so.  (My architecture is 
> > 64 bit ubuntu on a dual-core amd.)
> > -Collecting rendering stats is not easy without global variables.  It 
> > occurs to me that it would be neat if there were some sort of write-only 
> > global variables that can be incremented by pure code but can only be 
> > read from within monadic code; that would be sufficient to ensure that 
> > the pure code wasn't affected by the values.  The sorts of things I'm 
> > looking for are the number of calls to "trace" per image, the number of 
> > BIH branches traversed and ray/triangle and ray/sphere intersections per 
> > pixel.   (Disclaimer: I don't really fully understand monads, so I may 
> > be oblivious to an obvious solution.)
> Use a Writer monad to log statistics? Maybe a State monad.
> > -Is there a fast way to cast between Float and Double?  I'm using Float 
> > currently, and the only reason is because that's what the OpenGL api 
> > expects.  I'd like to be able to use either representation, but the only 
> > way to cast that I've found so far is "float_conv x = 
> > fromRational(toRational x)", which is too slow.
> I'd try realToFrac, which should be pretty much optimised away.
> With doubles, ensure you use -fexcess-precision

Unless something has changed, you also want to be compiling with -fvia-C
if you are going to be doing floating point intensive computations.

More information about the Haskell-Cafe mailing list