Threading oder kein Threading - das ist hier die Frage.

Status
Nicht offen für weitere Antworten.

Fret

Mitglied
Hallo zusammen!

Ich bastel momentan an einem Programm, dass ein bißchen numerische Mathematik (Integration, Optimierung) durchführen soll. Nun wollte ich gerne Threads benutzen, um die Geschwindigkeit zu steigern, da z.B. bei den Integrationsalgorithmen zwei Schritte parallel ausgeführt werden könnten. Ich habe gestern jedoch festgestellt, dass mein Programm langsamer wurde (auf einem Dual Core Rechner). Kann es sein, dass sich Threads in diesem Fall erst ab einer gewissen "Arbeitsgröße" lohnen? Ich habe den Eindruck, dass das Anlegen und Beenden der Threads länger dauert, als wenn ich einfach alle Rechenoperationen nacheinander durchführen lasse. Kann das sein oder liegt hier definitiv ein Programmierfehler von mir vor? Ich habe die threads einfach mit start() gestartet und mit join() die Ergebnisse eingesammelt.


Viele Grüße,
Arne
 

Wildcard

Top Contributor
Kann es sein, dass sich Threads in diesem Fall erst ab einer gewissen "Arbeitsgröße" lohnen? Ich habe den Eindruck, dass das Anlegen und Beenden der Threads länger dauert, als wenn ich einfach alle Rechenoperationen nacheinander durchführen lasse.
Wie soll man das beantworten ohne die "Arbeitsgröße" zu kennen.
Kann das sein oder liegt hier definitiv ein Programmierfehler von mir vor?
Wie kann man dasbeantworten, ohne die Implementierung zu kennen?
 

Saxony

Top Contributor
Hiho,

wenn der Thread ZeitOverhead > der eigentlichen Berechnungszeit ist, sollte man es nicht erst in Threads aufteilen. ;)

Maximal einen Berechnungsthread damit die GUI nicht einfriert.

[edit]
Du willst aber bestimmt die Berechnung auf die zwei Prozessorkerne forken. Das hat aber leider nix mit der JVM zu tun. Die JVM erzeugt zwar deine Threads aber das zu Grunde liegende OS kümmert sich um die Aufteilung auf die Kerne. Ist das OS aber nun der Meinung alle deine Threads auf einem Kern abzuarbeiten, ergibt sich daraus
ThreadOverhead + Berechnungszeit + OS Scheduling für die Gesamtlaufzeit.
[/edit]

bye Saxony
 

Fret

Mitglied
Danke erstmal. Mir ist schon klar, dass für genaue Aussagen der Quellcode nützlich wäre. Ich wollte nur fragen, ob es im Prinzip möglich ist, dass die Threadverwaltung mehr Zeit braucht als der eigentliche Programmteil, der im Thread abgearbeitet werden soll. Ich hatte keinen Plan, wie aufwending die Threadverwaltung für die JVM ist...
 

Saxony

Top Contributor
Fret hat gesagt.:
Ich hatte keinen Plan, wie aufwending die Threadverwaltung für die JVM ist...

Mittlerweile erzeugt die JVM nur Threads und mapped diese auf Native OS Threads. Die Threadverwaltung findet damit eigentlich im OS statt. :)

Füher waren die sogenannten Green Threads vom OS abgeschottet und damit alleinige Sache der JVM. Das hatte zum Beispiel den Nachteil, dass die JVM alleine die Threads nicht auf mehrere CPUs / Kerne aufteilen konnte, da sie über ihren eigenen ProcessScope nicht hinaus kam. Erst das Mapping auf OS Threads gab die Verteilung (Scheduling) an das OS weiter, welche nun nicht mehr an einen alleinigen Prozess gebunden war.
Ich weiß leider nicht ab welcher JavaVersion das Native Thread mapping der JVM nun default ist.

bye Saxony
 

byte

Top Contributor
Saxony hat gesagt.:
Du willst aber bestimmt die Berechnung auf die zwei Prozessorkerne forken. Das hat aber leider nix mit der JVM zu tun.
Man hat zwar keine direkte Kontrolle, aber in der Praxis lastet der Scheduler die Kerne nahezu immer gut aus.

