Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] std::atomic, a działanie std::memory_order_relaxed

Ostatnio zmodyfikowano 2013-06-05 12:27
Autor Wiadomość
Elaine
» 2013-06-04 23:58:13
Ja bym eksperymentalnie zapuścił np. milion razy wykonanie tego kodu i sprawdził czy choć raz zachodzi Assert.
Na x86 to nie ma sensu, ta architektura ma bardzo silny model pamięci, wszystko zachowuje się jak memory_order_seq_cst. Jeśli masz dostęp do maszyny na ARMie, MIPSie, PowerPC czy w zasadzie dowolnej w miarę nowoczesnej architekturze innej niż x86, to tak, taki eksperyment można przeprowadzić.

W każdym razie wydaje mi się nieco dziwne, aby zmienna modyfikowana później była 'synchronizowana' przed zmienną modyfikowaną wcześniej w tym samym wątku
W tym nie ma nic dziwnego, procesory i kontrolery pamięci lubią zmieniać kolejność operacji i nawet udawać, że operacja zaszła, podczas gdy ma dopiero zajść, to wszystko w imię wydajności. Znowu, to "wina" x86, gdzie kolejności widoczności operacji między procesorami dotyczą bardzo silne gwarancje. Na innych architekturach takich gwarancji "z urzędu" nie ma, trzeba o nie poprosić podając odpowiedni memory ordering przy operacjach atomowych. I dlatego ten kod, choć niepoprawny, będzie "działał" na typowym desktopie używającym x86, ale przestanie po skompilowaniu na telefon oparty o ARM.
P-84893
DejaVu
» 2013-06-05 00:19:19
Podsumowując: dopóki nie ma się pełnej wiedzy i świadomości na temat różnic w działaniu memory ordering to najlepiej korzystać z domyślnego zachowania std::atomic, tj. std::memory_order_seq_cst, bowiem mamy gwarancję, że na każdej architekturze aplikacja zachowa się tak samo. Racja?

No i wniosek z tego co napisałeś płynie również taki, że w przypadku pracy na architekturze x86 nie ma sensu stosować innego memory orderingu niż domyślny, bowiem nawet nie będziemy w stanie przetestować poprawności przyjętego rozwiązania.

/edit:
Jeszcze jedno: skoro ten cały std::memory_order_relaxed ma tylko i wyłącznie własność atomic, to w jakim konkretnym przypadku będzie istniało uzasadnienie i wymierne korzyści płynące z użycia wspomnianego memory orderingu?
P-84894
usmiech
» 2013-06-05 01:21:32
<< offtop >>
P-84901
Elaine
» 2013-06-05 12:27:07
Podsumowując: dopóki nie ma się pełnej wiedzy i świadomości na temat różnic w działaniu memory ordering to najlepiej korzystać z domyślnego zachowania std::atomic, tj. std::memory_order_seq_cst, bowiem mamy gwarancję, że na każdej architekturze aplikacja zachowa się tak samo. Racja?
Tak.

Jeszcze jedno: skoro ten cały std::memory_order_relaxed ma tylko i wyłącznie własność atomic, to w jakim konkretnym przypadku będzie istniało uzasadnienie i wymierne korzyści płynące z użycia wspomnianego memory orderingu?
Choćby przy zliczaniu referencji. Dodawanie nowych referencji nie potrzebuje żadnych szczególnych gwarancji, o synchronizację trzeba zatroszczyć się dopiero przy zmienjszaniu licznika.
C/C++
class Foo {
private:
    std::atomic < unsigned > referenceCount { 0 };
   
    friend void intrusive_ptr_add_ref( Foo * obj ) {
        obj->referenceCount.fetch_add( 1, std::memory_order_relaxed );
    }
    friend void intrusive_ptr_release( Foo * obj ) {
        if( obj->referenceCount.fetch_sub( 1, std::memory_order_release ) == 1 ) {
            std::atomic_thread_fence( std::memory_order_acquire );
            delete obj;
        }
    }
};
Dowód poprawności pozostawiam jako ćwiczenie dla czytelnika.
P-84912
1 « 2 »
Poprzednia strona Strona 2 z 2