Recherche…


Remarques

Les collections parallèles facilitent la programmation parallèle en masquant les détails de la parallélisation de bas niveau. Cela facilite l'utilisation des architectures multicœurs. ParArray , ParVector , mutable.ParHashMap , immutable.ParHashMap et ParRange exemples de collections parallèles. Une liste complète peut être trouvée dans la documentation .

Créer et utiliser des collections parallèles

Pour créer une collection parallèle à partir d'une collection séquentielle, appelez la méthode par . Pour créer une collection séquentielle à partir d'une collection parallèle, appelez la méthode seq . Cet exemple montre comment transformer un Vector normal en un ParVector , puis à nouveau:

scala> val vect = (1 to 5).toVector
vect: Vector[Int] = Vector(1, 2, 3, 4, 5)

scala> val parVect = vect.par
parVect: scala.collection.parallel.immutable.ParVector[Int] = ParVector(1, 2, 3, 4, 5)

scala> parVect.seq
res0: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4, 5)

La méthode par peut être chaînée, ce qui vous permet de convertir une collection séquentielle en une collection parallèle et d'y effectuer immédiatement une action:

scala> vect.map(_ * 2)
res1: scala.collection.immutable.Vector[Int] = Vector(2, 4, 6, 8, 10)

scala> vect.par.map(_ * 2)
res2: scala.collection.parallel.immutable.ParVector[Int] = ParVector(2, 4, 6, 8, 10)

Dans ces exemples, le travail est en fait distribué à plusieurs unités de traitement, puis joint à nouveau une fois le travail terminé, sans intervention du développeur.

Pièges

N'utilisez pas de collections parallèles lorsque les éléments de la collection doivent être reçus dans un ordre spécifique.

Les collections parallèles effectuent des opérations simultanément. Cela signifie que tout le travail est divisé en plusieurs parties et distribué à différents processeurs. Chaque processeur n'est pas au courant du travail effectué par d'autres. Si l' ordre de la collecte est important, alors le travail traité en parallèle n'est pas déterministe. (Exécuter deux fois le même code peut donner des résultats différents.)


Opérations non associatives

Si une opération est non associative (si l'ordre d'exécution est important), le résultat sur une collection parallélisée sera non déterministe.

scala> val list = (1 to 1000).toList
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10...

scala> list.reduce(_ - _)
res0: Int = -500498

scala> list.reduce(_ - _)
res1: Int = -500498

scala> list.reduce(_ - _)
res2: Int = -500498

scala> val listPar = list.par
listPar: scala.collection.parallel.immutable.ParSeq[Int] = ParVector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10...

scala> listPar.reduce(_ - _)
res3: Int = -408314

scala> listPar.reduce(_ - _)
res4: Int = -422884

scala> listPar.reduce(_ - _)
res5: Int = -301748

Effets secondaires

Les opérations qui ont des effets secondaires, tels que foreach , peuvent ne pas s'exécuter comme souhaité sur des collections parallélisées en raison de conditions de concurrence. Évitez cela en utilisant des fonctions sans effets secondaires, telles que reduce ou map .

scala> val wittyOneLiner = Array("Artificial", "Intelligence", "is", "no", "match", "for", "natural", "stupidity")

scala> wittyOneLiner.foreach(word => print(word + " "))
Artificial Intelligence is no match for natural stupidity 

scala> wittyOneLiner.par.foreach(word => print(word + " "))
match natural is for Artificial no stupidity Intelligence

scala> print(wittyOneLiner.par.reduce{_ + " " + _})
Artificial Intelligence is no match for natural stupidity

scala> val list = (1 to 100).toList
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15...


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow