[Haskell-cafe] announce: Glome.hs raytracer
dons at galois.com
Wed Mar 26 17:45:08 EDT 2008
> I have recently posted a haskell port of my ocaml raytracer, 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
More information about the Haskell-Cafe