Simple(?) Frage zu Threads

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:
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);
	}
}
Hier werden einfach nur sinnlos Strings zusammengefügt und die Zeit ausgegeben (Das ist natürlich nicht die Gesamtzeit!)

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
 

faetzminator

Gesperrter Benutzer
Davon ausgegangen, dass diese 50000 Durchläufe auf 3 Threads aufgetrennt werden sollen, musst du natürlich pro Thread nur 50000/3 Durchläufe laufen lassen. Abgesehen davon misst dein Programm gar nicht die Laufzeit des Gesamtprogramms.

Edit: Doch, aber ich seh nirgends ein [c]Time: ...[/c]
 
4

45sda4545fsd

Gast
Das erklärt aber nicht das auftretende Problem, da die einzelnen Threads nicht langsamer werden sollten solange die CPU noch Reserven hat.
Die Gesamtzeit wird in eines MSGBox ausgegeben, die Textausgabe ist nicht so der Hit das gebe ich zu, war auch nur zu Testzwecken. (Gesamtzeit entsprach in allen drei Fällen relativ genau der Zeit des längsten Treads + nen paar ms)

Die Gesamtzeitmessung habe ich auch vorher mit sleep usw getestet, schien alles einwandfrei zu funktionieren.
 
5

56sd4fg56s

Gast
Einmal eine verbesserte Textausgabe zum besseren Verständnis:

++++ Benchmark started. ++++
++++ Thread 0 started. ++++
Time for Thread 0: 2.402
Thread finished: 0
Total Time: 2.404
++++ Benchmark started. ++++
++++ Thread 0 started. ++++
++++ Thread 1 started. ++++
Time for Thread 1: 3.861
Time for Thread 0: 3.861
Thread finished: 0
Thread finished: 1
Total Time: 3.863
++++ Benchmark started. ++++
++++ Thread 0 started. ++++
++++ Thread 1 started. ++++
++++ Thread 2 started. ++++
Time for Thread 1: 5.614
Time for Thread 0: 5.626
Thread finished: 0
Thread finished: 1
Time for Thread 2: 5.633
Thread finished: 2
Total Time: 5.634

Ich sollte mich glaube ich mal registrieren... =/
 

DanZ

Bekanntes Mitglied
Kurz gesagt - es hat irgendwas mit dem Speichermanagement zu tun, das durch deine Stringoperationen ausgelöst wird.
Versuch mal stattdessen sowas:

Java:
 long tLong=1;
            for (long i = 0; i < 2000000000l; i++) {
                tLong*=i;
            }

Da wird es bei zunehmenden Threads sogar teilweise deutlich schneller(macht die VM wohl irgendwelchen Optimierungsvoodoo :))
 

Mille25

Mitglied
Du hast recht, mit mathematischen Operationen skaliert es absolut perfekt. Da muss man erstmal drauf kommen.

