Ich habe vor kurzem PLINQ verwendet, um einige Daten zu verarbeiten.Warum endet mein Parallel.ForAll-Aufruf mit einem einzelnen Thread?
Grundsätzlich habe ich etwa 4000 Zeitreihen (also im Grunde Instanzen von Dictionary<DataTime,T>
) die ich in einer Liste timeSeries
geführt habe.
meiner Operation ausführen zu können, ich tue einfach:
timeSeries.AsParallel().ForAll(x=>myOperation(x))
Wenn ich einen Blick auf das, was mit meinen verschiedenen Kernen geschieht, merke ich, dass zuerst sehen, alle meine CPUs benutzt werden und ich auf der Konsole (wo ich einige Protokolle ausgab), dass mehrere Zeitreihen zur gleichen Zeit verarbeitet werden.
Der Prozess ist jedoch langwierig und nach ungefähr 45 Minuten zeigt die Protokollierung deutlich an, dass nur ein Thread arbeitet. Warum das?
Ich habe versucht, einige Gedanken zu machen, und mir wurde klar, dass timeSeries
Instanzen enthält, die aus Sicht der myOperation
am Anfang und am Ende der Liste zu verarbeiten sind. Also, ich fragte mich, ob der Algorithmus, den PLINQ benutzte, darin bestand, die 4000 Instanzen auf etwa 4 Kernen aufzuteilen und jedem von ihnen 1000 zu geben. Wenn der Kern mit der Zuweisung der Arbeit fertig ist, geht er wieder in den Leerlauf. Dies würde bedeuten, dass einer der Kernbereiche mit einer viel größeren Arbeitslast konfrontiert wird.
Ist meine Theorie korrekt oder gibt es eine andere mögliche Erklärung?
Soll ich meine Liste mischen, bevor ich sie leite, oder gibt es Parallelparameter, die ich verwenden kann, um das Problem zu beheben?
Soweit ich weiß, arbeitet Arbeit Diebstahl auf Aufgaben, nicht auf Iterationen in PLINQ. Wenn ein Task eine Reihe von Elementen aus der Sammlung zur Verarbeitung erhält, können andere Tasks diese nicht stehlen. – svick
Auch hier ist möglicherweise kein benutzerdefinierter Partitionierer erforderlich (die vom Framework bereitgestellten) (http://msdn.microsoft.com/en-us/library/system.collections.concurrent.partitioner.create.aspx)) könnte genug sein. – svick
@svick - Sie haben wahrscheinlich Recht, aber würde das auf eine For-Schleife zeigen, die eine Menge Aufgaben erzeugt? Scheint unhandlich. –