C+11 memory model中提到了relaxed/acquire/release等内存模型。
GCC提供了Memory Model Aware Atomic Operations的内置函数 Built-in Functions.
原子操作内存模型有:
__ATOMIC_RELAXED
__ATOMIC_ACQUIRE
__ATOMIC_RELEASE
__ATOMIC_SEQ_CST
gcc提供的原子操作:
type __atomic_load_n (type *ptr, int memorder)
在arm64上
__ATOMIC_RELAXED/和直接读取,产生:
ldr w0, [x0]
__ATOMIC_ACQUIRE和__ATOMIC_SEQ_CST产生指令:
ldar w0, [x0]
ldr (Load Register)
普通的加载指令。
ldar (Load Aquire Register)
会设置内存屏障或限制流水线重排序
"I am reading a flag. Once I read it, NOTHING after this can come before it."
gcc提供的内置原则操作函数:
void __atomic_store_n (type *ptr, type val, int memorder)
类似的,在arm64上,relaxed产生:
str w1, [x0]
release产生:
stlr w1, [x0]
str (Store Register)
普通的存储指令
strlr (Store Release Register)
会设置内存屏障或限制流水线重排序
"I am writing a flag. Everything before this MUST be finished before I write it."
relaxed是最宽松的,没有任何memory order限制。
release,用在store。一般在最后写flag的时候,用release。保证写flag之前的所有内存不会跑到更新flag之后。
acquire,用来在load,一般用在读flag的时候,用acquire,可以保证后续的读取不会跑到flag之前。
seq_cst,sequential consistency,是最严格的。
参考:
https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync