Threads



  • Dieser Thread wurde von Moderator/in Nobuo T aus dem Forum Assembler in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • secondsun schrieb:

    Wie erreiche ich es, dass eine Art "Leitung" gelegt wird? Also Thread 1 schreibt durchgehend alles in einen Queue und Thread 2 holt sich die Daten aus dem Queue heraus und verarbeitet sie.

    das einfachste waere ein ringbuffer, das waere nicht nur lockfree, sondern auch waitfree.

    Jetzt ist der Thread 1 sehr viel schneller als der Thread 2.

    in dem fall solltest du dir ueberlegen, ob du nicht lieber beide threads die dateien verarbeiten laesst, ansonsten ist das langsammer als es sein koennte.



  • rapso schrieb:

    das einfachste waere ein ringbuffer, das waere nicht nur lockfree, sondern auch waitfree.

    aber nicht normalerweise, nur spezielle konstruktionen.

    rapso schrieb:

    Jetzt ist der Thread 1 sehr viel schneller als der Thread 2.

    in dem fall solltest du dir ueberlegen, ob du nicht lieber beide threads die dateien verarbeiten laesst, ansonsten ist das langsammer als es sein koennte.

    oder nur einen thread nehmen, der suchen und verarbeiten nacheinander macht.
    🙂



  • Beides in einem Thread ist natürlich Käse, weil I/O langsam ist und somit der Such-Thread ständig auf Daten warten muss in welcher Zeit Thread2 munter die Daten verarbeiten kann.

    Falls es wen interessiert: A lockless ring-buffer



  • Kenner der Wahrheit schrieb:

    Falls es wen interessiert: A lockless ring-buffer

    das gibts auch noch: http://www.koders.com/c/fidA649E1A0EA070488C13F29677B14D7C09E3E0187.aspx
    🙂



  • Hey,

    schön das hier so viele konstruktive Antworten kommen:-) Finde ich super.
    Mich würde das mit den Pipes aus der API32(?) interessieren da das andere meinen Horizont übersteigt:-P

    Deswegen würde ich gerne wissen wie das mit den Pipes funktioniert. Hat das jemand schon mal gemacht und welche Funktionen stehen mir zur Verfügung. Wenn sich keiner damit auskennt, dann muss ich mich wohl mit den anderen Sachen auseinander setzen;-)



  • Die Pipe erzeugst DU mit CreatePipe http://msdn.microsoft.com/en-us/library/aa365152(VS.85).aspx und kannst dann mit WriteFile reinschreiben und im anderen Thread mit ReadFile rauslesen. Ich würde vermutlich nichtmal die Daten selber pipen, sondern die Daten immer mit new anlegen und nur Zeiger drauf pipen.



  • das geht jetzt nicht gegen irgendwen bestimmten...

    glaubt ihr dass der OP auch nur den funken einer chance hat, eure tollen lock-free ring-buffer hier zu verstehen, oder gar fehlerfrei zu implementieren? mal davon abgesehen dass es IMO total plem ist mit lock-free algorithmen auf was draufzuhauen was IO-limitiert ist.

    eine stinknormale queue, sowas in der art wie C0de4Fun gepostet hat, ist hier sicher das beste.



  • ;fricky schrieb:

    rapso schrieb:

    das einfachste waere ein ringbuffer, das waere nicht nur lockfree, sondern auch waitfree.

    aber nicht normalerweise, nur spezielle konstruktionen.

    doch, normalerweise ist das der fall. man muss sich schon muehe geben sowas simples kaputt zu implementieren.

    rapso schrieb:

    Jetzt ist der Thread 1 sehr viel schneller als der Thread 2.

    in dem fall solltest du dir ueberlegen, ob du nicht lieber beide threads die dateien verarbeiten laesst, ansonsten ist das langsammer als es sein koennte.

    oder nur einen thread nehmen, der suchen und verarbeiten nacheinander macht.
    🙂

    einen thread zu nutzen statt die arbeit auf zwei aufzuteilen soll welchen vorteil genau bringen?



  • hustbaer schrieb:

    glaubt ihr dass der OP auch nur den funken einer chance hat, eure tollen lock-free ring-buffer hier zu verstehen, oder gar fehlerfrei zu implementieren?

    ein ringbuffer der nur einen feeder und nur einen consumer hat ist in den allermeisten implementierungen lock-/waitfree. da muss man nichts an hyper funky dingen imlementieren.

    mal davon abgesehen dass es IMO total plem ist mit lock-free algorithmen auf was draufzuhauen was IO-limitiert ist.

    er sagte der IO thread ist sehr viel schneller.
    weiter hat lockfree und IO limitierung nichts miteinander zu tun.

    eine stinknormale queue, sowas in der art wie C0de4Fun gepostet hat, ist hier sicher das beste.

    ja, wenn man spatzen mit raketenwerfen ausschalten will.



  • rapso schrieb:

    ;fricky schrieb:

    rapso schrieb:

    das einfachste waere ein ringbuffer, das waere nicht nur lockfree, sondern auch waitfree.

    aber nicht normalerweise, nur spezielle konstruktionen.

    doch, normalerweise ist das der fall. man muss sich schon muehe geben sowas simples kaputt zu implementieren.

    Das bezweifel ich, sonst hätte RedHat wohl kaum ein Patent auf einen der Algorithmen angemeldet welche in der von mir zitierten Ringbuffer Datenstruktur zur Anwendung kommt.



  • Algorithmiker schrieb:

    rapso schrieb:

    ;fricky schrieb:

    rapso schrieb:

    das einfachste waere ein ringbuffer, das waere nicht nur lockfree, sondern auch waitfree.

    aber nicht normalerweise, nur spezielle konstruktionen.

    doch, normalerweise ist das der fall. man muss sich schon muehe geben sowas simples kaputt zu implementieren.

    Das bezweifel ich, sonst hätte RedHat wohl kaum ein Patent auf einen der Algorithmen angemeldet welche in der von mir zitierten Ringbuffer Datenstruktur zur Anwendung kommt.

    P.S. Ich bezweifel das nicht nur deswegen, aber schaut euch einfach mal den von mir verlinkten Artikel an, dann wird die Problematik schon klar (der Artikel verweist übrigens auf ein Dokument des Autors, da findet ihr schöne Grafiken die die Problemsituationen illustrieren).



  • Algorithmiker schrieb:

    rapso schrieb:

    ;fricky schrieb:

    rapso schrieb:

    das einfachste waere ein ringbuffer, das waere nicht nur lockfree, sondern auch waitfree.

    aber nicht normalerweise, nur spezielle konstruktionen.

    doch, normalerweise ist das der fall. man muss sich schon muehe geben sowas simples kaputt zu implementieren.

    Das bezweifel ich, sonst hätte RedHat wohl kaum ein Patent auf einen der Algorithmen angemeldet welche in der von mir zitierten Ringbuffer Datenstruktur zur Anwendung kommt.

    brauchst nicht zu bezweifeln, das ist schon seit jahrzehnten die realitaet.
    RedHats patentierter ringbuffer ist fuer generische dinge, er ist abgesichert wenn mehrere feeder und consumer vorhanden sind. dabei musst du logischerweise synchronisieren.
    das hat aber nichts mit diesem fall hier zu tun.



  • Algorithmiker schrieb:

    Algorithmiker schrieb:

    rapso schrieb:

    ;fricky schrieb:

    rapso schrieb:

    das einfachste waere ein ringbuffer, das waere nicht nur lockfree, sondern auch waitfree.

    aber nicht normalerweise, nur spezielle konstruktionen.

    doch, normalerweise ist das der fall. man muss sich schon muehe geben sowas simples kaputt zu implementieren.

    Das bezweifel ich, sonst hätte RedHat wohl kaum ein Patent auf einen der Algorithmen angemeldet welche in der von mir zitierten Ringbuffer Datenstruktur zur Anwendung kommt.

    P.S. Ich bezweifel das nicht nur deswegen, aber schaut euch einfach mal den von mir verlinkten Artikel an, dann wird die Problematik schon klar (der Artikel verweist übrigens auf ein Dokument des Autors, da findet ihr schöne Grafiken die die Problemsituationen illustrieren).

    dein link? wo?



  • rapso schrieb:

    hustbaer schrieb:

    glaubt ihr dass der OP auch nur den funken einer chance hat, eure tollen lock-free ring-buffer hier zu verstehen, oder gar fehlerfrei zu implementieren?

    ein ringbuffer der nur einen feeder und nur einen consumer hat ist in den allermeisten implementierungen lock-/waitfree. da muss man nichts an hyper funky dingen imlementieren.

    ja wennst glaubst.
    gibt ja auch keine CPUs die load-/store-reordering machen, oder wo man selbst für cache coherency sorgen muss. sowas wie memory-barriers ist eh überbewertet.

    mal davon abgesehen dass es IMO total plem ist mit lock-free algorithmen auf was draufzuhauen was IO-limitiert ist.

    er sagte der IO thread ist sehr viel schneller.

    sorry, mein fehler.

    allerdings... wenn der IO thread schon schneller ist als der "verarbeitung-thread", dann hat es erst recht keinen sinn, irgendwelche schwer zu implementierenden optimierungen einzubauen, da man sie nicht spüren wird.

    weiter hat lockfree und IO limitierung nichts miteinander zu tun.

    ansichtssache. ich denke mir halt: wenn ich IO limitiert bin, dann werde ich mir keinen haxen aussreissen, um den CPU intensiven teil noch weiter zu beschleunigen.

    eine stinknormale queue, sowas in der art wie C0de4Fun gepostet hat, ist hier sicher das beste.

    ja, wenn man spatzen mit raketenwerfen ausschalten will.

    nein. es ist das beste, wenn man mit wenig aufwand ein korrektes programm schreiben will. das nicht anfängt mist zu bauen, wenn es mal auf nem MIPS/PPC/... läuft. oder eben unnötig kompliziert ist.



  • rapso schrieb:

    ;fricky schrieb:

    rapso schrieb:

    das einfachste waere ein ringbuffer, das waere nicht nur lockfree, sondern auch waitfree.

    aber nicht normalerweise, nur spezielle konstruktionen.

    doch, normalerweise ist das der fall.

    nee, weil die schreibfunktion mal kurz auf lesezeiger und die lesefunktion auf den schreibzeiger zugreifen muss.

    rapso schrieb:

    Jetzt ist der Thread 1 sehr viel schneller als der Thread 2.

    in dem fall solltest du dir ueberlegen, ob du nicht lieber beide threads die dateien verarbeiten laesst, ansonsten ist das langsammer als es sein koennte.

    oder nur einen thread nehmen, der suchen und verarbeiten nacheinander macht.

    einen thread zu nutzen statt die arbeit auf zwei aufzuteilen soll welchen vorteil genau bringen?
    [/quote]
    z.b. hätte der OP dann diese frage garnicht stellen brauchen. möglicherweise bringt multithreading in seinem fall überhaupt nix, könnte sogar langsamer sein.
    🙂



  • hustbaer schrieb:

    rapso schrieb:

    hustbaer schrieb:

    glaubt ihr dass der OP auch nur den funken einer chance hat, eure tollen lock-free ring-buffer hier zu verstehen, oder gar fehlerfrei zu implementieren?

    ein ringbuffer der nur einen feeder und nur einen consumer hat ist in den allermeisten implementierungen lock-/waitfree. da muss man nichts an hyper funky dingen imlementieren.

    ja wennst glaubst.
    gibt ja auch keine CPUs die load-/store-reordering machen, oder wo man selbst für cache coherency sorgen muss. sowas wie memory-barriers ist eh überbewertet.

    ja, das ist komplett irrelevant bei nem simplen ringbuffer. entweder es steht 0 drinnen, und dann kann der feeder was einfuegen, oder es steht ein ptr drinnen, dann kann der consumer 0 einfuegen. das ist dermassen primitiv. eine memory barrier brauchst du nur wenn du zwei writes hast die zueinander eine abhaengige reihenfolge haben, das gibt es hier nicht, weder im fall vom feeder, noch writer.

    mal davon abgesehen dass es IMO total plem ist mit lock-free algorithmen auf was draufzuhauen was IO-limitiert ist.

    er sagte der IO thread ist sehr viel schneller.

    sorry, mein fehler.

    allerdings... wenn der IO thread schon schneller ist als der "verarbeitung-thread", dann hat es erst recht keinen sinn, irgendwelche schwer zu implementierenden optimierungen einzubauen, da man sie nicht spüren wird.

    deswegen schlug ich ja diese simple vor. etwas als zwischenbuffer damit beide asynchron laufen braucht man, denn es wuerde ja keinen sinn machen zwei threads zu haben wenn der eine darauf warten wuerde dem anderen einen wert zu uebergeben.

    weiter hat lockfree und IO limitierung nichts miteinander zu tun.

    ansichtssache. ich denke mir halt: wenn ich IO limitiert bin, dann werde ich mir keinen haxen aussreissen, um den CPU intensiven teil noch weiter zu beschleunigen.

    das ist nicht wirklich IO relevant, denn wann auch immer das verhaeltniss von "arbeit" zu "sync" sich in richtung "arbeit" shiften, macht es weniger sinn den sync zu optimieren. da wuerde ich mir als auch keine arbeit machen.
    jedoch, wenn man kommunizieren will, muss man sich schon gedanken machen wie es sicher ist.
    von daher wuerde ich etwas waehlen was so trivial ist, dass man keine arbeit in sync investieren muss, weil es per definition sicher ist.
    mein tipp mit ringbuffer war also nicht als optimierung gedacht fuer die laufzeit, sondern implementierungszeit.

    eine stinknormale queue, sowas in der art wie C0de4Fun gepostet hat, ist hier sicher das beste.

    ja, wenn man spatzen mit raketenwerfen ausschalten will.

    nein. es ist das beste, wenn man mit wenig aufwand ein korrektes programm schreiben will.

    das ist deine meinung. ich hab meine 2cent dazu gegeben.
    steht dem threadstarter frei selbst zu entscheiden was er machen moechte.



  • ;fricky schrieb:

    rapso schrieb:

    ;fricky schrieb:

    rapso schrieb:

    das einfachste waere ein ringbuffer, das waere nicht nur lockfree, sondern auch waitfree.

    aber nicht normalerweise, nur spezielle konstruktionen.

    doch, normalerweise ist das der fall.

    nee, weil die schreibfunktion mal kurz auf lesezeiger und die lesefunktion auf den schreibzeiger zugreifen muss.

    wozu?

    rapso schrieb:

    Jetzt ist der Thread 1 sehr viel schneller als der Thread 2.

    in dem fall solltest du dir ueberlegen, ob du nicht lieber beide threads die dateien verarbeiten laesst, ansonsten ist das langsammer als es sein koennte.

    oder nur einen thread nehmen, der suchen und verarbeiten nacheinander macht.

    einen thread zu nutzen statt die arbeit auf zwei aufzuteilen soll welchen vorteil genau bringen?

    z.b. hätte der OP dann diese frage garnicht stellen brauchen. möglicherweise bringt multithreading in seinem fall überhaupt nix, könnte sogar langsamer sein.
    :)[/quote]es koennte auch sein dass er im debug baut 😉
    ja, wenn ich sowas annehmen wuerde, wuerde ich den thread meiden 😉



  • rapso schrieb:

    ;fricky schrieb:

    rapso schrieb:

    ;fricky schrieb:

    rapso schrieb:

    das einfachste waere ein ringbuffer, das waere nicht nur lockfree, sondern auch waitfree.

    aber nicht normalerweise, nur spezielle konstruktionen.

    doch, normalerweise ist das der fall.

    nee, weil die schreibfunktion mal kurz auf lesezeiger und die lesefunktion auf den schreibzeiger zugreifen muss.

    wozu?

    die schreibfunktion muss wissen, ob im buffer platz ist und die lesefunktion muss wissen, ob im buffer daten sind.

    rapso schrieb:

    ja, das ist komplett irrelevant bei nem simplen ringbuffer. entweder es steht 0 drinnen, und dann kann der feeder was einfuegen, oder es steht ein ptr drinnen, dann kann der consumer 0 einfuegen. das ist dermassen primitiv.

    darf man fragen, was du unter einem 'simplen ringbuffer' verstehst?
    🙂



  • rapso schrieb:

    hustbaer schrieb:

    rapso schrieb:

    hustbaer schrieb:

    glaubt ihr dass der OP auch nur den funken einer chance hat, eure tollen lock-free ring-buffer hier zu verstehen, oder gar fehlerfrei zu implementieren?

    ein ringbuffer der nur einen feeder und nur einen consumer hat ist in den allermeisten implementierungen lock-/waitfree. da muss man nichts an hyper funky dingen imlementieren.

    ja wennst glaubst.
    gibt ja auch keine CPUs die load-/store-reordering machen, oder wo man selbst für cache coherency sorgen muss. sowas wie memory-barriers ist eh überbewertet.

    ja, das ist komplett irrelevant bei nem simplen ringbuffer. entweder es steht 0 drinnen, und dann kann der feeder was einfuegen, oder es steht ein ptr drinnen, dann kann der consumer 0 einfuegen. das ist dermassen primitiv. eine memory barrier brauchst du nur wenn du zwei writes hast die zueinander eine abhaengige reihenfolge haben, das gibt es hier nicht, weder im fall vom feeder, noch writer.

    es ist eben nicht irrelevant, da es immer abhängigkeiten gibt.
    der "producer" muss sicherstellen, dass das, was er produziert hat, für den "consumer" auch sichtbar ist, bevor er anfängt es zu konsumieren.

    beispiel:

    int* buffer_ptr = 0; // der auf einen zeiger reduzierte ring-buffer
    
    void produce()
    {
        int* value_ptr = get_value_buffer();
        *value_ptr = 123; // (1) wert schreiben
    
        // HIER fehlt eine barrier
    
        // warten bis platz im buffer ist
        while (buffer_ptr != 0)
            wait();
    
        buffer_ptr = value_ptr; // (2) zeiger schreiben
    }
    
    void consume()
    {
       // warten bis es was zu konsumieren gibt
       while (buffer_ptr == 0) // (3.1)
            wait();
    
       int* value_ptr = buffer_ptr; // (3.2) zeiger lesen
       buffer_ptr = 0; // platz im buffer machen
    
       // HIER fehlt auch eine barrier
    
       int value = *value_ptr; // (4) wert lesen
       release_value_buffer(value_ptr);
    
       // irgendwas mit "value" machen
    }
    

    hier haben wir 2 interessante stores und 2 (bzw. 3) interessante loads.

    angenommen (2) wird für den "consumer" vor (1) sichtbar, dann wird der "consumer" bei (3) den neuen zeiger lesen, aber bei (4) einen alten wert lesen.

    -> fehler

    mal davon abgesehen dass es IMO total plem ist mit lock-free algorithmen auf was draufzuhauen was IO-limitiert ist.

    er sagte der IO thread ist sehr viel schneller.

    sorry, mein fehler.

    allerdings... wenn der IO thread schon schneller ist als der "verarbeitung-thread", dann hat es erst recht keinen sinn, irgendwelche schwer zu implementierenden optimierungen einzubauen, da man sie nicht spüren wird.

    deswegen schlug ich ja diese simple vor. etwas als zwischenbuffer damit beide asynchron laufen braucht man, denn es wuerde ja keinen sinn machen zwei threads zu haben wenn der eine darauf warten wuerde dem anderen einen wert zu uebergeben.

    ja, richtig. eine "stinknormale" über mutexen und condition-variablen implementierte producer-consumer queue würde genau das bewerkstelligen. ohne die diversen fehler, die man so schnell einbaut, wenn man versucht, etwas "einfaches" ohne explizite synchronisierung zu basteln.

    weiter hat lockfree und IO limitierung nichts miteinander zu tun.

    ansichtssache. ich denke mir halt: wenn ich IO limitiert bin, dann werde ich mir keinen haxen aussreissen, um den CPU intensiven teil noch weiter zu beschleunigen.

    das ist nicht wirklich IO relevant, denn wann auch immer das verhaeltniss von "arbeit" zu "sync" sich in richtung "arbeit" shiften, macht es weniger sinn den sync zu optimieren. da wuerde ich mir als auch keine arbeit machen.
    jedoch, wenn man kommunizieren will, muss man sich schon gedanken machen wie es sicher ist.

    genau. was du vorschlägst ist aber nicht sicher. genau darum geht's mir ja.

    von daher wuerde ich etwas waehlen was so trivial ist, dass man keine arbeit in sync investieren muss, weil es per definition sicher ist.

    mir wäre nichts bekannt, was gleichzeitig trivial, sync-frei und sicher ist. mal abgesehen von einfachen "kill-flags".

    mein tipp mit ringbuffer war also nicht als optimierung gedacht fuer die laufzeit, sondern implementierungszeit.

    mein tip war genauso gedacht.

    eine stinknormale queue, sowas in der art wie C0de4Fun gepostet hat, ist hier sicher das beste.

    ja, wenn man spatzen mit raketenwerfen ausschalten will.

    nein. es ist das beste, wenn man mit wenig aufwand ein korrektes programm schreiben will.

    das ist deine meinung. ich hab meine 2cent dazu gegeben.
    steht dem threadstarter frei selbst zu entscheiden was er machen moechte.

    jopp, das ist meine meinung 🙂


Anmelden zum Antworten