Ist das OS aber nun der Meinung alle deine Threads auf einem Kern abzuarbeiten, ergibt sich daraus
ThreadOverhead + Berechnungszeit + OS Scheduling für die Gesamtlaufzeit.
Häufig ist Multithreading auch bei einem Kern schneller als Single-Threading, weil eine Operation den Kern nicht immer durchweg zu 100% auslastet. Es gibt immer mal Wartezeiten (z.B. durch IO usw). Details dazu siehe Thinking in Java, 4. Ed.
 

byte

Top Contributor
Fret hat gesagt.:
Danke erstmal. Mir ist schon klar, dass für genaue Aussagen der Quellcode nützlich wäre. Ich wollte nur fragen, ob es im Prinzip möglich ist, dass die Threadverwaltung mehr Zeit braucht als der eigentliche Programmteil, der im Thread abgearbeitet werden soll. Ich hatte keinen Plan, wie aufwending die Threadverwaltung für die JVM ist...
Der Aufwand bei Threading und Scheduling liegt im Millisekundenbereich. In der Praxis sinds grade Operationen mit längerer Laufzeit, die man durch Multithreading optimieren will (z.B im 100er Millisekundenbereich und aufwärts). Da spielt der Scheduling-Overhead keine Rolle mehr.
Durch die Verwendung von Thread-Pools kann man den Overhead nochmal reduzieren, weil dann die nativen Threads nicht jedes mal neu allokiert werden.
 

Saxony

Top Contributor
byto hat gesagt.:
Häufig ist Multithreading auch bei einem Kern schneller als Single-Threading, weil eine Operation den Kern nicht immer durchweg zu 100% auslastet. Es gibt immer mal Wartezeiten (z.B. durch IO usw). Details dazu siehe Thinking in Java, 4. Ed.

Ähm versteh ich grad nicht was du meinst!

Arbeitet die CPU an einem Thread, dann arbeitet sie auch nur an genau diesem Thread - hat also zu dieser Zeit eine Last von 100%, da sie keinen anderen anderen Thread parallel mit verarbeiten kann.

Habe ich nur einen Thread T1 und einer CPU:

Code:
  |
T1|----------------
  |
  |
  --------------------------->t

Bei zwei Threads die sich die gleiche Arbeit teilen auf einer CPU:

Code:
  |
T1|  |---|    |--|  |---|
  |  |   |    |  |  |   |
T2|--|   |----|  |--|
  |
  --------------------------->t

Nun muss bei zwei Threads das OS aber wesentlich öfter hin und her schalten zwischen den Threads was die Sache auf einem Kern nun nicht gerade schneller macht.

bye Saxony
 

byte

Top Contributor
Saxony hat gesagt.:
Arbeitet die CPU an einem Thread, dann arbeitet sie auch nur an genau diesem Thread - hat also zu dieser Zeit eine Last von 100%, da sie keinen anderen anderen Thread parallel mit verarbeiten kann.
Das kommt auf die Operation an. Wenn Resourcen involviert sind (z.B. IO), dann hat die CPU häufig Wartezeiten, die man durch Multithreading sinnvoll füllen könnte.

Nun muss bei zwei Threads das OS aber wesentlich öfter hin und her schalten zwischen den Threads was die Sache auf einem Kern nun nicht gerade schneller macht.
Mir ist die Thematik durchaus bewusst. ;) Moderne Scheduling-Algorithmen sind aber extrem effizient. Der Overhead bei einem Thread mehr oder weniger ist kaum messbar und liegt deutlich unter der Zeit, die häufig durch das Warten auf (blockende) Resourcen (wie Festplattenzugriff etc) verloren geht.

Edit: Wenn Du Dir natürlich sicher bist, dass keine der Operationen blockiert, dann macht Concurrency wirklich keinen Sinn auf 1-Prozessor/Kern Systemen.
 

Fret

