Control.Parallel
モジュールの使い方を勉強しようとしていますが、正しいとは思えませんでした。Haskellでのマルチコアプログラミング - Control.Parallel
次のコード(fibs.hs)を実行しようとしています。
import Control.Parallel
fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = p `par` (q `pseq` (p + q))
where
p = fib (n-1)
q = fib (n-2)
main = print $ fib 30
私はこれをコンパイル:
ghc -O2 --make -threaded fibs.hs
そして、私はこのプログラム(各プログラムを100回実行の平均値と標準偏差を返すPythonスクリプトの出力を実行し、次の結果を得ます実行時間):
./fibs +RTS -N1 -> avg= 0.060203 s, deviation = 0.004112 s
./fibs +RTS -N2 -> avg= 0.052335 s, deviation = 0.006713 s
./fibs +RTS -N3 -> avg= 0.052935 s, deviation = 0.006183 s
./fibs +RTS -N4 -> avg= 0.053976 s, deviation = 0.007106 s
./fibs +RTS -N5 -> avg= 0.055227 s, deviation = 0.008598 s
./fibs +RTS -N6 -> avg= 0.055703 s, deviation = 0.006537 s
./fibs +RTS -N7 -> avg= 0.058327 s, deviation = 0.007526 s
私の質問は以下のとおりです。
-
私は
。 OK。しかし、
pseq
は何をしますか?なぜこのようなパフォーマンスの向上はわずかですか? 私はこれをインテルCore 2クアッドマシンで実行しています。私は-N5か-N6で走ることがパフォーマンスに大きな違いをもたらさない、あるいはプログラムが実際に非常に悪い結果を出すことを期待しています。しかし、なぜ-N2から-N3への改善が見られないのですか?最初の改善はどうしてこんなに小さいのですか?
par
bはBとリターンBと並列に計算についてのコンパイラをヒントになっていることを理解し
a `par` (b `pseq` (a + b)) ?
:まさに私が評価する際に起こっている
Haskellは自動的に最高のパフォーマンスを得るためにスパークのバランスを調整しませんか? – Chuck
自動的にスレッドのバランスをとります。ランタイムには評価されない式(スパーク)のキューがあり、ワークロードが減少するとスレッドに変換されます。あまりに多くのスパークを作らないようにしてください(そしてスパーク・キューを埋める時間を無駄にする) –