
My program which should use constant stack/heap is using a ton of heap. I profiled with -hd and the guy that's eating all the heap is BLACKHOLE. What does this mean? -- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume

The code that I was profiling that exhibited this behavior basically looked like: do t <- read a file r <- create an io ref mapM_ (\c -> do ... modifyIORef r <E> ) t but when i replace: modifyIORef r <E> with v <- readIORef r writeIORef r $! <E> I no longer run into this heap problem and the program runs much more quickly. even if I use (modifyIORef f (\x -> id $! <E> x)), which I thought would fix it, there is still a heap problem. looking in the ghc sources, modifyIORef is defined as: modifyIORef ref f = writeIORef ref . f =<< readIORef ref so i don't understand what's going on here. -- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume On Fri, 18 Apr 2003, Hal Daume III wrote:
My program which should use constant stack/heap is using a ton of heap. I profiled with -hd and the guy that's eating all the heap is BLACKHOLE. What does this mean?
-- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume

Hal Daume III writes: | but when i replace: | | modifyIORef r <E> | | with | | v <- readIORef r | writeIORef r $! <E> | | I no longer run into this heap problem and the program runs much | more quickly. Yes. When (f $! x) is evaluated, first x is forced to Weak Head Normal Form, and then (f x) is evaluated. In this case, (writeIORef r $! <E>) is evaluated early, thanks to the strict sequencing of actions in the IO monad, so <E> is evaluated early too. You should get the same result with modifyIORef r $! <E> | even if I use (modifyIORef f (\x -> id $! <E> x)), which I thought | would fix it, there is still a heap problem. That's different, because the application of ($!) does not get caught up in the sequencing of actions. In answer to the subject line, modifyIORef updates a reference strictly, but the thing the reference refers to may be a suspended computation. In this case, after the modifyIORef the reference points to a suspension of (\x -> id $! <E> x) the_thing_previously_pointed_to and the evaluation hasn't yet reached the ($!).

On Sat, Apr 19, 2003 at 12:29:13PM +1200, Tom Pledger wrote:
You should get the same result with
modifyIORef r $! <E>
But this will only force evaluation of the function passed to modifyIORef, won't it? Best regards, Tom

Tomasz Zielonka writes: | On Sat, Apr 19, 2003 at 12:29:13PM +1200, Tom Pledger wrote: | > You should get the same result with | > | > modifyIORef r $! <E> | | But this will only force evaluation of the function passed to | modifyIORef, won't it? You're right. My mistake, sorry. <E> is already in Weak Head Normal Form (because it's a function), so the ($!) has no effect.

Hal Daume III writes: | My program which should use constant stack/heap is using a ton of | heap. I profiled with -hd and the guy that's eating all the heap | is BLACKHOLE. What does this mean? AFAIK it's a way of detecting some infinite loops. The BLACKHOLE cells are the ones you're in the midst of evaluating, so if you try to reenter any of them, you're provably going around in circles. When the evaluation gets to the end of the chain of cells, and retracts, they cease to be BLACKHOLEs. As you go on to mention in your next message, this can happen when a program turns out to be lazier than you expected.
participants (3)
-
Hal Daume III
-
Tom Pledger
-
Tomasz Zielonka