Schnelle Interthreadkommunikation



  • Hallo @all,

    ich habe folgendes Perfomance Problem:

    Ich habe eine Funktion/Algorithmus, die für ihre Arbeit rund 11 Sekunden benötigt.
    Da diese Funktion später in einem thread abgearbeitet wird, habe ich zusätzlich 2 Parameter hinzugefügt ( ein std::atomic<bool>& und ein std::atomic<unsigned short>& ).
    - Ist die bool-Variable true, soll der Algorithmus abbrechen.
    - In die ushort Variable soll der przentuale Fortschritt geschrieben werden (0%, 10% 100% )

    Jetzt zum eigentlichen Problem: Füge ich diese Parameter hinzu und schreibe/lese diese in meinem thread, erhöht sich die benötigte Zeit auf 17sek! d.h. C++ benötigt 6 sek! für ein bisschen kommunikation?!?
    Ich habe selbiges mit std::mutex probiert, erzeugt aber langsameren Code...

    Die Frage ist nun gibt es eine bessere Methode, solche Kommunikationen zu lösen?

    Die Variante mit "normalen" Variablen habe ich bereits durchdacht, scheint mir aber zu unsicher zu sein (ich mein, dafür ist atomic schließlich da^^)

    // Der Thread Ausschnitt:
    // ...
    if( abbrechen)
        BrichAlgoAb();
    
    // ...
    
    fortschritt = CalcFortschrittInProzent();
    
    //...
    
    // Main:
    
    // ...
    
    while( 1 )
    {
        std::cout << fortschritt << std::endl;
        std::this_thread::sleep_for( std::chrono::milliseconds( 100 );
    }
    
    // ...
    


  • Kannste die atomischen Zugriffe sagen wir mal nur alle 1000 Durchläufe machen? Wie sieht's dann aus?



  • Danke für den tipp!

    Komme jetzt auf 12 Sekunden 😃



  • Du könntest es auch mal mit std::memory_order_relaxed probieren. Wäre interessant wie viel das bringt.
    (Auf x86 sollte es mMn. ziemlich viel bringen.)



  • Ich muss leider zugeben, dass ich das mir der memory_order noch nicht ganz verstanden habe.

    zu Releaxed

    The operation is ordered to happen atomically at some point

    At some Point? Also irgendwann? Wie gesagt, so richtig bin ich da noch nicht durchgestiegen^^



  • Naja...
    Kann halt sein dass du alte Werte liest.
    Oder dass ein anderer Lesender die Werte die du schreibst verspätet liest.
    Bzw. vermutlich könnte es sogar sein dass er die Werte in der falschen Reihenfolge liest.

    Also wenn du immer um 1 ansteigende Werte liest könnte es sein dass der andere z.B. sowas wie 2, 4, 3, 5, 6, 9, 10, 8, 10... liest.

    Je nachdem was am anderen Ende dranhängt ist das aber wurst.
    Z.B. für Cancel-Flags ist es meist egal.



  • Du meinst, selbst wenn immer weiter false gelesen wird bis irgendwann einmal true kommt und danach wieder false machts keinen Unterschied, weil die Abbruchbedingung ja schon erreicht wurde?



  • Ja, OK, da kann man pathologische Fälle konstruieren wo Unsinn passieren würde.
    Also z.B. dass ein Teil eines Prozesses abgebrochen wird aber andere, darauf folgende Teile nicht - die dann mit unfertigen Daten arbeiten.

    Hmmm...

    Vielleicht muss ich meine Meinung zur Eignung für Cancel Flags nochmal überdenken. Weil man kann ja wirklich kaum sicherstellen dass der gesamte Vorgang zuverlässig abgebrochen wird sobald das Cancel-Flag 1x als "true" gelesen wurde -- ohne dass sich ein nachfolgender Teil darauf verlässt es im "cancel" Fall wieder als "true" zu lesen.


Anmelden zum Antworten