Die ordered
-Klausel funktioniert folgendermaßen: Verschiedene Threads werden gleichzeitig ausgeführt, bis sie auf den Bereich ordered
stoßen, der dann sequenziell in derselben Reihenfolge ausgeführt wird, in der er in einer seriellen Schleife ausgeführt wird. Dies ermöglicht immer noch einen gewissen Grad an Gleichzeitigkeit, insbesondere wenn der Codeabschnitt außerhalb der ordered
Region eine beträchtliche Laufzeit aufweist.
Es gibt keinen besonderen Grund, dynamic
Zeitplan statt static
Zeitplan mit kleinen Chunk-Größe zu verwenden. Es hängt alles von der Struktur des Codes ab. Da ordered
eine Abhängigkeit zwischen den Threads einführt, wenn sie mit mit Standard-Chunk-Größe verwendet wird, müsste der zweite Thread warten, bis der erste alle Iterationen beendet hat. Dann müsste der dritte Thread warten, bis der zweite seine Iterationen beendet hat (und daher auch für den ersten), und so weiter. Man könnte es leicht mit 3 Fäden visualisieren und 9 Iterationen (3 pro Thread):
tid List of Timeline
iterations
0 0,1,2 ==o==o==o
1 3,4,5 ==.......o==o==o
2 6,7,8 ==..............o==o==o
=
zeigt, dass der Thread Code parallel ausführt. o
ist, wenn der Thread die ordered
Region ausführt. .
ist der Thread, der sich im Leerlauf befindet und darauf wartet, dass er wiederum die Region ordered
ausführt. Mit schedule(static,1)
würde folgendes passieren:
tid List of Timeline
iterations
0 0,3,6 ==o==o==o
1 1,4,7 ==.o==o==o
2 2,5,8 ==..o==o==o
Ich glaube, der Unterschied in beiden Fällen ist mehr als offensichtlich. Mit schedule(dynamic)
würden die obigen Bilder mehr oder weniger zufällig werden, da die Liste der jedem Thread zugewiesenen Iterationen nicht deterministisch ist. Es würde auch einen zusätzlichen Overhead hinzufügen. Es ist nur nützlich, wenn die Menge der Berechnung für jede Iteration unterschiedlich ist und es viel mehr Zeit für die Berechnung benötigt als der zusätzliche Aufwand für die Verwendung der dynamischen Planung.
Machen Sie sich keine Sorgen wegen der Iteration mit der niedrigsten Nummer. Es wird normalerweise mit dem ersten Thread im Team behandelt, um für die Ausführung von Code bereit zu sein.
Ausgezeichnete Antwort Hristo! Alles klar jetzt, danke! –
@ Cookie503, beachten Sie, dass, wenn die Chunk-Größe zu klein ist, Caching aufgrund verlorener Datenlokalität weniger nützlich wird. Dies könnte Ihre Leistung erheblich schlechter treffen als die implizierte Serialisierung. Experimentieren Sie mit verschiedenen Chunk-Größen, bis die beste Beschleunigung erreicht ist. Verwenden Sie "geordnete" Schleifen mit Bedacht und weichen Sie sie, falls möglich, selbst dann aus, wenn dies zu einem erhöhten Speicherbedarf führt - z. (Bei Ihrem bestimmten Beispiel) sollte anstelle eines Vektors ein einfaches vorher zugewiesenes Array (oder ein anderer Thread-sicherer Random-Access-Container) verwendet werden: 'arr [i] = i;' –