W 32-bitowy ARM, funkcja powyżej zostaną skompilowane do
ldr r2, [pc, #0x??] ; to retrieve the address of globalFloat
str r0, [r2] ; store value into globalFloat
Ponieważ istnieją 2 instrukcje i CPU może swobodnie wykonywać niczego między nimi, ale tylko druga instrukcja str r0, [r2]
wpływa na pamięć. Chyba że globalFloat
jest niewyrównany, CPU może wykonywać jednokopijne zapisy do niego.
Przypisanie może być nieatomowe, gdy globalny wskaźnik nie jest wyrównany. Jest także nieatomowa, jeśli piszesz do większej struktury np. CGRect.
Atomic nie wystarcza do bezpieczeństwa nici. Z powodu buforowania i zmiany kolejności instrukcji, twoja zmiana może nie być widoczna dla innych rdzeni procesora. Może być konieczne wstawienie OSMemoryBarrier()
w celu "opublikowania" zmiany.
Operacje atomowe są zwykle interesujące, gdy dotyczą operacji złożonych (np. globalFloat += value
). Możesz zajrzeć do wbudowanej biblioteki OSAtomic
.
Ale to jeszcze "trochę jakoś atomowy", że rzeczywisty zapis stanu globalnej jest pojedyncza instrukcja, więc nikt, kto patrzy na globalFloat, nigdy nie zobaczy go w stanie pośrednim. – unwind
Nie ma jednego do przypisania. –
@unwind: To dotyczy każdej instrukcji sklepu. Stan pośredni jest tu po przeczytaniu, a przed jego zapisaniem, kiedy zmienna fizycznie istnieje w dwóch miejscach (pamięć i rejestracja) jednocześnie. – Potatoswatter