В 32-битном ARM указанная выше функция будет скомпилирована в
ldr r2, [pc, #0x??] ; to retrieve the address of globalFloat
str r0, [r2] ; store value into globalFloat
Поскольку существует 2 инструкции, и ЦПУ может выполнять любые действия между ними, но только вторая инструкция str r0, [r2]
влияет на память. Если globalFloat
не выровнен, центральный процессор может выполнять атомную запись в одну копию.
Назначение может быть неатомарным, когда глобальный указатель не выровнен. Это также не атомарно, если вы пишете в большую структуру, например CGRect.
Быть атомарным недостаточно для безопасности потоков. Из-за кеширования и переупорядочения инструкций ваши изменения могут быть невидимы для других ядер ЦП. Возможно, вам придется вставить OSMemoryBarrier()
, чтобы «опубликовать» изменения.
Атомарные операции обычно интересны, когда они включают сложные операции (например, globalFloat += value
). Вы можете проверить встроенную библиотеку OSAtomic
для этого.