Je vois souvent l'utilisation et l'explication des stratégies parallèles de Haskell connectées à des calculs purs (par exemple fib
). Cependant, je ne le vois pas souvent avec des constructions monadiques: y a-t-il une interprétation raisonnable de l'effet de par
et des fonctions associées lorsqu'il est appliqué à ST s
ou IO
? Y aurait-il une accélération de cette utilisation?Utilisation de stratégies parallèles avec des monades
Répondre
Le parallélisme dans la mona IO s'appelle plus correctement "Concurrency" et est pris en charge par forkIO
et les amis dans le module Control.Concurrent
.
La difficulté avec la parallélisation de la monade ST est que ST est nécessairement monotrou - c'est son but. Il y a une variante paresseuse de la monade ST, Control.Monad.ST.Lazy
, qui en principe pourrait supporter l'évaluation parallèle, mais je ne suis au courant de personne ayant essayé de le faire.
Il existe une nouvelle monade pour l'évaluation parallèle appelée Eval, qui peut être trouvée dans les versions récentes du parallel package. Je recommande d'utiliser la monade Eval
avec rpar
et rseq
au lieu de par
et pseq
ces jours-ci, car il conduit à un code plus robuste et lisible. Par exemple, le fib
exemple usuel peut être écrit
fib n = if n < 2 then 1 else
runEval $ do
x <- rpar (fib (n-1))
y <- rseq (fib (n-2))
return (x+y)
Il y a des situations où cela a du sens, mais en général vous ne devriez pas le faire. Examinez les éléments suivants:
doPar =
let a = unsafePerformIO $ someIOCalc 1
b = unsafePerformIO $ someIOCalc 2
in a `par` b `pseq` a+b
dans doPar
, un calcul pour a
est déclenché, le thread principal évalue b
. Mais, il est possible qu'après que le thread principal termine le calcul de b
, il commencera également à évaluer a
. Vous avez maintenant deux threads évaluant a
, ce qui signifie que certaines des actions d'E/S seront effectuées deux fois (voire plus). Mais si un thread finit d'évaluer a
, l'autre va simplement laisser tomber ce qu'il a fait jusqu'à présent. Pour que cela soit sûr, vous devez avoir certaines choses pour être vraies:
- Il est possible d'exécuter plusieurs fois les actions d'E/S.
- Il est sûr que seules certaines des actions d'E/S sont effectuées (par exemple, il n'y a pas de nettoyage)
- Les actions E/S sont exemptes de conditions de concurrence. Si un thread mute certaines données lors de l'évaluation
a
, l'autre thread travaillant également sura
se comporte-t-il raisonnablement? Probablement pas. - Tous les appels étrangers sont réentrantes (vous en avez besoin pour la concurrence en général bien sûr)
Si votre someIOCalc
ressemble à ceci
someIOCalc n = do
prelaunchMissiles
threadDelay n
launchMissiles
il est absolument pas sûr d'utiliser avec par
et unsafePerformIO
.
Maintenant, cela en vaut-il la peine? Peut être. Les étincelles sont bon marché, même moins chères que les threads, donc en théorie cela devrait être un gain de performance. En pratique, peut-être pas tellement. Roman Leschinsky a une belle blog post about this.
Personnellement, j'ai trouvé beaucoup plus simple de raisonner sur forkIO
.
- 1. Stratégies parallèles efficaces
- 2. Utilisation des extensions parallèles ou LINQ parallèle avec LINQ Prise
- 3. Mélanger des monades dans Haskell
- 4. Comment écrire un problème de boucle imbriquée en utilisant des stratégies parallèles dans Haskell
- 5. données de base avec des opérations parallèles
- 6. Indexation de Lucene avec des extensions parallèles
- 7. Stratégies de gestion des utilisateurs avec LightOpenID
- 8. Monades à l'invite?
- 9. Conseils pour un code plus élégant avec des monades?
- 10. Implémentation de monades d'arbres binaires
- 11. problèmes mono avec des extensions parallèles
- 12. Tri des tableaux parallèles
- 13. Lecture des stratégies Exchange
- 14. Haskell et paresseux Monades évaluation
- 15. façon idiomatiques de combiner différentes monades avec Scala dans
- 16. Dessucrage do-notation pour Monades
- 17. Problème jouer des effets parallèles
- 18. Passer des valeurs avec des extensions parallèles et VB.net
- 19. Conception basée sur des stratégies avec des modèles Variadic
- 20. Travailler avec des classes et des pythons parallèles
- 21. System.ServiceModel.ProtocolException avec deux proxies «parallèles»
- 22. tranformers monade et l'empilage de plusieurs monades
- 23. Erreur de module asynchrone avec des demandes API parallèles
- 24. Transformation de matrices en place avec des collections parallèles
- 25. PHP exécuter des instances de classe parallèles
- 26. Combinant StateT et de l'État monades
- 27. Quelle est la meilleure approche pour implémenter des monades en C#
- 28. Stratégies de tuyau nommées avec mémoire dynamique?
- 29. Monades dans un contexte de transformateur monad
- 30. Haskell Monades MSUM dans HappStack
Vous souhaitez que vos actions E/S soient exécutées dans un certain ordre (par exemple, ouvrez d'abord le fichier, puis lisez-le plutôt que de le fermer). Que voulez-vous paralléliser ici? – helium
@helium: cela semble principalement provenir de données mutables ou lors de l'utilisation du FFI. –
Je me suis demandé cela. J'ouvre souvent plusieurs fichiers volumineux (100 Mo) et les décompresser dans des threads parallèles, puis travailler avec eux après leur ouverture. Ils sont assez grands pour voir une amélioration des performances, mais assez petit, je peux les garder en mémoire. Je me suis demandé comment faire ça à Haskel. –