[Haskell-beginners] missing parallelism

Maurizio Vitale mrz.vtl at gmail.com
Fri Apr 24 12:21:12 UTC 2015


G'day,
  I have a test code that I compile with ghc -threaded -eventlog
-rtsopts --make parallel.hs and run with ./parallel 2 +RTS -ls -N4 on
a laptop with 4 physical cores. I would expect activities in two
threads, but threadscope shows only one active thread.
Can somebody explain me the program's behaviour?

Thanks a lot

   Maurizio

{-# LANGUAGE UnicodeSyntax #-}
{-# LANGUAGE TupleSections #-}

import Control.Applicative
import Control.Concurrent.Async (async, waitAny, Async)
import Data.List (delete, sortBy)
import Data.Ord (comparing)
import System.CPUTime
import System.Environment
import GHC.Conc (numCapabilities)

concurrentlyLimited :: Int -> [IO a] -> IO [a]
concurrentlyLimited n tasks = concurrentlyLimited' n (zip [0..] tasks) [] []

concurrentlyLimited' ∷ Int               -- ^ number of concurrent evaluations
                     → [(Int, IO b)]     -- ^ still to run (ordered by
first element)
                     → [Async (Int,b)]   -- ^ currently running
                     → [(Int,b)]         -- ^ partial results (ordered
by first element)
                     → IO [b]
concurrentlyLimited' _ [] [] results = return . map snd $ sortBy
(comparing fst) results
concurrentlyLimited' 0 todo ongoing results = do
    (task, newResult) <- waitAny ongoing
    concurrentlyLimited' 1 todo (delete task ongoing) (newResult:results)

concurrentlyLimited' _ [] ongoing results = concurrentlyLimited' 0 []
ongoing results
concurrentlyLimited' n ((i, task):otherTasks) ongoing results = do
    t <- async $ (i,) <$> task
    concurrentlyLimited' (n-1) otherTasks (t:ongoing) results

euler :: Int → Int
euler n = length (filter (relprime n) [1..n-1])
          where
            relprime x y = gcd x y == 1

sumEuler :: Int → Int
sumEuler = sum . (map euler) . mkList
           where
             mkList n = [1..n-1]

p ∷ IO Int
p = return $ sumEuler 3000

numThreads ∷ [String] → IO Int
numThreads [] = return numCapabilities
numThreads [cores] = return $ read cores

main ∷ IO()
main = do
  threads ← getArgs >>= numThreads
  putStrLn $ "Running up to " ++ show threads ++ " threads in parallel
(on " ++ show numCapabilities ++ " cores)"
  startTime ← getCPUTime
  f ← concurrentlyLimited threads $ replicate 10 p
  endTime ← getCPUTime
  putStrLn $ foldr  ((++) . show ) ""  f
  putStrLn $ "Evaluation took " ++ show (fromIntegral (endTime -
startTime) / 1000000000000∷Double)


More information about the Beginners mailing list