Mitglied
Also meine Rechenoperation braucht ohne Threading ca 6 sek, mit Threading hat sich die Zeit ca verdoppelt. Allerdings werden ca 40000 Rechenschritte in dieser Zeit ausgeführt, die ich auf zwei Threads aufteilen wollte. Da jeder Thread nach der entsprechenden Rechenoperation stirbt (da run() erfolgreich beendet wurde) muss ich also 20000 mal einen neuen Thread erstellen, richtig? Das wäre natürlich blöd. Wie könnte ich das geschickter machen? Helfen mir da Thread-Pools?
 

tfa

Top Contributor
Da machst du was falsch. Wenn du nur 2 Threads rechnen lassen willst, brauchst du auch nur 2 und nicht 20000.
Der Rechenthread darf natürlich nicht nach einer Operation sterben, wenn diese nur sher kurz ist.
 

Fret

Mitglied
Soweit war ich jetzt auch schon. :) Ich denke, ich muss den Code etwas umstricken, damit das geht. Vermutlich müßte doch dann jeder Thread nach erfolgter Rechenoperation warten, bis er wieder rechnen darf, oder? Mache ich das besser mit await() und signal(), oder mit wait() und notify()?
 

byte

Top Contributor
Verwendest Du Java 5+ ? Dann guck Dir umbedingt das Java Concurrency Framework an. Hantierung mit wait() und notify() sollte man wenn möglich immer umgehen.
 

Fret

Mitglied
Ich verwende Java 6, ja. Du meinst Executor bzw. ExecutorService? Das Framework lässt aber doch keine Steuerung im Sinne von warten und signalisieren zu, oder? Da müßte ich doch trotzdem über ein Condition-Objekt gehen...
 

schalentier

Gesperrter Benutzer
Fret hat gesagt.:
Ich denke, ich muss den Code etwas umstricken, damit das geht.

Du MUSST den Code umstricken. Erklaer mal bisschen genauer, was das fuer eine Rechnung ist. Parallelisieren eines Algorithmus ist absolut nicht trivial.
 

byte

Top Contributor
Fret hat gesagt.:
Ich verwende Java 6, ja. Du meinst Executor bzw. ExecutorService? Das Framework lässt aber doch keine Steuerung im Sinne von warten und signalisieren zu, oder? Da müßte ich doch trotzdem über ein Condition-Objekt gehen...

Doch lässt es. Du kannst sogar explizit Rückgabewerte aus einem Thread bekommen (siehe Callable, Future).
 

Fret

Mitglied
So, ich habe nun mal ausprobiert, die Threads über einen ExecutorService zu starten. Funktioniert auch prima, offensichtlich werden nun beide Kerne meines Rechner benutzt. Leider bringt es keinen Geschwindigkeits-Vorteil, die entsprechenden Rechenoperationen brauchen immernoch ca 8 sek im Vergleich zu ca 5 sek ohne Threading. Ich gehe also davon aus, dass der vom Threading produziert Overhang zu groß ist, als dass es sich lohnen würde. Was kann man denn sonst noch machen, um die Geschwindigkeit eines Programms zu erhöhen? Kann man den ByteCode auch in "richtigen" Code übersetzen?
 

byte

Top Contributor
Die beste Art, die Performance von Quellcode zu verbessern, ist immernoch Quake-Optimization. :roll:

Aber mal im Ernst: ich glaube kaum, dass der Scheduling Overhead zufällig genauso groß ist, dass der Code am Ende die identische Laufzeit hat wie zuvor, als alles noch in einem Thread lief.
Da ist es wahrscheinlicher, dass Deine Implementierung nicht korrekt ist. Aber solange Du keinen Code zeigst, kann man nur spekulieren.
 

byte

Top Contributor
Quake Optimization:
Die Entwickler spielen ein Jahr nur Quake. Danach läuft die Software (auf der dann aktuellen Hardware) schneller! ;)
 

Fret

