Haskell Language
병행
수색…
매개 변수
유형 / 기능 | 세부 묘사 |
---|---|
data Eval a | Eval은 병렬 전략을보다 쉽게 정의 할 수있는 Monad입니다. |
type Strategy a = a -> Eval a | 병렬 평가 전략을 구체화하는 기능. 이 함수는 인수의 일부를 가로 지르거나, 병렬 식 또는 순차적으로 하위 식을 평가합니다. |
rpar :: Strategy a | 그것의 논쟁을 촉발시킨다 (병렬로 평가하기 위해) |
rseq :: Strategy a | 약한 머리 정규형에 대한 인수를 평가한다. |
force :: NFData a => a -> a | 인수 자체를 반환하기 전에 인수의 전체 구조를 평가하여 일반 형식으로 줄입니다. Control.DeepSeq 모듈에 의해 제공됩니다. |
비고
사이먼 말로우 (Simon Marlow)의 저서 , 하스켈의 동시 및 병렬 프로그래밍은 탁월하며 많은 개념을 다룹니다. 또한 최신 Haskell 프로그래머에게도 매우 쉽게 접근 할 수 있습니다. 이 제품은 PDF 또는 온라인으로 무료로 제공 할 것을 적극 권장합니다.
병렬 대 동시성
Simon Marlow는 다음과 같이 설명합니다 .
병렬 프로그램은 계산을 더 빨리 수행하기 위해 다양한 계산 하드웨어 (예 : 여러 개의 프로세서 코어)를 사용하는 프로그램입니다. 목표는 계산의 다른 부분을 동시에 실행하는 다른 프로세서에 위임하여 이전에 응답에 도달하는 것입니다.
대조적으로 동시성은 제어 구조가 여러 개인 프로그램 구조화 기술입니다. 개념적으로 컨트롤의 스레드는 "동시에"실행됩니다. 즉, 사용자는 효과가 삽입 된 것을 봅니다. 실제로 같은 시간에 실행되는지 여부는 구현 세부 사항입니다. 동시 프로그램은 인터리빙 된 실행 또는 여러 물리적 프로세서를 통해 단일 프로세서에서 실행할 수 있습니다.
약한 머리 보통 모양
게으른 평가가 작동하는 방법을 알고 있어야합니다. 이 장의 첫 번째 절 에서는 WHNF에 대한 강력한 소개와 이것이 병렬 및 동시 프로그래밍과 관련되는 방법에 대해 설명합니다.
에볼 발 Monad
Haskell에서의 병렬 처리는 rpar
와 rseq
함수를 사용하여 Control.Parallel.Strategies
의 Eval
Monad를 사용하여 표현할 수 있습니다.
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
을 실행하면 즉시 실행되고 "return"되며, 두 값인 a
와 b
는 rpar
통해 백그라운드에서 계산됩니다.
주 : 병렬 실행을 위해 -threaded
로 컴파일하십시오.
Rpar
rpar :: Strategy a
주어진 전략을 실행합니다 (리콜 : type Strategy a = a -> Eval a
).
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..])
이것을 실행하면 동시 동작을 보여줍니다.
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
rseq :: Strategy a
사용하여 Weak Head Normal Form에 인수를 강제로 적용 할 수 있습니다.
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)
이것은 rpar
예제의 의미를 약간 변경합니다. 후자의 배경의 값을 계산하는 동안 즉시 반환까지 반면,이 예에서는 대기하는 a
WHNF로 평가 될 수있다.