Kurze Version ist im Titel.Parallelisierung: Was bewirkt, dass Java-Threads andere als Synchronisierung & I/O blockieren?
Lange Version: Ich arbeite an einem Programm zur wissenschaftlichen Optimierung mit Java. Die Arbeitslast des Programms kann in parallele und serielle Phasen unterteilt werden - parallele Phasen, was bedeutet, dass stark parallelisierbare Arbeit ausgeführt wird. Um das Programm zu beschleunigen (es läuft Stunden/Tage), erstelle ich eine Anzahl von Threads, die der Anzahl der CPU-Kerne auf der Maschine entspricht, die ich verwende - typischerweise 4 oder 8 - und teile die Arbeit zwischen ihnen. Ich starte dann diese Threads und verbinde() sie, bevor ich zu einer seriellen Phase übergehe.
So weit so gut. Was mich stört ist, dass die CPU-Auslastung und die Beschleunigung der parallelen Phasen nicht annähernd dem "theoretischen Maximum" entspricht - z. Wenn ich 4 Kerne habe, erwarte ich irgendwo zwischen 350-400% "Auslastung" (wie oben berichtet), aber stattdessen springt es zwischen 180 und 310 um. Mit nur einem Thread bekomme ich 100% CPU-Auslastung.
Die einzigen Gründe, warum ich von für Threads wissen nicht mit voller Geschwindigkeit auszuführen, sind: blockier wegen I/O blockier aufgrund Synchronisation
keine E/A überhaupt in meiner parallelen Threads vorgeht , noch irgendeine Synchronisation - die einzigen Datenstrukturen, die von den Threads geteilt werden, sind schreibgeschützt und sind entweder Grundtypen oder (nicht gleichzeitige) Sammlungen. Ich suche nach anderen Erklärungen. Eine Möglichkeit wäre, dass mehrere Threads für die Garbage-Collection wiederholt blockiert werden, aber das scheint nur in einer Situation mit Speicherdruck sinnvoll zu sein, und ich ordne viel über den erforderlichen maximalen Heap-Platz zu.
Irgendwelche Vorschläge würden geschätzt.
Update: Nur für den Fall, dass jemand neugierig ist, nach einigen weiteren Untersuchungen habe ich den Code für die allgemeine Leistung optimiert und sehe bessere Auslastung, obwohl nichts, was ich geändert habe, mit der Synchronisation zu tun hat. Einige der Änderungen sollten jedoch zu weniger neuen Heapzuweisungen geführt haben, insbesondere habe ich die Verwendung von Iteratoren und temporary boxed Nummern (Die CERN "Colt" -Bibliothek für Hochleistungs-Java-Computing war hier nützlich: it bietet Sammlungen wie IntArrayList, DoubleArrayList usw. für grundlegende Typen.). Also ich denke, Müllsammlung war wahrscheinlich der Schuldige.
Joe, da ich neugierig bin, was Sie sagen, ist, dass nach der Optimierung sehen Sie eine bessere CPU-Auslastung.Was sind die Zahlen? – Dan