Erzwingen mehrerer Threads zur Verwendung mehrerer CPUs, wenn diese verfügbar sind
Ich Schreibe ein Java-Programm, das verwendet eine Menge CPU-weil von der Natur, was es tut. Jedoch, viele davon parallel laufen können, und ich habe mein Programm multi-threaded. Wenn ich es laufen, es scheint nur eine CPU verwendet, bis es mehr braucht, dann verwendet es eine andere CPU ist, aber was ich tun kann, in Java zu zwingen, verschiedene threads auf verschiedenen Kerne/CPUs?
InformationsquelleAutor der Frage Nosrama | 2009-08-03
Du musst angemeldet sein, um einen Kommentar abzugeben.
Interpretiere ich diesen Teil Ihrer Frage, als was bedeutet, dass Sie bereits angesprochen haben das problem, dass Ihre Anwendung die multi-thread-fähig. Und trotz, dass, es nicht sofort mit mehreren Kernen.
Die Antwort auf die Frage "gibt es eine Möglichkeit, um Kraft ..." ist (AFAIK) nicht direkt. Ihre JVM und/oder das host-OS entscheiden, wie viele 'native' - threads zu verwenden, und wie diese threads zugeordnet sind, die physikalischen Prozessoren. Sie haben ein paar Optionen für das tuning. Zum Beispiel, fand ich auf dieser Seite die Gespräche darüber, wie tune Java-threading auf Solaris. Und auf dieser Seite spricht über andere Dinge, die verlangsamen können einen multi-threaded-Anwendung.
InformationsquelleAutor der Antwort Stephen C
Gibt es zwei grundlegende Möglichkeiten, um multi-thread in Java. Jede logische Aufgabe, die Sie erstellen mit diesen Methoden sollten an einem frischen Kern, wenn erforderlich und verfügbar.
Methode eins: definieren ein Runnable oder Thread-Objekt (das kann ein Thread im Konstruktor) und starten Sie es läuft mit dem Thread.start () - Methode. Es wird ausgeführt, auf was auch immer core OS gibt es-in der Regel die weniger geladen werden.
Tutorial: Definieren und Starten von Threads
Methode zwei: definieren von Objekten Implementierung des Runnable (wenn Sie nicht zurückkehren, Werte) oder Callable (wenn Sie tun) - Schnittstelle, die die Verarbeitung code. Übergeben Sie diese Aufgaben an einen ExecutorService aus java.util.concurrent-Paket. Die java.util.gleichzeitige.Testamentsvollstrecker-Klasse hat eine Reihe von Methoden zu erstellen, standard, nützliche Arten von ExecutorServices. Link zu Vollzieher tutorial.
Aus der persönlichen Erfahrung, der Vollzieher Feste & Cache-thread-pools sind sehr gut, obwohl Sie möchten tweak thread zählt. - Laufzeit.getRuntime().availableProcessors() kann verwendet werden, zur Laufzeit zu zählen Kerne. Sie müssen shut down thread-pools, wenn Ihre Anwendung fertig ist, da sonst die Anwendung nicht beenden, weil der ThreadPool-threads bleiben.
Immer gute multicore-performance ist manchmal schwierig und voller Fallstricke:
parallel. Nur ein thread tun sollte, die Festplatte zu Lesen/schreiben, zu einem Zeitpunkt.
triviale (kleine Arbeit-bits, ausführen
fast) der Aufwand, diese zu verwalten
in einem ExecutorService Kosten von mehr als
erhalten Sie von mehreren Kernen.
Einem anderen problem: die Steuerung ist harte Arbeit! Eine gute Praxis ist, haben ein manager-thread, der erstellt und sendet, Aufgaben, und dann ein paar threads arbeiten mit work-queues (ExecutorService).
Bin ich auch nur zu berühren auf die wichtigsten Punkte hier -- Multithread-Programmierung ist als eines der härtesten Programmierung Themen von vielen Experten. Es ist nicht intuitiv, unübersichtlich, und die Abstraktionen sind oft schwach.
Bearbeiten -- Beispiel mit ExecutorService:
InformationsquelleAutor der Antwort BobMcGee
Zunächst sollten Sie sich selbst zu beweisen, dass Ihr Programm laufen würde schneller auf mehrere Kerne. Viele Betriebssysteme setzen Mühe in das laufende Programm-threads auf dem gleichen Kern Wann immer möglich.
Läuft auf dem gleichen Kern hat viele Vorteile. Der CPU-cache ist heiß, was bedeutet, dass die Daten für dieses Programm wird in die CPU geladen. Die lock - /monitor - /synchronisationsobjekte sind im CPU-cache, was bedeutet, dass andere CPUs nicht tun müssen, um cache-Synchronisierung der Operationen über den bus (teuer!).
Eine Sache, die kann sehr leicht machen Sie Ihr Programm ausgeführt, auf die gleiche CPU ist die ganze Zeit über-Nutzung von Schlössern und shared memory. Deine threads sollten nicht miteinander sprechen. Das weniger oft deine threads die gleichen Objekte in den gleichen Speicher, desto öfter werden Sie auf verschiedenen CPUs laufen. Je öfter Sie verwenden den gleichen Speicher, desto öfter müssen Sie blockieren, warten auf den anderen thread.
Wenn das OS sieht ein thread-block für einen anderen thread, wird es ausgeführt, dass der thread auf der gleichen CPU, Wann immer er kann. Es reduziert die Menge an Speicher, der bewegt sich über die inter-CPU-bus. Das ist das, was ich denke, verursacht das, was Sie sehen in Ihrem Programm.
InformationsquelleAutor der Antwort Zan Lynx
Erste, würde ich vorschlagen, das Lesen "Concurrency in Practice" von Brian Goetz.
Dies ist bei weitem das beste Buch, das beschreibt, concurrent java-Programmierung.
Parallelität ist leicht zu lernen, schwer zu meistern'. Ich würde vorschlagen, Lesen viel über das Thema, bevor es zu versuchen. Es ist sehr einfach, ein multi-threaded Programm, um korrekt zu arbeiten 99,9% der Zeit, und nicht von 0,1%. Allerdings, hier sind einige Tipps, um Sie begann:
Gibt es zwei gängige Möglichkeiten, um ein Programm mehr als einen Kern:
In der niedrigsten Stufe kann man erstellen und zerstören von threads. Java macht es einfach zu erstellen threads in einem tragbaren Plattform-übergreifende Art und Weise.
Als es neigt dazu, teuer zu erstellen und zerstören von threads, die alle die Zeit, die Java enthält jetzt Vollzieher zu erstellen, re-usable thread-pools. Aufgaben können zugewiesen werden, um die Vollzieher, und das Ergebnis kann abgerufen werden über ein Zukünftiges Objekt.
In der Regel hat man eine Aufgabe, die aufgeteilt werden können in kleinere Aufgaben, aber die Endergebnisse müssen zurück gebracht werden, zusammen. Zum Beispiel mit einem merge-sort-kann man unterteilen Sie die Liste in kleinere und kleinere Teile, so lange, bis man jeden Kern dabei die Sortierung. Doch wie jede Teilliste wird sortiert, es muss zusammengeführt werden, um die endgültig sortierte Liste. Da dieses "Teile-und-herrsche" - Problem ist ziemlich verbreitet, es gibt eine JSR-frameworkdie mit der zugrunde liegenden Verteilung und Verbindung. Dieser Rahmen wird wahrscheinlich enthalten sein, die in Java 7.
InformationsquelleAutor der Antwort brianegge
Gibt es keine Möglichkeit, die CPU-Affinität in Java. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4234402
Wenn Sie es zu tun haben, verwenden JNI zu erstellen, die native threads, und Ihre Affinität.
InformationsquelleAutor der Antwort Iouri Goussev
Schreiben Sie Ihr Programm, um seine Arbeit in form einer viel von Callable ' s übergeben, um einen ExecutorService und ausgeführt mit invokeAll(...).
Können Sie dann wählen Sie eine geeignete Implementierung zur Laufzeit von der Vollstrecker-Klasse. Ein Vorschlag wäre zu nennen Vollzieher.newFixedThreadPool() mit einer Zahl entspricht etwa der Anzahl der cpu-Kerne, um sich zu beschäftigen.
InformationsquelleAutor der Antwort Thorbjørn Ravn Andersen
Ist die einfachste Sache zu tun ist, brechen Sie Ihr Programm in mehrere Prozesse. Wird das OS reservieren Sie über die Kerne.
Etwas härter ist, brechen Sie Ihr Programm in mehrere threads und das Vertrauen der JVM zum zuordnen, richtig. Dies ist -- in der Regel -- was Menschen tun, um die Nutzung der verfügbaren hardware.
Bearbeiten
Wie kann ein multi-processing-Programm "leichter"? Hier ist eine Schritt in einer pipeline.
Jeden Schritt in der pipeline ist ähnlich strukturiert. 9 Linien der overhead für was auch immer verarbeitet.
Dies ist vielleicht nicht die absolute effizienteste. Aber es ist sehr einfach.
Die Allgemeine Struktur Ihrer gleichzeitigen Prozessen ist keine JVM problem. Es ist ein OS problem, so verwenden Sie die shell.
Das einzige, was Links ist zu arbeiten, eine Serialisierung für Ihre Daten-Objekte in der pipeline.
Standard-Serialisierung funktioniert gut. Lesen http://java.sun.com/developer/technicalArticles/Programming/serialization/ für Hinweise, wie zu serialisieren. Sie können ersetzen Sie die
BufferedReader
undBufferedWriter
mitObjectInputStream
undObjectOutputStream
um dies zu erreichen.InformationsquelleAutor der Antwort S.Lott
Ich denke, dieses Problem ist im Zusammenhang mit Java Parallel Proccesing Framework (JPPF). Mit diesem können Sie laufen mehrere jobs auf verschiedenen Prozessoren.
InformationsquelleAutor der Antwort Nandika
JVM-performance-tuning vorher schon erwähnt wurde, in Warum dieser Java-code nicht nutzen, alle CPU-Kerne?. Beachten Sie, dass dies nur für die JVM, so dass Ihre Anwendung muss bereits mit threads (und mehr oder weniger "richtig" an, dass):
http://ch.sun.com/sunnews/events/2009/apr/adworkshop/pdf/5-1-Java-Performance.pdf
InformationsquelleAutor der Antwort ShiDoiSi
Können Sie unter API von Vollzieher mit Java-8-version
Durch work stealing-Mechanismus, der im Leerlauf befindlichen threads stehlen, Aufgaben aus der task-queue des threads beschäftigt und den Gesamtdurchsatz zu erhöhen.
Vom grepcodeUmsetzung
newWorkStealingPool
ist wie folgtInformationsquelleAutor der Antwort Ravindra babu