Threadprogrammierung in Java
lima-city → Forum → Programmiersprachen → Java
berechnung
bestimmen
brauchen
datei
double
effizienter code
ergebnis
erzeugen
fazit
kern
last
laufzeit
problem
prozessor
rechenleistung
sandrock
sekunde
simulation
test
verteilen
-
Hallo,
ich versuche mich hier verzweifelt an der Threadprogrammierung in Java, um meinen DualCore-Prozessor richtig auszureizen zu können. Leider funktioniert das aber nicht so, wie ich mir das denke. Ich habe unten mal eine Beispielklasse eingefügt, die demonstriert, wie ich mir das denke. An sich funktioniert das ja, ABER: wenn ich nur einen Thread starte, wird einer meiner Prozessoren zu 100 % ausgelastet. Die Berechnung dauert dann ca. 3,5 Sekunden. Starte ich aber zwei Threads, so dauert die Berechnung ca. 7 Sekunden, wobei beide Prozessoren zu 100 % ausgelastet werden. Das heißt: zwei Threads verbrauchen mehr Leistung (was ja auch so gedacht ist) aber brauchen trotzdem doppelt so lange. Es wird quasi 4mal so viel Rechenleistung verbraten als mit einem Prozessor. Was mache ich falsch? Oder geht das in Java nicht effizienter?
public class Test { // Anzahl der Threads, die zur Simulation benutzt werden sollen private final int threads = 2; // So oft soll die Simulation durchgefuehrt werden private int counter = 100000000; public static void main(String... args) { new Test(); } public Test() { long start = System.currentTimeMillis(); // Threads initialisieren und starten Simulation[] theThreads = new Simulation[threads]; for (int i=0;i<threads;i++) { theThreads[i] = new Simulation(); theThreads[i].start(); } // Warten, bis alle Threads fertig sind try { for (int i=0;i<threads;i++) { theThreads[i].join(); } } catch (InterruptedException e) { System.err.println("Ein Prozess wurde unterbrochen."); } long end = System.currentTimeMillis(); // Dauer berechnen long duration = end - start; // Ausgabe System.out.println("Dauer der Simulation: " + duration); } private class Simulation extends Thread { public void run() { while (counter > 0) { counter--; double a = Math.random(); Math.sqrt(a); } } } }
Mit freundlichen Grüßen
sandrock-jonas
Beitrag zuletzt geändert: 1.1.2010 11:54:10 von sandrock-jonas -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Hi,
du beschäftigst dich ja mit einem interessanten aber aus meiner Sicht schwer durchschaubarem Thema ;).
Grundsätzlich hast du als Programmierer wenig Einfluss auf die Verwaltung von Threads bzw. Prozessen, denn da will schon das Betriebssystem bestimmen ;). Da geht übrigens der Ärger schon los, da die Begriffe Thread und Prozess nicht immer eindeutig verwendet werden.
Ich habe mir dein Beispiel mal auf meinem T2060 unter Vista angeschaut (ist der einzige Zweikern den ich privat zur Verfügung habe) und ähnliche Ergebnisse festgestellt wie du. Ein Thread braucht 24 Sekunden (dabei laufen aber beide Kerne) zwei Threads brauchen dann etwa 43 Sekunden. Ich habe gesehen, dass Vista auch bei 2 Threads nur einen Prozess startet. Deshalb habe ich mal zwei class Dateien mit je einem Thread sofort nacheinander gestartet und dann 24 und 28 Sekunden Laufzeit gehabt. Sowohl bei zwei Threads aus einer class Datei als auch bei je einem Thread aus einer class Datei waren beide Kerne zu 100% ausgelastet. Dabei wurde die Last also eher auf die zwei Kerne verteilt. Für mich sieht es so aus, als würde die Threadverwaltung der VM einigen Overhead erzeugen, der dann die Kerne belastet. Aber das ist nur eine Vermutung.
Nach meiner Auffassung sind die Threads auch nicht unbedingt zur Lastverteilung erfunden worden (zumindest in Java), sondern um weiterarbeiten zu können, während ein Programm beispielsweise auf Eingaben wartet.
Mehr fällt mir dazu nicht ein, vielleicht findest du ja noch etwas mehr heraus. Ich wäre für Infos dankbar.
Gruß
Manni
-
Hallo,
Danke für die ausführliche Antwort. Ich bin jetzt in der Thematik etwas weiter (und habe das Problem auch gelöst). Allerdings habe ich dazu die Programmiersprache gewechselt (zu C++). Anfänglich hatte ich da auch Probleme, dass die Rechenleistung nicht vernünftig verteilt wurde, allerdings wurden einfach nicht beide Prozessoren voll ausgelastet. Das lag scheinbar an dem C-Zufallszahlengenerator (rand() aus der cstdlib), der nicht effizient parallel lief. Nachdem ich mir meinen eigenen (Pseudo-)Zufallszahlengenerator geschrieben hatte, funktionierte es so, wie ich es wollte: die Rechenleistung wurde effektiv auf mehrere Kerne verteilt und die Laufzeit fast halbiert.
Das Ergebnis: http://www.logisch-gedacht.de/matheraetsel/ziegenproblem/loesung/
Fazit: es ist durchaus möglich, die Rechenleistung zu verteilen (vorausgesetzt, das Problem ist so gestrickt, dass sich ein sinnvoller Algorithmus dazu formulieren lässt - bei meiner Simulation war das aber durchaus der Fall). -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage