Zoeken…


parameters

Type / Functie Detail
data Eval a Eval is een monade die het gemakkelijker maakt om parallelle strategieën te definiëren
type Strategy a = a -> Eval a een functie die een parallelle evaluatiestrategie belichaamt. De functie doorloopt (delen van) zijn argument, en evalueert subexpressies parallel of in volgorde
rpar :: Strategy a vonkt zijn argument (voor parallelle evaluatie)
rseq :: Strategy a evalueert zijn argument voor de normale vorm van een zwak hoofd
force :: NFData a => a -> a evalueert de hele structuur van zijn argument, reduceert het tot de normale vorm, voordat het argument zelf wordt teruggestuurd. Het wordt geleverd door de module Control.DeepSeq

Opmerkingen

Het boek van Simon Marlow , Concurrent and Parallel Programming in Haskell, is uitstekend en omvat een groot aantal concepten. Het is ook zeer toegankelijk voor zelfs de nieuwste Haskell-programmeur. Het wordt sterk aanbevolen en is gratis beschikbaar in PDF of online.

Parallel versus gelijktijdig

Simon Marlow zegt het beste :

Een parallel programma is een programma dat een veelvoud van computerhardware (bijv. Meerdere processorcores) gebruikt om een berekening sneller uit te voeren. Het doel is om eerder tot het antwoord te komen, door verschillende delen van de berekening te delegeren aan verschillende processoren die tegelijkertijd worden uitgevoerd.

Concurrency is daarentegen een programmastructureringstechniek waarbij er meerdere controledraden zijn. Conceptueel worden de draden van controle "tegelijkertijd" uitgevoerd; dat wil zeggen, de gebruiker ziet hun effecten verweven. Of ze daadwerkelijk tegelijkertijd uitvoeren of niet is een implementatiedetail; een gelijktijdig programma kan worden uitgevoerd op een enkele processor via interleaved uitvoering of op meerdere fysieke processors.

Zwak hoofd Normale vorm

Het is belangrijk om te weten hoe luie evaluatie werkt. Het eerste deel van dit hoofdstuk geeft een sterke introductie in WHNF en hoe dit verband houdt met parallelle en gelijktijdige programmering.

De Eval Monad

Parallellisme in Haskell kan worden uitgedrukt met behulp van de Eval Monad van Control.Parallel.Strategies , met behulp van de functies rpar en rseq (onder andere).

f1 :: [Int]
f1 = [1..100000000]

f2 :: [Int]
f2 = [1..200000000]

main = runEval $ do
  a <- rpar (f1) -- this'll take a while...
  b <- rpar (f2) -- this'll take a while and then some...
  return (a,b)

main uitvoeren hierboven wordt onmiddellijk uitgevoerd en "geretourneerd", terwijl de twee waarden a en b op de achtergrond worden berekend via rpar .

Opmerking: zorg ervoor dat u compileert met -threaded voor parallelle uitvoering.

RPAR

rpar :: Strategy a voert de gegeven strategie (terugroepen: type Strategy a = a -> Eval a ) parallel uit:

import Control.Concurrent
import Control.DeepSeq
import Control.Parallel.Strategies
import Data.List.Ordered

main = loop
  where 
    loop = do
      putStrLn "Enter a number"
      n <- getLine

      let lim = read n :: Int
          hf  = quot lim 2
          result = runEval $ do
            -- we split the computation in half, so we can concurrently calculate primes
            as <- rpar (force (primesBtwn 2 hf))
            bs <- rpar (force (primesBtwn (hf + 1) lim))
            return (as ++ bs)

      forkIO $ putStrLn ("\nPrimes are: " ++ (show result) ++ " for " ++ n ++ "\n")
      loop

-- Compute primes between two integers
-- Deliberately inefficient for demonstration purposes
primesBtwn n m = eratos [n..m]
  where
    eratos []     = []
    eratos (p:xs) = p : eratos (xs `minus` [p, p+p..])

Als u dit uitvoert, wordt het gelijktijdige gedrag aangetoond:

Enter a number
12
Enter a number

Primes are: [2,3,5,7,8,9,10,11,12] for 12

100
Enter a number

Primes are: [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100] for 100

200000000
Enter a number
-- waiting for 200000000    
200
Enter a number

Primes are: [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200] for 200

-- still waiting for 200000000

rseq

We kunnen rseq :: Strategy a gebruiken om een argument te forceren om de normale vorm van het hoofd te rseq :: Strategy a :

f1 :: [Int]
f1 = [1..100000000]

f2 :: [Int]
f2 = [1..200000000]

main = runEval $ do
  a <- rpar (f1) -- this'll take a while...
  b <- rpar (f2) -- this'll take a while and then some...
  rseq a
  return (a,b)

Dit verandert subtiel de semantiek van het rpar voorbeeld; terwijl deze laatste onmiddellijk zou terugkeren terwijl de waarden op de achtergrond worden berekend, wacht dit voorbeeld tot a kan worden geëvalueerd naar WHNF.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow