Ich habe kürzlich PLINQ benutzt, um Daten zu verarbeiten.
Grundsätzlich habe ich etwa 4000 Zeitreihen (also im Grunde Fälle von Dictionary<DataTime,T>
), die ich in einer Liste namens timeSeries
vorhalte.
Um meine Operation auszuführen, mache ich einfach:
%Vor%Wenn ich mir anschaue, was mit meinen verschiedenen Kernen passiert, merke ich, dass zuerst alle meine CPUs benutzt werden und ich auf der Konsole (wo ich einige Logs auslege) sehe, dass mehrere Zeitreihen gleichzeitig bearbeitet werden Zeit.
Der Prozess ist jedoch langwierig und nach etwa 45 Minuten zeigt die Protokollierung deutlich an, dass nur ein Thread arbeitet. Warum ist das so?
Ich habe versucht, darüber nachzudenken, und mir wurde klar, dass timeSeries
Instanzen enthält, die aus der Sicht von myOperation
am Anfang und am Ende der Liste einfacher 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.
Stimmt meine Theorie oder gibt es eine andere mögliche Erklärung?
Soll ich meine Liste mischen, bevor ich sie leite, oder gibt es einige Parallelparameter, mit denen ich dieses Problem beheben kann?
Ihre Theorie ist wahrscheinlich richtig, obwohl es etwas gibt, das man "Arbeitssteurung" nennt, das dem entgegenwirken sollte. Ich bin mir nicht sicher, warum das hier nicht funktioniert. Gibt es viele (& gt; = Dutzende) große Jobs an den äußeren Enden oder nur ein paar?
Neben dem Mischen Ihrer Daten können Sie die Überladung für AsParallel()
verwenden, die ein akzeptiert benutzerdefinierte Partioner . Das würde Ihnen erlauben, die Arbeit besser auszugleichen.
Randnotiz: Für diese Situation würde ich Parallel.ForEach()
, mehr Optionen und sauberere Syntax bevorzugen.