1

このコードはどうですか:

parfib :: Int -> Int
parfib 0 = 1
parfib 1 = 1
parfib n = nf2 `par` (nf1 `par` (nf1+nf2+1))
           where nf1 = parfib (n-1)
                 nf2 = parfib (n-2)

これより良い:

parfib :: Int -> Int
parfib 0 = 1
parfib 1 = 1
parfib n = nf2 `par` (nf1 `seq` (nf1+nf2+1))
           where nf1 = parfib (n-1)
                 nf2 = parfib (n-2)

オンラインで見つけた「メインの式が正しい順序で評価されることを保証するために (つまり、子タスクのメイン タスクをブロックすることなく)、seq アノテーションが使用される」という説明が得られません。

seq が使用される理由 インタープリターが最初に parfib (n-1) を評価することを強制することは知っていますが、なぜそれが必要なのですか?

2 番目のプログラムを実行するとき、インターピーターは、nf1+nf2+1 式の nf1 を並行して評価しながら、nf2 を評価する新しいプロセスを起動しませんか? nf1 で始まる必要があることを指定するように指示する必要は何ですか?

4

2 に答える 2

4

後者は nf1 に依存するため、nf1を並行して評価することはあまり意味がありません。それを使用すると、それが評価されたことを知って初めて使用が試みられます。nf1+...nf1seqnf1

于 2009-04-03T10:54:40.580 に答える
0

2 つのバージョンが同じ結果を生成するという私の理解から、スパークの数を最小限に抑えたいためである可能性があります。

ただし、最初のオプションでは、2 つの追加プロセス (nf1、nf2) を開始します。しかし、seq を使用すると、1 つの追加プロセス (nf1) のみを起動するだけです。

于 2009-06-06T20:46:10.217 に答える