1votos

STM vs Bloqueos en Haskell

por josejuan hace 6 años

Con MVar "sólo" es 3.2 veces más lento que la "canónica" de C# (debido seguramente a mi inexperiencia con Haskell).

A raíz de la fructífera conversación surgida en el desafío de "La tela de araña", se propone comparar las estrategias STM vs Bloqueos más fondo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{-# LANGUAGE BangPatterns #-} 
import Control.Concurrent 
import Control.Monad 
import System.Environment(getArgs) 
import Data.Int 
 
addMany :: MVar Int64 -> [MVar Int64] -> Int64 -> Int64 -> IO () 
addMany !c !a !n !i = forM_ [1..i] (\_ -> forM_ a (shW n)) >> shW 1 c 
 
shR = readMVar 
shW !k !r = 
  do x' <- takeMVar r 
     putMVar r $! (x' + k) -- <<<< ¡¡¡¡ éste es el culpable de todo !!!! 
 
main = do 
  (niters': nvars': nthreads': _) <- getArgs 
  let (niters, nvars, nthreads) = (read niters', read nvars', read nthreads') 
  c <- newMVar 0 
  a <- mapM (\_ -> newMVar 0) [1..nvars] 
  mapM_ (\k -> forkIO $ addMany c a k niters) [1..nthreads] 
  waitTo c nthreads 
  z <- mapM shR a 
  putStrLn $ show $ sum z 
 
-- ¿no hay forma de hacer un "join" entre procesos? 
waitTo !c !nth = do 
  threadDelay (100*1000) 
  w' <- shR c 
  if w' == nth 
    then return () 
    else waitTo c nth 
 
 
 
 
== compilando como ============= 
 
$ ghc -O2 -threaded -rtsopts -funfolding-use-threshold=16 counting.hs 
$ time -f "%E, %M" ./counting 100000 1000 6 +RTS -N6 -H128m 
2100000000 
0:10.22, 137068 

Comenta la solución

Tienes que identificarte para poder publicar tu comentario.