Ich versuche, wir zu verstehen, warum alle Teile des Standardbeispielcode benötigen:Warum brauchen wir 'Seq' oder 'Pseq' mit 'Par' in Haskell?
a `par` b `pseq` a+b
Warum werden die folgenden nicht ausreichen?
a `par` b `par` a+b
Der obige Ausdruck scheint sehr anschaulich: Versuchen sowohl a
und b
parallel zu bewerten und gibt das Ergebnis a+b
. Ist das nur der Grund der Effizienz: Die zweite Version würde zweimal anstatt einmal entflammen?
Wie wäre es mit der folgenden, prägnanteren Version?
a `par` a+b
Warum sollten wir sicherstellen müssen, dass b
vor a+b
wie im Original, Standard-Code ausgewertet wird?
Dies ist richtig und erklärt auch, warum 'seq' für dieses Problem nicht ausreicht. 'seq' gibt keine Garantie für die Reihenfolge der Auswertung. In 'seq b (a + b)' kann der Haupt-Thread 'a' vor 'b' auswerten, solange 'b' in WHNF ist, wenn '(a + b)' ausgewertet wird. –
Ich sehe nicht, wie dieses Argument beschreibt das Problem mit 'par a (par b (a + b))' - sicher, entweder 'a' oder 'b' wird sofort ausgewertet, und der entsprechende Funke wird verpuffen, aber der andere Funke sollte sehr lebendig sein und Parallelität erzeugen. Natürlich ist es nicht die effizienteste Art, dies zu tun, wenn man einen Funken zündet, aber es funktioniert und überlässt die Frage der Evaluierungsreihenfolge dem Compiler. – gereeter
Im Falle von 'par a (a + b)' ist es immer noch möglich, eine "glückliche" Parallelisierung zu erhalten, wenn die Laufzeit stattdessen zuerst "b" wählt. Dann wird der 'a'-Funke nicht zerstreut. Dies wird im PDF erwähnt: community.haskell.org/~simimonmar/papers/threadscope.pdf (Seite 2) – CMCDragonkai