Komisch ist nur, dass mein eigentlich angedachter Algorythmus unter dem gleichen Problem wie die String-Operation leidet. :(
Kann es sein, dass das Problem auftritt sobald man Objekte verwendet und nicht nur primitive Datentypen?
 
Zuletzt bearbeitet:

DanZ

Bekanntes Mitglied
Wie sieht der denn aus? Sobald man durchgehend eine Menge Speicher allokiert bringt die verteilte Rechenkraft halt nicht mehr so viel, aber sowas hat dann meist auch ordentlich Optimierungspotenzial.
 

Mille25

Mitglied
Wie sieht der denn aus? Sobald man durchgehend eine Menge Speicher allokiert bringt die verteilte Rechenkraft halt nicht mehr so viel, aber sowas hat dann meist auch ordentlich Optimierungspotenzial.

Ist das dann so zu verstehen, dass irgendwann der Speicher limitiert obwohl die CPU mehr informationen verarbeiten könnte?

Der eigentliche Algorythmus war ein Türme von Hannoi Programm, bestehend aus mehreren Klassen und einer rekursiven Funktion. Es wurde also recht viel Speicher alloziert.
 

Lumaraf

Bekanntes Mitglied
Genaugenommen ist das was du da geschrieben hast ein einfacher Belastungstest für die Garbage-Collection. In jedem Schleifendruchlauf werden mehre GB an Objekten erstellt. Ein relativ großer Teil der CPU-Zeit wird wohl in der GC verbracht. Da ist es dann klar warum mehr Threads auch insgesamt die Laufzeit erhöhen.

Pro Schleifendurchlauf werden die folgenden Objekte erstellt:
- ein StringBuilder (8 Bytes für den Objektheader + 4 Bytes für die länge + 4 Bytes referenz auf ein char[])
- ein char[] vom StringBuilder (8 Bytes Header + 4 Bytes länge + (s.length()+16)*2 Bytes Daten)
- ein String (8 Bytes Header + 4 Bytes offset + 4 Bytes länge + 4 Bytes hashcode + 4 Bytes referenz auf ein char[])
- ein char[] vom String (8 Bytes Header + 4 Bytes länge + (s.length()+1)*2 Bytes Daten)

Das ganze basiert auf der Annahme das das Programm auf einer 32Bit VM ohne AggresiveOpts läuft und der Kompiler s+"." als new StringBuilder(s).append(".").toString() kompiliert hat. Ansonsten könnte der Speicherbedarf durchaus um Faktor 2 nach oben oder unten abweichen. Es sind so oder so auf jeden Fall einige Gigabytes.
 

DanZ

Bekanntes Mitglied
Der eigentliche Algorythmus war ein Türme von Hannoi Programm, bestehend aus mehreren Klassen und einer rekursiven Funktion. Es wurde also recht viel Speicher alloziert.

Ist so abstrakt schwer zu sagen, aber ich würd erstmal versuchen Instanzen wieder zu verwenden statt sie neu zu erstellen. Ansonsten musst du mal konkreten Code zeigen :)
 

Mille25

Mitglied
Das TVH Programm wurde nicht explizit für den Benchmark entwickelt, sondern ich habe es vorher schon unabhängig davon entwickelt und dachte mir nun, dass ich es vielleicht für das Benchmark-Programm verwenden könnte, aber anscheinend ist es dafür ungeeignet.

Ich werde mir wohl was neues ausdenken müssen. Im grunde genommen ist es ja auch relativ egal, was man rechnet. (Oder?)
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Wegen Übermüdung nur ein kleiner Einwurf: Welchen Einfluß könnte der String-Pool auf sowas haben? Könnte das Problem vielleicht (NICHT auf das Speichermanagement an sich, sondern auf den StringPool zurückzuführen sein, und deswegen) mit anderen Arten von Objekten besser skalieren? (Vielleicht schon ein StringBuilder statt eines Strings?)
 

DanZ

Bekanntes Mitglied
StringBuilder skaliert schon deutlich besser als String "+" Operationen... allerdings lange nicht so gut wie ich erwartet hätte. Leider hauts einem auf den Heap voll bevor man auf anständige Vergleichswerte kommt.

[OT]Freitag um halb elf übermüdet? Gleich geht die Party doch erst los :O[/OT]
 

Lumaraf

Bekanntes Mitglied
Wegen Übermüdung nur ein kleiner Einwurf: Welchen Einfluß könnte der String-Pool auf sowas haben? Könnte das Problem vielleicht (NICHT auf das Speichermanagement an sich, sondern auf den StringPool zurückzuführen sein, und deswegen) mit anderen Arten von Objekten besser skalieren? (Vielleicht schon ein StringBuilder statt eines Strings?)

Der String-Pool wird afaik nur für Strings verwendet die direkt aus dem Bytecode kommen und durch den Aufruf von String#intern() erzeugte.
 

Paddelpirat

