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での同時並行プログラミング」は優れており、多数の概念をカバーしています。また、最新のHaskellプログラマーにとっても非常にアクセス可能です。それは非常にお勧めし、PDFまたはオンラインで無料でご利用いただけます。
並行対並行
Simon Marlow はそれを最善のものにしています :
並列プログラムは、より迅速に計算を実行するために、多数の計算ハードウェア(例えば、いくつかのプロセッサコア)を使用するものです。目的は、計算のさまざまな部分を同時に実行する異なるプロセッサに委任することによって、より早期に回答に到達することです。
対照的に、並行処理は、複数の制御スレッドが存在するプログラム構造化手法です。概念的には、コントロールのスレッドは「同時に」実行されます。つまり、ユーザーはその効果がインターリーブされているとみなします。実際に同時に実行するかどうかは実装の詳細です。並行プログラムは、インターリーブされた実行または複数の物理プロセッサを介して単一のプロセッサ上で実行することができる。
弱い頭の標準形
遅延評価がどのように機能するかを知っておくことが重要です。 この章の最初のセクションでは、 WHNFについての強力な紹介と、これが並行プログラミングおよび並行プログラミングにどのように関係するかについて説明します。
エヴァーモナド
ハスケルの並列を用いて表現することができるEval
からモナドをControl.Parallel.Strategies
用いて、 rpar
とrseq
(とりわけ)機能を。
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
を実行すると、すぐに実行され、「戻る」、 a
とb
2つの値はrpar
によってバックグラウンドで計算されます。
注意:パラレル実行が発生するように-threaded
でコンパイルして-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に引数を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)
これは、 rpar
例のセマンティクスを微妙に変更します。後者はバックグラウンドで値を計算する間に直ちに戻りますが、この例はa
がWHNFに評価されるまで待機します。