Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."
Today's Topics:
1. Re: Strange "Not in scope" error message (Matthew Moppett)
2. Re: missing parallelism (Maurizio Vitale)
3. Re: missing parallelism (Grzegorz Milka)
4. Re: missing parallelism ([email protected])
----------------------------------------------------------------------
Message: 1
Date: Sat, 25 Apr 2015 08:27:22 +0700
From: Matthew Moppett <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] Strange "Not in scope" error message
Message-ID:
<camlejzasv7zgrfd7f2123pdxl5jeesjrejetznoqtnfvsni...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"
So I did. That's kind of embarrassing -- I could swear I stared at that
error message for ages trying to work out if there were any typos like that
and never saw it. Thanks for pointing it out.
On Sat, Apr 25, 2015 at 12:14 AM, Francesco Ariis <[email protected]> wrote:
> On Fri, Apr 24, 2015 at 11:49:15PM +0700, Matthew Moppett wrote:
> > Perhaps you meant one of these:
> > `C.isEmptyMVar' (imported from Control.Concurrent),
>
> Haskell is case sensitive, isEmptyMVar is different from isEmptyMvar
> (lowercase v)
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://mail.haskell.org/pipermail/beginners/attachments/20150425/e2971acd/attachment-0001.html>
------------------------------
Message: 2
Date: Fri, 24 Apr 2015 21:40:55 -0400
From: Maurizio Vitale <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] missing parallelism
Message-ID:
<CAAeLbQ+wm0GJZ-yZON93-B10g4h=h3uri0kjhttcynj3kwh...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8
Not even with this simplified version, I can get two async running on
separate threads.
I must be missing something really basic:
{-# LANGUAGE UnicodeSyntax #-}
{-# LANGUAGE TupleSections #-}
import Control.Concurrent.Async (async, waitBoth)
sumEuler :: Int ? Int
sumEuler = sum . map euler . mkList
where
mkList n = [1..n-1]
euler n = length (filter (relprime n) [1..n-1])
where
relprime x y = gcd x y == 1
p ? IO Int
p = return $ sumEuler 5000
main ? IO()
main = do
a ? async p
b ? async p
(av, bv) ? waitBoth a b
print (av,bv)
On Fri, Apr 24, 2015 at 7:06 PM, Maurizio Vitale <[email protected]> wrote:
> You're right, without the show, no work is done.
> But I'm puzzled. I thought waitAny would have caused one task to be executed.
> If that doesn't wait for the async to compute a value (and not some
> thunk) I don't see how to use asyncs, so I'm obviously missing
> something.
> How can I force deeper evaluation?
> [in the end p would be a full parser, so whatever it is needed to
> cause the parsing needs to be done outside of it]
>
> On Fri, Apr 24, 2015 at 10:44 AM, <[email protected]> wrote:
>> On 24/04/2015 14:21, Maurizio Vitale wrote:
>>>
>>> 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)
>>> _______________________________________________
>>> Beginners mailing list
>>> [email protected]
>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>
>>
>> Hello,
>>
>> I don't have an Haskell environnement at hand, but my advice is to search
>> for when your Async/eulerSum calls are evaluated.
>> For example try to remove this line -- putStrLn $ foldr ((++) . show ) ""
>> f
>> Does your program still compute something ? If no that's because your sum is
>> evaluated due to the show and not due to your async.
>>
>> t <- async $ (i,) <$> task
>>
>> Your async will try to compute (i,eulerSum) but you never force the
>> computation of the eulersum inside the async, so the async take no time and
>> return quickly.
>> Instead of this type [Async (Int, b)] you should aim for this one [(Int,
>> Async b)]
>>
>> Let me know if that helps you.
>>
>> Regards,
>> Romain
>>
>> _______________________________________________
>> Beginners mailing list
>> [email protected]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
>
> On Fri, Apr 24, 2015 at 1:44 PM, <[email protected]> wrote:
>> On 24/04/2015 14:21, Maurizio Vitale wrote:
>>>
>>> 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)
>>> _______________________________________________
>>> Beginners mailing list
>>> [email protected]
>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>
>>
>> Hello,
>>
>> I don't have an Haskell environnement at hand, but my advice is to search
>> for when your Async/eulerSum calls are evaluated.
>> For example try to remove this line -- putStrLn $ foldr ((++) . show ) ""
>> f
>> Does your program still compute something ? If no that's because your sum is
>> evaluated due to the show and not due to your async.
>>
>> t <- async $ (i,) <$> task
>>
>> Your async will try to compute (i,eulerSum) but you never force the
>> computation of the eulersum inside the async, so the async take no time and
>> return quickly.
>> Instead of this type [Async (Int, b)] you should aim for this one [(Int,
>> Async b)]
>>
>> Let me know if that helps you.
>>
>> Regards,
>> Romain
>>
>> _______________________________________________
>> Beginners mailing list
>> [email protected]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
------------------------------
Message: 3
Date: Sat, 25 Apr 2015 10:25:29 +0200
From: Grzegorz Milka <[email protected]>
To: [email protected]
Subject: Re: [Haskell-beginners] missing parallelism
Message-ID: <[email protected]>
Content-Type: text/plain; charset="windows-1252"
As far as I can tell there's nothing wrong with your code. My hypothesis
is that Haskell optimizes call to sumEuler 5000 by calling it only once
in one thread. Here's why I think so:
The program I used for debugging this is:
import Control.Concurrent.Async (async, wait)
import System.IO.Unsafe (unsafePerformIO)
sumEuler :: Int -> Int
sumEuler = sum . map euler . mkList
where
mkList n = seq (unsafePerformIO (putStrLn
"Calculating")) [1..n-1]
euler n = length (filter (relprime n) [1..n-1])
where
relprime x y = gcd x y == 1
p :: Int -> IO Int
p b = return $! sumEuler b
p5000 :: IO Int
p5000 = return $ sumEuler 5000
main :: IO ()
main = do
a <- async $ p5000
b <- async $ p5000
av <- wait a
bv <- wait b
print (av,bv)
The two main modification are adding a debugging message "Calculating"
when a list [1..(n-1)] is evaluated. The second one is making p into a
function. Notice that it uses strict application ($! - check how it
works with simple $). I will use that function in further examples.
Running this program with "time ./Test 2 +RTS -ls -N2" gives me:
Calculating
(7598457,7598457)
real 0m3.752s
user 0m3.833s
sys 0m0.211s
Just to be sure I have almost the same time when doing only one
computation with:
main :: IO ()
main = do
a <- async $ p5000
av <- wait a
print av
So it seems like the value returned by p5000 is computed only once. GHC
might be noticing that p5000 will always return the same value and might
try cache it or memoize it. If this hypothesis is right then calling
sumEuler with two different values should run in two different threads.
And indeed it is so:
main :: IO ()
main = do
a <- async $ p 5000
b <- async $ p 4999
av <- wait a
bv <- wait b
print (av,bv)
Gives:
Calculating
Calculating
(7598457,7593459)
real 0m3.758s
user 0m7.414s
sys 0m0.064s
So it runs in two threads just as expected. The strict application ($!)
here is important. Otherwise it seems that the async thread returns a
thunk and the evaluation happens in print (av, bv) which is evaluated in
a single thread. Also the fact that p5000 is a top level binding is
important. When I do:
main :: IO ()
main = do
a <- async $ p 5000
b <- async $ p 5000
av <- wait a
bv <- wait b
print (av,bv)
I get no optimization (GHC 7.6.3).
Best,
Greg
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://mail.haskell.org/pipermail/beginners/attachments/20150425/7c2293b6/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL:
<http://mail.haskell.org/pipermail/beginners/attachments/20150425/7c2293b6/attachment-0001.sig>
------------------------------
Message: 4
Date: Sat, 25 Apr 2015 12:25:25 +0200
From: [email protected]
To: [email protected]
Subject: Re: [Haskell-beginners] missing parallelism
Message-ID: <[email protected]>
Content-Type: text/plain; charset="utf-8"; Format="flowed"
Again, does you program compute something if you remove the print ? no ?
So you have a stricness/laziness problem.
Let's see together what does mean p :: IO Int
By its signature *p* assure you that *when evaluate* it will return you
an *IO Int*.
By Its signature *IO Int* assure you that*when evaluated* it will return
you an *Int*.
By Its signature *Int* assure you that *when evaluated* it will return
you an *Int* but this time, a *strict one* as there is *nothing left to
evaluate*
ok so now, what does mean *async p* ? Async will *force the evaluation*
of the *IO* but that is all.
so : async p = async $ return $ sumEuler 5000 :: IO Int
so : a <- async p = a <- async $ return $ sumEuler 5000 :: IO Int -> Int
so : a = sumEuler 5000 :: Int
So *a* promise you an Int (but a lazy one) so where has it been
evaluated ? Nowhere, the evaluation of *a *never happens anywhere. So
you are missing a final step, the last evaluation of *a* (which does
happen after, due to the print)
How to solve that ? Force the evaluation of sumEuler 5000 inside the IO
monad, so it will be evaluated at the same time that the async will
evaluate the IO. (In order to evaluate something you have to force a
data depedency)
p :: IO int
p = return $! sumEuler 5000
or
p :: IO int
p = let x = sumEuler in x `seq` return x
This should solve your problem of everything running on a single
thread/core, because now you force the evaluation of sumEuler inside p
and not inside the print.
Now, be aware that as sumEuler is pure and that 5000 is a static value
(also pure), sumEuler 5000 needs to be computed only once. The program
is free to optimize away further calls to sumEuler 5000 by caching the
value.
But at least you shoud see this evaluation happening on multiples cores.
Regards,
Romain
On 25/04/2015 03:40, Maurizio Vitale wrote:
> Not even with this simplified version, I can get two async running on
> separate threads.
> I must be missing something really basic:
>
> {-# LANGUAGE UnicodeSyntax #-}
> {-# LANGUAGE TupleSections #-}
>
> import Control.Concurrent.Async (async, waitBoth)
>
> sumEuler :: Int ? Int
> sumEuler = sum . map euler . mkList
> where
> mkList n = [1..n-1]
> euler n = length (filter (relprime n) [1..n-1])
> where
> relprime x y = gcd x y == 1
>
> p ? IO Int
> p = return $ sumEuler 5000
>
> main ? IO()
> main = do
> a ? async p
> b ? async p
> (av, bv) ? waitBoth a b
> print (av,bv)
>
> On Fri, Apr 24, 2015 at 7:06 PM, Maurizio Vitale <[email protected]> wrote:
>> You're right, without the show, no work is done.
>> But I'm puzzled. I thought waitAny would have caused one task to be executed.
>> If that doesn't wait for the async to compute a value (and not some
>> thunk) I don't see how to use asyncs, so I'm obviously missing
>> something.
>> How can I force deeper evaluation?
>> [in the end p would be a full parser, so whatever it is needed to
>> cause the parsing needs to be done outside of it]
>>
>> On Fri, Apr 24, 2015 at 10:44 AM, <[email protected]> wrote:
>>> On 24/04/2015 14:21, Maurizio Vitale wrote:
>>>> 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)
>>>> _______________________________________________
>>>> Beginners mailing list
>>>> [email protected]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>>
>>> Hello,
>>>
>>> I don't have an Haskell environnement at hand, but my advice is to search
>>> for when your Async/eulerSum calls are evaluated.
>>> For example try to remove this line -- putStrLn $ foldr ((++) . show ) ""
>>> f
>>> Does your program still compute something ? If no that's because your sum is
>>> evaluated due to the show and not due to your async.
>>>
>>> t <- async $ (i,) <$> task
>>>
>>> Your async will try to compute (i,eulerSum) but you never force the
>>> computation of the eulersum inside the async, so the async take no time and
>>> return quickly.
>>> Instead of this type [Async (Int, b)] you should aim for this one [(Int,
>>> Async b)]
>>>
>>> Let me know if that helps you.
>>>
>>> Regards,
>>> Romain
>>>
>>> _______________________________________________
>>> Beginners mailing list
>>> [email protected]
>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>
>> On Fri, Apr 24, 2015 at 1:44 PM, <[email protected]> wrote:
>>> On 24/04/2015 14:21, Maurizio Vitale wrote:
>>>> 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)
>>>> _______________________________________________
>>>> Beginners mailing list
>>>> [email protected]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>>
>>> Hello,
>>>
>>> I don't have an Haskell environnement at hand, but my advice is to search
>>> for when your Async/eulerSum calls are evaluated.
>>> For example try to remove this line -- putStrLn $ foldr ((++) . show ) ""
>>> f
>>> Does your program still compute something ? If no that's because your sum is
>>> evaluated due to the show and not due to your async.
>>>
>>> t <- async $ (i,) <$> task
>>>
>>> Your async will try to compute (i,eulerSum) but you never force the
>>> computation of the eulersum inside the async, so the async take no time and
>>> return quickly.
>>> Instead of this type [Async (Int, b)] you should aim for this one [(Int,
>>> Async b)]
>>>
>>> Let me know if that helps you.
>>>
>>> Regards,
>>> Romain
>>>
>>> _______________________________________________
>>> Beginners mailing list
>>> [email protected]
>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://mail.haskell.org/pipermail/beginners/attachments/20150425/ef526631/attachment.html>
------------------------------
Subject: Digest Footer
_______________________________________________
Beginners mailing list
[email protected]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
------------------------------
End of Beginners Digest, Vol 82, Issue 35
*****************************************