new files
This commit is contained in:
parent
3af7344581
commit
86c034bb8b
1364 changed files with 21352 additions and 0 deletions
|
|
@ -0,0 +1,82 @@
|
|||
import Control.Parallel
|
||||
|
||||
data Task a = Idle | Make a
|
||||
type TaskList a = [a]
|
||||
type Results a = [a]
|
||||
type TaskGroups a = [TaskList a]
|
||||
type WorkerList a = [Worker a]
|
||||
type Worker a = [Task a]
|
||||
|
||||
-- run tasks in parallel and collect their results
|
||||
-- the function doesn't return until all tasks are done, therefore
|
||||
-- finished threads wait for the others to finish.
|
||||
runTasks :: TaskList a -> Results a
|
||||
runTasks [] = []
|
||||
runTasks (x:[]) = x : []
|
||||
runTasks (x:y:[]) = y `par` x : y : []
|
||||
runTasks (x:y:ys) = y `par` x : y : runTasks ys
|
||||
|
||||
-- take a list of workers with different numbers of tasks and group
|
||||
-- them: first the first task of each worker, then the second one etc.
|
||||
groupTasks :: WorkerList a -> TaskGroups a
|
||||
groupTasks [] = []
|
||||
groupTasks xs
|
||||
| allWorkersIdle xs = []
|
||||
| otherwise =
|
||||
concatMap extractTask xs : groupTasks (map removeTask xs)
|
||||
|
||||
-- return a task as a plain value
|
||||
extractTask :: Worker a -> [a]
|
||||
extractTask [] = []
|
||||
extractTask (Idle:_) = []
|
||||
extractTask (Make a:_) = [a]
|
||||
|
||||
-- remove the foremost task of each worker
|
||||
removeTask :: Worker a -> Worker a
|
||||
removeTask = drop 1
|
||||
|
||||
-- checks whether all workers are idle in this task
|
||||
allWorkersIdle :: WorkerList a -> Bool
|
||||
allWorkersIdle = all null . map extractTask
|
||||
|
||||
-- the workers must calculate big sums. the first sum of each worker
|
||||
-- belongs to the first task, and so on.
|
||||
-- because of laziness, nothing is computed yet.
|
||||
|
||||
-- worker1 has 5 tasks to do
|
||||
worker1 :: Worker Integer
|
||||
worker1 = map Make [ sum [1..n*1000000] | n <- [1..5] ]
|
||||
|
||||
-- worker2 has 4 tasks to do
|
||||
worker2 :: Worker Integer
|
||||
worker2 = map Make [ sum [1..n*100000] | n <- [1..4] ]
|
||||
|
||||
-- worker3 has 3 tasks to do
|
||||
worker3 :: Worker Integer
|
||||
worker3 = map Make [ sum [1..n*1000000] | n <- [1..3] ]
|
||||
|
||||
-- worker4 has 5 tasks to do
|
||||
worker4 :: Worker Integer
|
||||
worker4 = map Make [ sum [1..n*300000] | n <- [1..5] ]
|
||||
|
||||
-- worker5 has 4 tasks to do, but starts at the second task.
|
||||
worker5 :: Worker Integer
|
||||
worker5 = [Idle] ++ map Make [ sum [1..n*400000] | n <- [1..4] ]
|
||||
|
||||
-- group the workers' tasks
|
||||
tasks :: TaskGroups Integer
|
||||
tasks = groupTasks [worker1, worker2, worker3, worker4, worker5]
|
||||
|
||||
-- a workshop: take a function to operate the results and a group of tasks,
|
||||
-- execute the tasks showing the process and process the results
|
||||
workshop :: (Show a, Num a, Show b, Num b) => ([a] -> b) -> [[a]] -> IO ()
|
||||
workshop func a = mapM_ doWork $ zip [1..length a] a
|
||||
where
|
||||
doWork (x, y) = do
|
||||
putStrLn $ "Doing task " ++ show x ++ "."
|
||||
putStrLn $ "There are " ++ show (length y) ++ " workers for this task."
|
||||
putStrLn "Waiting for all workers..."
|
||||
print $ func $ runTasks y
|
||||
putStrLn $ "Task " ++ show x ++ " done."
|
||||
|
||||
main = workshop sum tasks
|
||||
Loading…
Add table
Add a link
Reference in a new issue