Bekanntes Mitglied
Was für eine CPU hast du eigentlich? Bei so wenigen Threads kann es z.B. bei Intel-CPUs zu unterschieden durch Turbo-Boost kommen (wenn nur ein Kern benutzt wird, wird dieser hochgetaktet).
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Simple User Interface Frage Allgemeine Java-Themen 13
J Simple Date Format Alternativen bitte um Code Allgemeine Java-Themen 14
K Simple Wassersimulation Allgemeine Java-Themen 6
Thallius Simple JSON Parser Error null Allgemeine Java-Themen 6
S Simple Rechnung automatisieren Allgemeine Java-Themen 4
I zwei simple fragen Allgemeine Java-Themen 22
MiMa Grundsätzliche Frage zur Verwendung von Java Versionen?? Allgemeine Java-Themen 3
KonradN Mal eine Frage zu Binary Serialization Allgemeine Java-Themen 15
8u3631984 Frage zu Java Streams min / max Allgemeine Java-Themen 17
8u3631984 Frage Performance bei Linked List und Array List Allgemeine Java-Themen 5
H Frage regex greater than less than Allgemeine Java-Themen 7
berserkerdq2 Frage zu IntelliJ und JavaFX Allgemeine Java-Themen 1
W Timer Konzept-Frage Allgemeine Java-Themen 16
T Eine Frage des Designs Allgemeine Java-Themen 2
C Frage zu eigenem TableCellRenderer Allgemeine Java-Themen 11
C Programmvorstellung & Frage zum Thema Geschäftsform Allgemeine Java-Themen 51
J Frage zu System.getproperties. Allgemeine Java-Themen 60
molat100 wie kann man die Frage beantworten Allgemeine Java-Themen 1
pkm Frage zur Präzision von Calendar.WEEK_OF_YEAR Allgemeine Java-Themen 12
J Eine Frage zu den Threads und Task Allgemeine Java-Themen 1
pkm Frage nach eventuellem syntaktischen Zucker bei der Konkatenation von ArrayLists Allgemeine Java-Themen 4
M Frage-Antwortspiel wie Wer wird Millionär Allgemeine Java-Themen 1
F Frage zu System.in Allgemeine Java-Themen 3
marcooooo Frage zum Beispiel im Anhang Allgemeine Java-Themen 16
T Meine Frage lautet wie ich 2 CSV Dateien miteinander in Java verbinde und Spalten die zueinander gehören durch den gleichen Key zusammen ausgebe? Allgemeine Java-Themen 5
S Noch eine Design-Frage zu Setter Allgemeine Java-Themen 6
B For-Loop Frage Allgemeine Java-Themen 21
L Java frage Allgemeine Java-Themen 3
bueseb84 Frage zu Mock und UpperBound Allgemeine Java-Themen 2
M Frage zum Konstruktor Allgemeine Java-Themen 2
W Best Practice Frage zur Umsetzung MVC Allgemeine Java-Themen 9
P String-Verschlüsselung - Frage zur Sicherheit Allgemeine Java-Themen 21
B Frage zu Unit-Tests Allgemeine Java-Themen 6
T Allgemeine Frage: GUI für 3D-Visualisierung Allgemeine Java-Themen 5
R Allgemeine Frage zu RMI bei MVC Allgemeine Java-Themen 2
O Frage zum Runtimeverhalten von Java ... Allgemeine Java-Themen 2
H Rundreise frage (Algorithmus) Allgemeine Java-Themen 18
B Generelle Frage bei einer Webanwendung / Reduzierung von DB Abfragen Allgemeine Java-Themen 1
D Frage zu Vererbung Allgemeine Java-Themen 5
J Frage zu regulärem Ausdruck Allgemeine Java-Themen 2
M Allgemeine Frage: Wie lernt man Java / Programmieren von Grund auf? Allgemeine Java-Themen 7
rentasad Design-Frage - Interfaces, Klassen, statische Methoden Allgemeine Java-Themen 3
S Frage zur JLS Allgemeine Java-Themen 0
J Verständnis Frage zur Instanz, Objekte, Instanzierung, Referenz Allgemeine Java-Themen 14
A Methoden Allgemeine Java Frage Allgemeine Java-Themen 3
E String Frage Allgemeine Java-Themen 9
I bin neu bei GitHub, Frage zur Sicherheit Allgemeine Java-Themen 14
C J2V8 NodeJs Java Bride Problem und Frage!?!? Allgemeine Java-Themen 1
C KeyListener Frage Allgemeine Java-Themen 3
T Frage zu UML in Java programmieren Allgemeine Java-Themen 1
R Konstanten initialisieren - FRAGE Allgemeine Java-Themen 3
MTJ004 FTP Frage zu FTP Speicherung Java-Android-FTP Allgemeine Java-Themen 5
J Frage zum Entwurf / json-Datenmodell Allgemeine Java-Themen 8
A Frage zu meinem Code Allgemeine Java-Themen 2
RalleYTN Classpath Nur ne kleine Frage zur MANIFEST.MF Allgemeine Java-Themen 4
T Frage zu Access Modifiers Allgemeine Java-Themen 6
W Input/Output Frage zu pdfbox und FileUtils Allgemeine Java-Themen 2
O Frage zur Implementierungsweise Allgemeine Java-Themen 4
B Frage zu Bitshift Allgemeine Java-Themen 3
J Java Zufallsgenerator (6 aus 49) Frage Allgemeine Java-Themen 7
L Frage zu RIA und GWT Allgemeine Java-Themen 0
P Concurrency Frage Allgemeine Java-Themen 8
M Frage zu Enumerations Allgemeine Java-Themen 2
F Unlimited Strength Policy. Frage Verbreitung der Anwendung Allgemeine Java-Themen 1
F Frage zur Library JTS Allgemeine Java-Themen 5
S Java Design Frage Allgemeine Java-Themen 10
E Reflection? Frage Allgemeine Java-Themen 4
C FileInputStream frage Allgemeine Java-Themen 6
G Polymorphie Programmdesign Frage Allgemeine Java-Themen 20
Uzi21 Frage zu NetBeans ( Console) Allgemeine Java-Themen 11
D Classpath Frage zum Java Resource Loading Allgemeine Java-Themen 2
G Frage zu JPA Allgemeine Java-Themen 1
S Methoden Frage Allgemeine Java-Themen 2
P MVC - Frage zu Model Allgemeine Java-Themen 4
K Frage zu Locks Allgemeine Java-Themen 1
S Frage zu abstract Allgemeine Java-Themen 5
M ArrayList<String> Frage Allgemeine Java-Themen 7
M OOP Design Frage Allgemeine Java-Themen 2
N Frage zur while-Schleife Allgemeine Java-Themen 18
T Best Practice Auslesen von Zeichenketten (Frage, Antworten, usw) Allgemeine Java-Themen 4
C Eine Frage zur Bearbeitungszeit Allgemeine Java-Themen 8
H Frage wegen Heap-Speicher Allgemeine Java-Themen 2
T Garbage Collection Frage Allgemeine Java-Themen 15
P Kurze Frage: aus einer File die Zeilenanzahl auslesen Allgemeine Java-Themen 9
D Frage zu Java und Umlauten / charsets Allgemeine Java-Themen 2
B Frage zu Java und OpenGL? Allgemeine Java-Themen 3
Q Kapselung Allgemeine Design- Frage Allgemeine Java-Themen 8
A eine test thread.join() frage Allgemeine Java-Themen 2
DStrohma LayoutManager Frage zum GridBagLayout Allgemeine Java-Themen 4
F Frage zu Regex möglich Allgemeine Java-Themen 4
H XML-File mit Java erzeugt Frage Allgemeine Java-Themen 10
D Frage und Antwort Programm, Problem bei Methodenaufruf Allgemeine Java-Themen 3
J NetBeans Frage bezüglich der Scanner-Klasse Allgemeine Java-Themen 6
H Java Vector Frage Allgemeine Java-Themen 9
W Frage... Allgemeine Java-Themen 29
R Frage zur topologischen Sortierung Allgemeine Java-Themen 2
H Frage zu weka.core.Instance Allgemeine Java-Themen 3
Y Kleine Frage zu String.split Allgemeine Java-Themen 3
T Frage zu Klassendesing Allgemeine Java-Themen 3
W Frage zu Refactoring statischer Methoden Allgemeine Java-Themen 4

Ähnliche Java Themen


Oben