31

標準のサンプルコードのすべての部分が必要な理由を理解しようとしています。

a `par` b `pseq` a+b

なぜ以下では不十分なのですか?

a `par` b `par` a+b

上記の式は非常にわかりやすいようです。abを並行して評価し、結果を返しa+bます。理由は効率の理由だけですか:2番目のバージョンは1回ではなく2回スパークしますか?

次のより簡潔なバージョンはどうですか?

a `par` a+b

元の標準コードのように、b事前に評価されていることを確認する必要があるのはなぜですか?a+b

4

3 に答える 3

30

Ok。次の論文が私の質問に答えると思います:http://community.haskell.org/~simonmar/papers/threadscope.pdf

要約すると、

a `par` b `par` a+b 

a `par` a+b

評価の順序の欠如です。どちらのバージョンでも、メインスレッドはすぐにa(または場合によってbは)動作し、メインスレッドがすでに評価を開始したものを評価するためにスレッドを開始する必要がなくなるため、スパークがすぐに「消える」ようになります。

元のバージョン

a `par` b `pseq` a+b

b メインスレッドが以前に 動作することを保証しa+b(または代わりに評価を開始する)、並列評価のためaにスパークがスレッドに具体化する機会を与えます。a

于 2011-01-02T02:26:17.533 に答える
16
a `par` b `par` a+b 

aとbを並行して評価し、a +bを返します。はい。

ただし、そこでのpseqは、a +bが評価される前にaとbの両方が評価されることを保証します。

そのトピックの詳細については、このリンクを参照してください。

于 2011-01-02T02:19:05.070 に答える
7

a `par` b `par` a+baとの両方のスパークを作成しますが、bすぐa+bに到達するため、スパークの1つが消えます(つまり、メインスレッドで評価されます)。これに伴う問題は、不要な火花を作成したため、効率です。これを使用して並列分割統治を実装している場合、オーバーヘッドによってスピードアップが制限されます。

a `par` a+b火花が1つしかないので、より良いようです。ただし、a前に評価しようとするbと、の火花が消え、火花がないため、の連続評価になりaます。順序をに切り替えるとこの問題は解決しますが、コードとしてこれは順序を強制せず、Haskellはそれをとして評価できます。ba+bb+aa+b

したがって、を評価する前に、メインスレッドでのa `par` b `pseq` a+b評価を強制します。これにより、評価を試みる前にスパークが実現する機会が与えられ、不要なスパークは作成されていません。ba+baa+b

于 2014-05-19T09:40:16.450 に答える