laziness, memoization and inlining
Don Stewart
dons at galois.com
Tue May 13 23:20:11 EDT 2008
sedillard:
> Hi Everybody,
>
> I'm experiencing some undesirable performance behavior, I suspect from
> inlining things that shouldn't be, defeating my memoization attempts.
> I've been experimenting with purely functional 3D modeling code, so a
> mesh is (initially) something like
>
> > type Mesh = Map (Int,Int) (Int,Int)
>
> that is, a function from from an edge to the next edge around the
> face, where an edge is a pair of Ints (the vertices.)
>
> This nice and pure and everything, but its slow to read from. So I
> have another immutable pointer-based representation
>
> > data Edge = Edge { edgeOrg :: Int , edgeSym :: Edge , edgeNext :: Edge }
>
> which is something like a half-edge, for those familiar with such
> things. Its basically a big net made of circular lists that are tied
> together. I do the knot tying stuff to create this thing,
>
> > memoMesh :: Map (Int,Int) (Int,Int) -> Edge Int
> > memoMesh nexts = head $ Map.elems ties
> > where
> > ties = Map.mapWithKey (\ij _ -> make ij) nexts
> > lookup ij = trace "hello" $ fromJust $ Map.lookup ij ties
> > make ij@(i,j) = Edge i (lookup (j,i)) (lookup . fromJust $ Map.lookup ij nexts)
>
> The program first loads the model file and creates the Edge-based mesh
> using the memoMesh function. The result is then captured in the
> closure for the rendering callback in GLUT. When I compile with -O0 I
> see the "hello" traces only during the first drawing. Subsequent
> redraws are fast and output no traces. When I compile with -O1 or -O2,
> the traces get output on every redraw, and its very slow. I suspect
> all of the calls which create the mesh are inlined into the rendering
> callback, effectively rebuilding the mesh on every draw.
Hmm. I wonder if *this* is the no-state-hack at play.
Does -fno-state-hack help?
> I've tried littering NOINLINE pragmas all around, to no avail.
>
> The main function is something like
>
> > main = do
> > initGlut ...
> > rawMesh <- loadMeshFile ...
> > let
> > mesh = memoMesh rawMesh
> > otherstuff = ...
> > display =
> > draw mesh >> amongOtherThings
> > displayCallback $= display
> > glutMainLoop
>
> Can someone help me understand what's going on here? Is there a nice
> solution to this, hopefully a single strategic pragma or something?
Is it possible to boil this down to a program that doesn't use GL?
-- Don
More information about the Glasgow-haskell-users
mailing list