unsafePerformIO and NOINLINE Pragma

Hi! I want to analyse the laziness of a data structure. To check how many nodes are constructed I use a global counter. counter :: IORef Int counter = unsafePerformIO (newIORef 0) This counter is increased every time the constructor is called by redefining the constructor OBDD as follows. oBDD low var high = seq (unsafePerformIO (modifyIORef counter (+1))) (OBDD low var high) This works fine. When I compile with optimisations the counter is always set to one no matter how many nodes are constructed. I thought this would be caused by inlining. Therefore I have added two NOINLINE pragmata. {-# NOINLINE counter #-} {-# NOINLINE oBDD #-} Although the counter doesn't work. Is there another optimisation that can cause harm? Is there something wrong with the pragmata? best regards, Jan

Hi,
Hi!
I want to analyse the laziness of a data structure. To check how many nodes are constructed I use a global counter.
counter :: IORef Int counter = unsafePerformIO (newIORef 0)
This counter is increased every time the constructor is called by redefining the constructor OBDD as follows.
oBDD low var high = seq (unsafePerformIO (modifyIORef counter (+1))) (OBDD low var high)
This works fine. When I compile with optimisations the counter is always set to one no matter how many nodes are constructed. I thought this would be caused by inlining. Therefore I have added two NOINLINE pragmata.
{-# NOINLINE counter #-} {-# NOINLINE oBDD #-}
Although the counter doesn't work. Is there another optimisation that can cause harm? Is there something wrong with the pragmata?
Two comments: 1. There are other optimisations than inlining that can break sharing, e.g. common subexpression elimination, full-laziness-transformation. 2. I tested the following: {-# NOLINE counter #-} {-# INLINE oBDD #-} then the counter "seems" to work correct. In my opinion oBDD is an abstraction and can always be inlined. Cheer, David

Am Dienstag, 13. September 2005 16:13 schrieb David Sabel:
Hi,
Hi!
I want to analyse the laziness of a data structure. To check how many nodes are constructed I use a global counter.
counter :: IORef Int counter = unsafePerformIO (newIORef 0)
This counter is increased every time the constructor is called by redefining the constructor OBDD as follows.
oBDD low var high = seq (unsafePerformIO (modifyIORef counter (+1))) (OBDD low var high)
This works fine. When I compile with optimisations the counter is always set to one no matter how many nodes are constructed. I thought this would be caused by inlining. Therefore I have added two NOINLINE pragmata.
{-# NOINLINE counter #-} {-# NOINLINE oBDD #-}
Although the counter doesn't work. Is there another optimisation that can cause harm? Is there something wrong with the pragmata?
Two comments: 1. There are other optimisations than inlining that can break sharing, e.g. common subexpression elimination, full-laziness-transformation.
2. I tested the following:
{-# NOLINE counter #-} {-# INLINE oBDD #-}
then the counter "seems" to work correct. In my opinion oBDD is an abstraction and can always be inlined.
Sadly this solution doesn't work in my environment. The counter is always set to 2 while it should be something around 15.000. I think it's not worth going into detail of the transformations for me thus I will check the number of nodes without optimisations and the performance with optimisations. Thanks anyway.
participants (2)
-
David Sabel
-
Jan Christiansen