[Haskell-cafe] Question about STRef

Michael Snoyman michael at snoyman.com
Thu Jan 26 13:22:08 UTC 2017

On Thu, Jan 26, 2017 at 3:15 PM, Michael Snoyman <michael at snoyman.com>

> On Thu, Jan 26, 2017 at 3:05 PM, Johannes Waldmann <
> johannes.waldmann at htwk-leipzig.de> wrote:
>> What Michael did not mention in the mail, but it's in his code:
>> numerals defaulted to Integer, and the story changes (somewhat)
>> if we force Int.
>> I updated my measurements:
>> http://www.imn.htwk-leipzig.de/~waldmann/etc/mob/
>> and ghc-8 looks better now - but not quite wins.
>> > there's still some more low hanging fruit here
>> ... for whom? What could we reasonably expect of the compiler here?
>> It could do the strictification? the unboxing?
>> It certainly could not replace Integer by Int,
>> since the range of numerical values has no obvious bound.
>> But then, all these Integers are small, but we pay quite an overhead
>> (for represeting Int as Integer) which has increased for current ghcs?
> I meant that, if someone wanted to bring down allocations significantly, I
> would think there's still room for optimization. I was not commenting on
> what GHC should or shouldn't be capable of doing here. It would certainly
> be nice, for example, if it was capable of noticing the strictness involved
> and automatically unbox the STRefs, but that would be quite a feat.
> I didn't investigate further myself, so I could be mistaken about the
> possibility to further reduce allocations. It was just a guess (thus the "I
> think").
> Michael

As an example, upon reviewing the code I realized it was unnecessarily
allocating a reference in the case of `k <= 0`. Fixing that reduces
allocations to 800MB (from 1.9GB). This was a pretty easy change to make. A
more involved change would be to share a mutable vector of larger size
instead of allocating a new reference each time. I'm now intrigued enough
by the problem that I'll probably do that next :)

#!/usr/bin/env stack
-- stack --resolver lts-7.14 --install-ghc exec --package
mutable-containers -- ghc -O2 -with-rtsopts=-s
import Control.Monad.ST
import Data.Mutable

a :: Int
  -> ST s Int
  -> ST s Int
  -> ST s Int
  -> ST s Int
  -> ST s Int
  -> ST s Int
a k x1 x2 x3 x4 x5
    | k <= 0 = do
        x3' <- x3
        x4' <- x4
        return $! x3' + x4'
    | otherwise = do
        kRef <- fmap asURef $ newRef k

        let b = do
                k0 <- readRef kRef
                let k1 = k0 - 1
                writeRef kRef k1
                a k1 b x1 x2 x3 x4

        x5' <- x5
        b' <- b
        return $! x5' + b'

main = print $ runST $ a
    (return 1)
    (return (-1))
    (return (-1))
    (return 1)
    (return 0)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20170126/7b15039b/attachment.html>

More information about the Haskell-Cafe mailing list