4
45fsdghfd46hfh
Gast
Moin,
ich habe eine hoffentlich simple Frage zu Threads.
Ich möchte aus Spaß ein mehr oder weniger sinnloses Benchmarkprogramm schreiben, dass irgendwelche Algorythmen ausführt und die Zeit dafür misst.
Um Prozessoren mit mehreren Kernen richtig auslasten zu können, möchte ich mehrere Threads laufen lassen, die aber alle das selbe berechnen. Dann möchte ich die Zeit messen, die der Prozessor benötigt um ALLE Threads zu beenden.
Jedoch bekomme ich sehr merkwürdige Testergebnisse, die ich mir nicht erklären kann.
Obwohl ich einen 4-Kern-Prozessor besitze, dauert das abarbeiten der einzelnen Threads länger wenn ich mehr Threads starte, obwohl die CPU auslastung weit unter 100% liegt.
Ein Beispiel:
Ich starte nur einen Thread, warte bis alle Threads beendet sind -> 10s. (CPU auslastung 25%)
Ich starte 2 Threads, warte bis alle fertig sind -> 20s. (CPU auslastung 50%)
Ich starte 3 Threads, warte bis alle fertig sind -> 30s. (CPU auslastung 75%)
... usw
Sprich: Obwohl das Programm mehr rechenleistung nutzt, skaliert die Dauer ca. linear mit der Thread-Anzahl, und das verstehe ich einfach nicht. Wo liegt mein Denkfehler? Theoretisch sollte doch die Zeit bis alle Threads beendet sind ungefähr gleich bleiben, solange die CPU Auslastung unter 100% liegt (Dh. theoretisch bei 1-4 Threads bei meinem 4-Kerner.).
Ich habe auch schon versucht die Priorität der Threads auf maximal zu erhöhen, da ich vermutete dass der Windows Sheduler da irgendwie seine Finger im Spiel hat, dies zeigte allerdings keinen Effekt.
Hier mein (zu Testzwecken sehr einfacher) Source-Code:
Der Thread:
Hier werden einfach nur sinnlos Strings zusammengefügt und die Zeit ausgegeben (Das ist natürlich nicht die Gesamtzeit!)
In meiner Hauptklasse werden nun die Threads gestartet und gewartet, bis alle fertig sind und anschließend die Zeit ausgegeben. Das alles scheint auch wunderbar zu funktionieren, bis auf das oben genannte Problem...
Die Zeitmessung in den einzelenen Threads hat auch ganz klar gezeigt, dass jeder Thread für sich länger braucht. Woran liegt das nun und was mache ich falsch?
PS: Hier nochmal die Textausgabe beim Testen:
MfG
ich habe eine hoffentlich simple Frage zu Threads.
Ich möchte aus Spaß ein mehr oder weniger sinnloses Benchmarkprogramm schreiben, dass irgendwelche Algorythmen ausführt und die Zeit dafür misst.
Um Prozessoren mit mehreren Kernen richtig auslasten zu können, möchte ich mehrere Threads laufen lassen, die aber alle das selbe berechnen. Dann möchte ich die Zeit messen, die der Prozessor benötigt um ALLE Threads zu beenden.
Jedoch bekomme ich sehr merkwürdige Testergebnisse, die ich mir nicht erklären kann.
Obwohl ich einen 4-Kern-Prozessor besitze, dauert das abarbeiten der einzelnen Threads länger wenn ich mehr Threads starte, obwohl die CPU auslastung weit unter 100% liegt.
Ein Beispiel:
Ich starte nur einen Thread, warte bis alle Threads beendet sind -> 10s. (CPU auslastung 25%)
Ich starte 2 Threads, warte bis alle fertig sind -> 20s. (CPU auslastung 50%)
Ich starte 3 Threads, warte bis alle fertig sind -> 30s. (CPU auslastung 75%)
... usw
Sprich: Obwohl das Programm mehr rechenleistung nutzt, skaliert die Dauer ca. linear mit der Thread-Anzahl, und das verstehe ich einfach nicht. Wo liegt mein Denkfehler? Theoretisch sollte doch die Zeit bis alle Threads beendet sind ungefähr gleich bleiben, solange die CPU Auslastung unter 100% liegt (Dh. theoretisch bei 1-4 Threads bei meinem 4-Kerner.).
Ich habe auch schon versucht die Priorität der Threads auf maximal zu erhöhen, da ich vermutete dass der Windows Sheduler da irgendwie seine Finger im Spiel hat, dies zeigte allerdings keinen Effekt.
Hier mein (zu Testzwecken sehr einfacher) Source-Code:
Der Thread:
Java:
public class TestThread extends Thread {
public void run() {
System.out.println("++++ Thread started. ++++");
long startzeit = System.currentTimeMillis();
String s = "";
for (int i = 0; i < 50000; i++) {
s += ".";
}
long endzeit = System.currentTimeMillis();
long zeit = endzeit - startzeit;
System.out.println("Zeit für diesen Thread: " + zeit/1000.0);
}
}
Java:
private static void startBenchmark(int threads) {
Thread tvht[] = new Thread[threads];
for (int i = 0; i < threads; i++) {
tvht[i] = new TestThread();
tvht[i].start();
}
System.out.println("++++ Benchmark started. ++++");
long startzeit = System.currentTimeMillis();
for (int i = 0; i < threads; i++) {
try {
tvht[i].join();
System.out.println("Thread finished: " + i);
} catch (InterruptedException ie) {
System.out.println("Thread interrupted:" + i);
}
}
long endzeit = System.currentTimeMillis();
long zeit = endzeit - startzeit;
JOptionPane.showMessageDialog(null, "Time: " + zeit/1000.0);
}
In meiner Hauptklasse werden nun die Threads gestartet und gewartet, bis alle fertig sind und anschließend die Zeit ausgegeben. Das alles scheint auch wunderbar zu funktionieren, bis auf das oben genannte Problem...
Die Zeitmessung in den einzelenen Threads hat auch ganz klar gezeigt, dass jeder Thread für sich länger braucht. Woran liegt das nun und was mache ich falsch?
PS: Hier nochmal die Textausgabe beim Testen:
++++ Benchmark started. ++++
++++ Thread started. ++++
Zeit für diesen Thread: 2.467
Thread finished: 0
++++ Benchmark started. ++++
++++ Thread started. ++++
++++ Thread started. ++++
Zeit für diesen Thread: 3.898
Thread finished: 0
Zeit für diesen Thread: 3.899
Thread finished: 1
++++ Thread started. ++++
++++ Thread started. ++++
++++ Benchmark started. ++++
++++ Thread started. ++++
Zeit für diesen Thread: 5.796
Zeit für diesen Thread: 5.801
Zeit für diesen Thread: 5.805
Thread finished: 0
Thread finished: 1
Thread finished: 2
MfG