Mitglied
Der Code ist ziemlich groß, ich werde mal die wesentlichen Teile extrahieren und später posten.
Ein anderer Punkt, der die Geschwindigkeit beeinflussen könnte, ist folgendes: Ich muss eine Funktion auswerten, die das Programm aus Benutzereingaben konstruiert. D.h. der Benutzer gibt ein Modell ein, das Programm konstruiert daraus Differentialgleichungen und integriert diese. Ich habe das so gelöst, dass ich die Benutzereingaben als Variablen in arrays geschrieben habe, die dann vom Programm in einer bestimmten Art und Weise abgelaufen werden (z.B. werden die Felder/Variablen addiert oder multipliziert). Das Auswerten der Gleichungen wäre ja vermutlich schneller, wenn direkt eine "richtige" Gleichung (2x + 3) verfügbar wäre. Wie könnte man das machen?
 

Saxony

Top Contributor
Fret hat gesagt.:
Das Auswerten der Gleichungen wäre ja vermutlich schneller, wenn direkt eine "richtige" Gleichung (2x + 3) verfügbar wäre. Wie könnte man das machen?

Mit einem Funktionsparser.

bye Saxony
 

Fret

Mitglied
Äh, ich glaube wir missverstehen uns. Ich habe bereits einen Parser geschrieben, der aus einer Textdatei mit chemischen Gleichungen die entsprechenden Ratengleichungen (Differentialgleichungen) ableitet. Diese sind prinzipiell recht einfach aufgebaut, es tauchen pro gleichung mehrere Terme auf, die addiert werden. Beim Parsen wird jeweils der Koeffizient des Terms und die nachfolgenden Variablen in eine Array-Struktur geschrieben. Zum Berechnen der jeweiligen Werte der Differentialgleichungen laufe ich mit einer Schleife diesen Array ab und multipliziere bzw. addiere die Werte der dort abgelegten Variablen.
Die Frage ist nun, ob das Ablaufen der Arrays vermieden und die Gleichungen geschickter in anderer Form abgespeichert werden können.
Ein zweiter Punkt wäre der folgende: Ich benutze einen Integrationsalgorithmus für steife Differentialgleichungen, der mir recht langsam vorkommt. Das ist aber dummerweise der einzige, den ich für Java gefunden habe. Kennt jemand von euch einen guten Algorithmus für sowas? In diesem werden recht oft Matrizen kopiert, ich vermute dass das eine zeitaufwendige Sache ist, oder?

