[Haskell-cafe] STM unperformance
Wojtek Narczyński
wojtek at power.com.pl
Thu Feb 18 14:25:48 UTC 2016
Dear list,
I create four haskell threads, each performs disjoint STM transactions.
The more system threads I add, the slower the program runs. With four
system threads the performance is 14% of the nonparallel run.
What is going on?
$ ghc -v
Glasgow Haskell Compiler, Version 7.10.3, stage 2 booted by GHC version
7.8.4
$ ghc -O2 -threaded test-stm.hs
$ time ./test-stm +RTS -N1
real 1.843s
$ time ./test-stm +RTS -N2
real 7.469s
$ time ./test-stm +RTS -N3
real 9.640s
$ time ./test-stm +RTS -N4
real 13.144s
$ cat test-stm.hs
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Monad
import Control.Concurrent
import Control.Concurrent.STM
import Control.Concurrent.STM.Stats
import System.IO.Unsafe
-- Copied from GHC docs
children :: MVar [MVar ()]
children = unsafePerformIO (newMVar [])
waitForChildren :: IO ()
waitForChildren = do
cs <- takeMVar children
case cs of
[] -> return ()
m:ms -> do
putMVar children ms
takeMVar m
waitForChildren
forkChild :: IO () -> IO ThreadId
forkChild io = do
mvar <- newEmptyMVar
childs <- takeMVar children
putMVar children (mvar:childs)
forkFinally io (\_ -> putMVar mvar ())
-- Test case
main = do
forkChild $ newTVarIO 0 >>= incrManyTimes "thread1"
forkChild $ newTVarIO 0 >>= incrManyTimes "thread2"
forkChild $ newTVarIO 0 >>= incrManyTimes "thread3"
forkChild $ newTVarIO 0 >>= incrManyTimes "thread4"
waitForChildren
dumpSTMStats -- Confirms no conflicts
incrManyTimes :: String -> TVar Int -> IO ()
incrManyTimes l = incrRec (1000000 :: Int) where
incrRec n v | n == 0 = pure ()
| otherwise = trackNamedSTM l (modifyTVar v (+1)) >>
incrRec (n-1) v
--
Wojtek
More information about the Haskell-Cafe
mailing list