2016-07-24 2 views
3

Si la valeur x est dans une liste où x est une fonction et parList est appelée sur cette liste (par exemple [l,x,l,x]) ne x se calcule une ou deux fois? D'après ma compréhension de l'évaluation paresseuse de Haskell, une fois que x a été évalué, il n'a pas besoin d'être évalué à nouveau car il retournerait la même valeur. Mais cela s'appliquerait-il dans un environnement multithread?Haskell évaluation paresseuse dans le parallélisme

Répondre

6

Chaque fois que vous créez une étincelle pour un calcul (qui est ce que parList fait), il y a toujours une possibilité que le travail pour que le calcul sera effectué deux fois. En pratique, cela arrive rarement. Fondamentalement, il existe une condition de concurrence entre les threads traitant les étincelles et le fil principal.

Haskell met en œuvre la paresse en mettant d'abord la valeur d'une variable à un thunk - essentiellement un pointeur vers un code pour calculer la valeur. Lorsque la valeur de la variable est demandée, Haskell exécute le code pointé par le thunk et remplace le thunk par la valeur renvoyée. Si la variable est utilisée plus tard, Haskell utilise simplement la valeur stockée.

Lorsque vous évaluez une variable en parallèle, une étincelle est créée en pointant sur la variable. Lorsque l'étincelle est traitée par un fil d'arrière-plan, ne demande que la valeur vers laquelle pointe l'étincelle. Si l'étincelle pointe vers un thunk, le thunk est exécuté et mis à jour avec la valeur renvoyée. Si l'étincelle pointe vers une valeur déjà évaluée, rien ne se passe et on dit que l'étincelle fait.

Ainsi, si vous évaluez une liste comme [x,x,x,x,x,x] en parallèle, une étincelle sera créé pour chaque élément de la liste, et il est possible que deux ou plusieurs de ces étincelles exécutera en même temps. Il est également possible que le thread principal évalue x en même temps. Dans ce cas, le travail à calculer x sera dupliqué. Cependant, une fois que le thunk pour x a été mis à jour, aucune évaluation d'étincelle ou de thread principal de x commençant après cela ne recalculera x.

+0

À la vôtre, j'ai une autre question de suivi. Considérons que nous avons 2 durées d'étincelles raisonnablement longues. Imaginez la première étincelle accède et calcule 'x' mais ne retourne pas. Pendant ce temps, dans un parallèle mais après ce calcul, le deuxième étincelle d'accès 'x'. Cette étincelle obtient-elle la valeur de «x» à partir du calcul de la première étincelle ou calcule-t-elle «x» elle-même? –

+0

Si un calcul nécessite la valeur de 'x' et' x' est actuellement un thunk, il effectuera le travail pour calculer 'x', mettre à jour' x' avec la valeur calculée (donc 'x' n'est plus un thunk) et continuez. – ErikR

+0

Oui, merci pour cela, mais ma question concerne l'interaction de l'évaluation paresseuse et des étincelles. J'essaye de comprendre si un thunk évalué d'une étincelle devient disponible à une autre étincelle qui a été commencée avant que le thunk ait été évalué. Dites que j'ai deux étincelles S1 et S2 fonctionnant actuellement en parallèle, et que toutes deux ont été passées à un thunk à x initialement à l'instant t0. A l'instant t1, un certain temps après que S1 et S2 ont commencé, S1 accède à x, évaluant ainsi le thunk.Supposons que l'évaluation du thunk se termine à l'instant t2. A l'instant t3, (où t3> t2), l'étincelle S2 accède à x. –