Suche…


Bemerkungen

Parallele Kollektionen erleichtern die parallele Programmierung, indem Parallelisierungsdetails auf niedriger Ebene ausgeblendet werden. Dies macht es einfach, Multi-Core-Architekturen zu nutzen. Beispiele für parallele Sammlungen umfassen ParArray , ParVector , mutable.ParHashMap , immutable.ParHashMap und ParRange . Eine vollständige Liste finden Sie in der Dokumentation .

Parallele Sammlungen erstellen und verwenden

Um eine parallele Sammlung aus einer sequentiellen Sammlung zu erstellen, rufen Sie die par Methode auf. Um eine sequentielle Sammlung aus einer parallelen Sammlung zu erstellen, rufen Sie die Methode seq . Dieses Beispiel zeigt, wie Sie einen regulären Vector in einen ParVector und dann wieder zurückkehren:

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)

Die par Methode kann verkettet werden, sodass Sie eine sequentielle Auflistung in eine parallele Auflistung konvertieren und sofort eine Aktion darauf ausführen können:

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)

In diesen Beispielen wird die Arbeit in mehrere Verarbeitungseinheiten aufgeteilt und nach Abschluss der Arbeit wieder zusammengefügt - ohne dass ein Eingreifen des Entwicklers erforderlich ist.

Fallstricke

Verwenden Sie keine parallelen Sammlungen, wenn die Sammlungselemente in einer bestimmten Reihenfolge empfangen werden müssen.

Parallele Sammlungen führen gleichzeitig Operationen durch. Das bedeutet, dass die gesamte Arbeit in Teile aufgeteilt und an verschiedene Prozessoren verteilt wird. Jeder Verarbeiter weiß nicht, welche Arbeit andere erledigen. Wenn die Reihenfolge der Sammlung von Belang ist, ist die parallel verarbeitete Arbeit nicht deterministisch. (Wenn Sie denselben Code zweimal ausführen, kann dies zu unterschiedlichen Ergebnissen führen.)


Nicht assoziative Operationen

Wenn eine Operation nicht assoziativ ist (wenn die Reihenfolge der Ausführung von Belang ist), ist das Ergebnis einer parallelisierten Sammlung nicht deterministisch.

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

Nebenwirkungen

Operationen, die Nebeneffekte haben, wie z. B. foreach , werden bei parallelisierten Sammlungen aufgrund von foreach möglicherweise nicht wie gewünscht ausgeführt. Vermeiden Sie dies, indem Sie Funktionen verwenden, die keine Nebenwirkungen haben, wie z. B. reduce oder 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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow