{- Parallelitaet in funktionalen Programmiersprachen, Einfache Haskell-Beispielprogramme -} module Main where import Data.Time.Clock (diffUTCTime, getCurrentTime) import System.Environment (getArgs) import System.Random (StdGen, getStdGen, randoms) import Data.List (transpose) import Control.Parallel (par,pseq) import Strategies usage :: String usage = "1. Arg.: Versionen - 0 (binom), 1 (quicksort), 2 (qsort/parlist) \n" ++ "2. Arg.: Eingabegroesse" -- Hauptprogramm (Testumgebung) main :: IO () main = do args <- getArgs if null args then putStrLn usage else do let v = read (head args) let n = read (head (tail args)) putStrLn $ "Input Size: " ++ show n input <- randomInts n `fmap` getStdGen start <- getCurrentTime let result = test v n input sforce result $ putStrLn ("Length of Result List: " ++ (show (length result))) end <- getCurrentTime putStrLn (show (end `diffUTCTime` start) ++ " elapsed." ) {- Beispielaufrufe: Binomialkoeffizienten: examplePar 0 30 +RTS -ls -N2 bzw. -N1 Quicksort: examplePar 1 100000 +RTS -ls -N2 bzw. -N1 -} test :: Int -> Int -> [Int] -> [Int] test v n input = case v of 0 -> [binom n (n `div` 2)] 1 -> qsort input 2 -> qsort2 input randomInts :: Int -> StdGen -> [Int] randomInts k g = let result = take k (randoms g) in length result `pseq` result -- Binomialkoeffizienten binom :: Int -> Int -> Int binom n k | k == 0 && n >= 0 = 1 | n < k && n >= 0 = 0 | k <= n && k >= 0 = b1 + b2 `using` strat | otherwise = error "negative parameters" where b1 = binom (n-1) k b2 = binom (n-1) (k-1) strat _ = b1 `par` b2 `pseq` () -- Quicksort qsort :: (Ord a, NFData a) => [a] -> [a] qsort [] = [] qsort (x:xs) = -- length smalls `par` length bigs `pseq` (smalls ++ x : bigs) `using` strat where smalls = qsort [y | y<-xs, y <=x] bigs = qsort [y | y<-xs, y > x] strat res = rnf bigs `par` rnf smalls qsort2 :: (Ord a, NFData a) => [a] -> [a] qsort2 [] = [] qsort2 (x:xs) = -- length smalls `par` length bigs `pseq` combine ([smalls, bigs] `using` parList rnf) where smalls = qsort [y | y<-xs, y <=x] bigs = qsort [y | y<-xs, y > x] combine (xs:ys:_) = xs ++ x:ys