Vielen Dank für eure Hilfe!
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
Tarrew Threading - Unregelmäßige Lock-Vergabe Allgemeine Java-Themen 0
Thallius Ist Background-Threading in Java wirklich so schwer? Allgemeine Java-Themen 7
C Threading mit BufferedReader/InputStream & sockets Allgemeine Java-Themen 0
B Threading Allgemeine Java-Themen 23
Luk10 Multi-Threading mit join() Allgemeine Java-Themen 16
R Threading und Rekursion führen zu “GC overhead limit exceeded” Allgemeine Java-Themen 4
SuperSeppel13 Bilder auf Anfrage laden - Threading Allgemeine Java-Themen 3
J Threading / Callables Allgemeine Java-Themen 8
K Threading - schreiben auf Hashmap/löschen - ConcurrentModificationException Allgemeine Java-Themen 3
G Fehlerbereinigung bei Multi Threading Anwedung Allgemeine Java-Themen 2
Zrebna SonarLint: Warum kein Null-Referencing-CodeSmell-Hint hier? Allgemeine Java-Themen 23
M Kein Scanner Fehler durch falsche EIngabe Allgemeine Java-Themen 4
I OpenPDF (ehem. iText) will kein PDF mit CMYK only erzeugen Allgemeine Java-Themen 6
A Kein Online-Zugang mögl.! Allgemeine Java-Themen 4
D kein Versand von Mails mit Anhang mehr Allgemeine Java-Themen 2
D Best Practice Gesamten Bildschirminhalt auslesen und Email schicken sobald kein Pixel sich ändert Allgemeine Java-Themen 11
R Warum kein throw? Allgemeine Java-Themen 3
W String Parsen und auf eigenes Muster anwenden (kein Regex) Allgemeine Java-Themen 11
A Datentypen Long.valueOf liefert kein "L" am Ende Allgemeine Java-Themen 3
M Kein Zugriff auf microSD Karten Allgemeine Java-Themen 4
B Input/Output Server Startet, Jedoch Kein Output. Allgemeine Java-Themen 1
B NullPointerException - Aber kein Fehler im Code Allgemeine Java-Themen 4
T JNI: kein Zugriff auf VM in Callback-Methode eines Windows-Hooks Allgemeine Java-Themen 3
Guybrush Threepwood Kein user.home unter Windows8 Allgemeine Java-Themen 7
127.0.0.1 SQL Exception, kein Driver Allgemeine Java-Themen 9
Z Concurrent Modification Exception - HashMap (kein remove) Allgemeine Java-Themen 4
D Eclipse Kein Zugriff auf Inhalt einer referenzierten .jar Allgemeine Java-Themen 5
S Schnell eine fortlaufende nummer erzeugen SQL, kein Primkey Allgemeine Java-Themen 8
P Mail wird nicht gesendet - Muss ich kein PW angeben ? Allgemeine Java-Themen 13
G RegEx kein Unterstrich Allgemeine Java-Themen 2
E kein doppelter Programmaufruf Allgemeine Java-Themen 3
reibi Workspace schon geöffnet (Kein Eclipse Thema) Allgemeine Java-Themen 14
D Kein Zugriff auf WebService ausser localhost Allgemeine Java-Themen 4
H Bestimmten String mit Pattern und Matcher herauslesen => kein erfolg Allgemeine Java-Themen 9
Haave Audio Device Unavailable: Kein gleichzeitiger Zugriff auf Soundsystem möglich Allgemeine Java-Themen 7
Z Boolean Abfrage gibt kein Boolean zurück, aber warum? Allgemeine Java-Themen 6
T GregorianCalendar - kein Februar Allgemeine Java-Themen 6
0 kein Java unter Server 2008 ? Allgemeine Java-Themen 3
I kann JAVA kein Mathe? Allgemeine Java-Themen 10
J Kein Zugriff auf Klassen im Default Package Allgemeine Java-Themen 8
V FileWriter und Zahlen (Kein Problem, nur Verständnisfrage) Allgemeine Java-Themen 4
T Problem, warum macht der das so(finde kein titel.) Allgemeine Java-Themen 3
K Kein schließendes Tag bei leerem Element mit JDOM Allgemeine Java-Themen 8
D Ich ikann kein Java-Programm starten Allgemeine Java-Themen 10
B Ausführungsproblem: admin, kein admin Allgemeine Java-Themen 2
E Warum kein Import? Allgemeine Java-Themen 3
L Kein Ausführen möglich Allgemeine Java-Themen 3
A Kein finally ausführen trotz verlassen des try blocks? Allgemeine Java-Themen 14
egrath Anonyme Methode - warum hier kein Compilerfehler Allgemeine Java-Themen 2
D kann kein java installieren Allgemeine Java-Themen 2
S Kein Sound in Java Applets unter Win 9x Allgemeine Java-Themen 4
P kein sound bei freenet spielen Allgemeine Java-Themen 2
K Scanner.hasNext findet kein Ende Allgemeine Java-Themen 6
K Problem mit Vererbung - Kein wirklicher Nutzen. Allgemeine Java-Themen 10
Redfrettchen addAll verwendet kein Iterator? Allgemeine Java-Themen 8
P Eclipse: Kein Fehler beim Debuging aber beim normalen run Allgemeine Java-Themen 3
T Feststellen ob kein extra Thread läuft Allgemeine Java-Themen 10
U Versions-Konfusion: Ist long kein object? Allgemeine Java-Themen 3
A Dateistatus abfragen und Datei löschen sobald kein Zugriff Allgemeine Java-Themen 7
M DOS-Shell kennt kein CP850!! Allgemeine Java-Themen 2
D Kein public Konstruktor Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben