int operacją atomową?

0

Mam wrażenie że pisanie do int w c nie jest operacją atomową ale potrzebuję jakiś argumentów

4

Samo pisanie może i jest ale np. inkrementacja lub warunkowe pisanie (get-check-write) już niekoniecznie.

Po cos co powstało:
https://en.cppreference.com/w/cpp/atomic/atomic

4

@Miang standard tak mówi. Od atomowości masz stdatomic.h

I mówisz o atomic w rozumieniu „thread safe”, czy atomic w kontekście sygnałów? To nie jest to samo.

8

atomowość bez jawnego prefiksu lock zależy od wyrównania adresu:

https://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.html

8.1.1 Guaranteed Atomic Operations

The Intel486 processor (and newer processors since) guarantees that the following basic memory operations will
always be carried out atomically:

  • Reading or writing a byte
  • Reading or writing a word aligned on a 16-bit boundary
  • Reading or writing a doubleword aligned on a 32-bit boundary

The Pentium processor (and newer processors since) guarantees that the following additional memory operations
will always be carried out atomically:

  • Reading or writing a quadword aligned on a 64-bit boundary
  • 16-bit accesses to uncached memory locations that fit within a 32-bit data bus

The P6 family processors (and newer processors since) guarantee that the following additional memory operation
will always be carried out atomically:

  • Unaligned 16-, 32-, and 64-bit accesses to cached memory that fit within a cache line

oczywiście powyższe dotyczy pojedynczej operacji odczytu albo zapisu (czyli instrukcji mov), ale nie modyfikacji (czyli np. add [memory], cośtam)

4

@Wibowit: pisze o Intelu. Na ARM ztcp z kolei masz read-modify-write i nie ma przeciwwskazań, żeby coś tam wlazło z innego wątku/dma podczas tego cyklu. Jak chcesz atomowo to wjeżdżają instrukcje/intrinsici ldrex/strex albo typy z stdatomic (które efektywnie się do powyższych kompilują).

EDIT @Miang jestem na komórce teraz, ale na godbolcie podgląd asma jest Twoim przyjacielem jak chcesz dowodów. Mogę Ci potem wrzucić przykłady.

EDIT2: taki int bez synca może wylądować w rejestrze i będziesz mieć potencjalnie dwie różne zmienne bo optymalizator nie wie o wielowątkowości. Wtedy potencjalnie może pomoc volatile… ale to nie służy do synchronizacji.

4

x86 ma ogólnie (czyli nawet bez otaczania lockami) dość silną synchronizację danych (silniejszą niż to co jest wymagane przez modele pamięci z javy, c++, itp itd), więc ludzie programujący i testujący tylko i wyłącznie na x86 mogą nie wyłapać błędów w swoich programach.

alagner napisał(a):

EDIT2: taki int bez synca może wylądować w rejestrze i będziesz mieć potencjalnie dwie różne zmienne bo optymalizator nie wie o wielowątkowości. Wtedy potencjalnie może pomoc volatile… ale to nie służy do synchronizacji.

co więcej, bez volatile / atomic / etc optymalizator w kompilatorze może poprzestawiać instrukcje, jeśli model pamięci kompilatora na to pozwala i to nawet wbrew gwarancjom platformy x86.

ogólnie trzeba poczytać o tym: https://en.wikipedia.org/wiki/Memory_model_(programming)

0

@Wibowit:

czyli mój kolega właściwie ma rację tylko zapomniał ze piszemy też na ARM ;)

4

@Miang: atomici to kontrakt. Ty używasz kontraktu w dobry sposób -> kompilator wygeneruje kod, który robi to co mówi kontrakt. Nie znaczy to, że bez atomiców nie będziesz miał atomowych operacji dla konkretnej wersji kompilatora, operacji i architektury procesora. Przykładowo x86 jest dużo bardziej "atomowe" niż ARM, więc kod, który przypadkiem działa na intelach może się wywalić na innych prockach. Jak chcesz zachować zdrowie psychiczne to używasz atomiców, bo ich używanie samo w sobie jest ciężkie nie mówiąc o UB. Poczytaj o tym https://abseil.io/docs/cpp/atomic_danger

0

tak po pierwsze, to int nie jest operacją

1 użytkowników online, w tym zalogowanych: 0, gości: 1