"==" Operator atomar?



  • manni66 schrieb:

    Ich kann jetzt zwar spontan keine Stelle aus dem Standard zitieren, aber beim Vergleich zwischen T und atomic<T> sollte "operator T() const;" zum Zuge kommen => der Vergleich ist thread safe.

    Oh tatsächlich. Ein impliziter Konvertierungsoperator in einer neuen Komponente der Standardbibliothek. Warum machen die so etwas?

    hustbaer schrieb:

    Man kann es aber oft gut mit CAS nachbilden. Und mit transactional memory kann man überhaupt einfach so tun als wäre es so.

    Was kann man nachbilden? Ein Spinlock?



  • Jetzt bin ich verwirrt.

    Sind nun Vergleichsoperatoren (==, !=, <= etc) thread-safe im Sinne des C++-Standards? Wie sieht es mit älteren Standards aus? (Atomar sind sie ja nicht wie ich nun gelernt habe)



  • Wenn du ein atomic Object in einem Vergleich verwendest, wird sein Wert benötigt und das Laden des Wertes erfolgt natürlich atomar. Die Frage ist: Was genau versprichst du dir davon? Anfangen kannst du damit am Ende sowieso nix...



  • Naja, ich würde einfach gerne wissen ob z.B. ein shift auf einem atomic int atomar und thread-safe ist (keine data races). Also z.B.

    std::atomic<int> myInt = 9;

    myInt = myInt >> 4;

    oder

    myInt >>= 4;

    ?



  • Hat keine Data Races, die Operation als Ganzes ist aber nicht atomar...was hat das nun mit == zu tun? Abgesehen davon: Nur weil etwas atomar ist, heißt noch lange nicht, dass Code, der es verwendet, threadsafe ist...

    Wenn du wissen willst, was für Operationen atomar sind, wieso nicht einfach in die Doku schauen?



  • Danke aber kannst Du darauf ncohmal genauer eingehen:

    Hat keine Data Races

    Was hat keine Data races und warum nicht?



  • std::atomic<int> myInt = 9; 
    
    myInt = myInt >> 4;
    

    Hat keine Data Races weil alle nebenläufigen Zugriffe auf geteilte Objekte atomic sind. Es gibt aber keine Garantie darüber, welchen Wert myInt am Ende genau haben wird, wenn dieser Code nebenläufig ausgeführt wird. Das einzige, das gesichert ist, ist, dass es sich um einen der möglichen Werte, die aus einer der möglichen Serialisierungen aller Zugriffe resultieren, handelt...



  • ah, du meinst also es ist nicht thread-safe, aber data race frei sozusagen !?



  • sozusagen...



  • TyRoXx schrieb:

    hustbaer schrieb:

    Man kann es aber oft gut mit CAS nachbilden. Und mit transactional memory kann man überhaupt einfach so tun als wäre es so.

    Was kann man nachbilden? Ein Spinlock?

    Atomare "if (cond) do_stuff();" Blöcke.

    Mit CAS geht es natürlich nur sehr begrenzt. Und natürlich muss man Retries machen falls einem wer zwischen dem Test und dem CAS für's "updaten" dazwischengefahren ist.

    EDIT: Was ich vielleicht dazuschreiben sollte: D.h. ne klassische Spinlock/Mutex muss es oft nicht sein. So Sachen wie "if (a < 123) a++;" lassen sich mit Load + Test + CAS + Retry ganz ohne Spinlock/Mutex machen.
    Quasi

    auto expected = a.load(std::memory_order_relaxed);        // Load
    while (expected < 123)                                    // Test & Retry
        if (a.compare_exchange_weak(expected, expected + 1))  // CAS
            break;
    

Anmelden zum Antworten