Ab wann macht std::async Sinn



  • Gast3 schrieb:

    Was von deinem Algorithmus braucht denn die 17-20ms - hast du mal einen sinnvollen Benchmark für deinen Berechnung erstellt? z.B. Mio von Durchläufen, Profile laufen lassen, ohne GUI/Allokationen usw. - damit du überhaupt sehen kannst wo deine Kosten herkommen

    Nach einem akuellen profiling sieht es so aus als ob die meiste Zeit des Algorithmus beim einlesen der Punktdaten verloren geht. Da ich hier von einen std::string auf einen double Wert kommen muss. Das scheint mir noch relativ ineffizient zu sein.



  • Zu Umwandeln von strings/int gibt es nen interessanten Vortrag von Alexandrescu hier: https://www.youtube.com/watch?v=o4-CwDo2zpg. Sollte das wirklich dein Flaschenhals sein, dann schau dir das mal an.



  • Gast3 schrieb:

    100,000 Zyklen ist bei dir kein nennenswerter Overhead?

    Das ist nirgendwo ein nennenswerter Overhead, nicht nur bei mir. Es handelt sich etwa um 30us. Wir reden gerade von Tasks, deren Laufzeit in die Millisekunden geht.

    deswegen nutzt man für sehr kurz kleine Aufgaben häufig Thread-Pools, bei seiner 17-20ms Laufzeit wird das wohl schnell relevant wie lange das starten kostet

    Das ist ein Trugschluss. Einen bestehenden Thread eines Threadpools z.B. mittels von pthread_cond_signal aufzuwecken dauert länger, als einen neuen Thread zu starten. Es wäre schon sachdienlich, wenn du deine Theorien auch testen würdest.



  • ;arf schrieb:

    Das ist ein Trugschluss. Einen bestehenden Thread eines Threadpools z.B. mittels von pthread_cond_signal aufzuwecken dauert länger, als einen neuen Thread zu starten. Es wäre schon sachdienlich, wenn du deine Theorien auch testen würdest.

    Das kann ich mir nur schwerlich vorstellen, denn sonst würde Task-Based Parallelism wie z.B. in OpenMP keinerlei Sinn machen.

    Wobei wir gerade bei dem Thema sind, Intel empfiehlt für TBB die Tasks möglichst größer als 10000 Zyklen zu granulieren, um den Management Overhead nicht dominieren zu lassen.



  • Skym0sh0 schrieb:

    Das kann ich mir nur schwerlich vorstellen, denn sonst würde Task-Based Parallelism wie z.B. in OpenMP keinerlei Sinn machen.

    Es gibt ja auch andere Methoden. Speziell das in solchen Szenarien gern verwendete pthread_cond_signal ist unverhältnismäßig teuer, aber pthread_cond_broadcoast kostet schon weniger, ein normaler Mutex noch weniger. Und wie ich schon erwähnt hatte, sind mit spinlocks 2.000 Zyklen möglich (also die Zeit, die vergeht, bis das Ergebnis des anderen Threads im aktuellen Thread zur Verfügung steht, inkl. task dispatch). Aber busy waiting ist nicht immer angebracht und eine generische Threadpool-Implementation wird das auch nicht machen.

    Man muss sich überlegen, was im aktuellen Anwendungsszenario angemessener ist und vielleicht generell weniger nachdenken und mehr messen. Auch jenseits von Multithreading eine gute Idee.



  • Man muss den Thread ja nicht für jeden Auftrag aufwecken sondern nur wenn sich der Zustand von "Leere Queue" nach "Gefüllte Queue" wechselt. Also sehr selten, wenn der Thread immer was zu tun hat.



  • Nach einem akuellen profiling sieht es so aus als ob die meiste Zeit des Algorithmus beim einlesen der Punktdaten verloren geht

    also wenn du noch so viel Zeit im import verbringst lohnen sich Threads noch nicht
    Frage 1: wie hast du rausgefunden das die Zeit dort verloren geht, Profiler?

    Die Berechnung fällt immer dann an wenn der Nutzer einen Parameter ändert.

    Frage 2: wieso werden denn beim Ändern von Parametern Punktedaten in strings geschrieben die dann noch nach double konvertiert werden muessen?

    kannst du nicht auf die Konvertierung verzichten und ohne direkt mit den Daten arbeiten?

    oder ist dein Szenario nur schlecht beschrieben?



  • Gast3 schrieb:

    Frage 2: wieso werden denn beim Ändern von Parametern Punktedaten in strings geschrieben die dann noch nach double konvertiert werden muessen?

    kannst du nicht auf die Konvertierung verzichten und ohne direkt mit den Daten arbeiten?

    oder ist dein Szenario nur schlecht beschrieben?

    Es gibt genau genommen zwei szenairen. Einmal die Darstellung vorhandener Punkte, eingelesen aus einer Datei, und die Berechnung einer Funktion, mit verschiedenen variablen Parameter, aus dem Funktionsterm.

    Bei der Darstellung von Punkten und deren Auswertung ist ganz klar das Einlesen mein Flaschenhals. Das bekomm ich auch in absehbarer Zeit nicht schneller hin. Deswegen versuche ich durch Parallelisierung alles andere möglichst schnell zu gestalten um die verlorene Zeit "aufzuholen".

    Bei der Berechnung aus dem Funktionsterm heraus ist der Parser meine Engstelle. Diesen kann ich nicht parallelisieren da ich dessen Berechnung für jeden Schnitt komplett brauche.
    Somit versuche ich das Update der UI bei einer Änderung des Parameters, was zwangsläufig nötig ist, Parallel zu machen um nicht die ganze Anwendung zu blockieren.



  • Bei der Darstellung von Punkten und deren Auswertung ist ganz klar das Einlesen mein Flaschenhals. Das bekomm ich auch in absehbarer Zeit nicht schneller hin.

    Weil du keine Zeit für die Optimierung hast oder keine Idee hast wie man das (auch ohne Threads) beschleunigen könnte?

    Bei der Berechnung aus dem Funktionsterm heraus ist der Parser meine Engstelle. Diesen kann ich nicht parallelisieren da ich dessen Berechnung für jeden Schnitt komplett brauche.

    Und der Parser arbeitet schon "optimal"?

    Somit versuche ich das Update der UI bei einer Änderung des Parameters, was zwangsläufig nötig ist, Parallel zu machen um nicht die ganze Anwendung zu blockieren.

    du musst deinen Import- und Term-Parser optimieren - dann wird es schon schneller, aber den GUI-Abtrenn-Thread brauchst du meistens trotzdem



  • Gast3 schrieb:

    Und der Parser arbeitet schon "optimal"?

    Für mich gibt es an ihm nichts mehr zu optimieren. Evtl. müsse man den Erstellen hier aus dem Forum fragen, ob er da noch Möglichkeiten sieht.

    du musst deinen Import- und Term-Parser optimieren - dann wird es schon schneller, aber den GUI-Abtrenn-Thread brauchst du meistens trotzdem

    Soweit bin ich gedanklich auch schon.
    Danke!



  • Für mich gibt es an ihm nichts mehr zu optimieren.

    weil der maximal schnell ist oder warum?

    bei dem Import könntest du z.B. auch schnellere string->double Konvertierungsfuntkionen nutzen (https://github.com/miloyip/dtoa-benchmark)

    Evtl. müsse man den Erstellen hier aus dem Forum fragen, ob er da noch Möglichkeiten sieht.

    warum nur ihn?



  • sorry ich hab das falsche Projekt bei string->double gepostet - bin noch am suchen



  • Es kann bei string->double konvertierung sehr relevant sein was du nutzt, scanf, iostream,strtod...



  • Hallo Gast3, meinst du ggf. https://github.com/google/double-conversion?



  • Hallo Gast3, meinst du ggf. https://github.com/google/double-conversion?

    bin mir nicht sicher - ich dachte da wäre eine Benchmark-Übersicht dabei gewesen


Anmelden zum Antworten