c++11 atomic中的6种 momey order
memory_order_relaxed: 只提供对单个atomic变量的原子读/写,不和前后语句有任何memory order的约束关系. 一般只用来做普通计数器,引用计数都不能做。可能导致别打cpu看不到最新的数据变化而产生错误的虚构行为。
memory_order_release memory_order_consume:thread A 对变量x release。thread B 对变量x consume。那么thread A对依赖x所有的写操作,对thread B依赖x的读操作都收可见的。
memory_order_release memory_order_acquire: thread A 执行release, thread B执行acquire。那么thread A 在release之前的所有写操作,对thread B acquire后任何读操作,都是可见的。
即 release执行的操作 不能reorder到release之后。acquire 之后的操作,不能reorder到acquire之前。
memory_order_acq_rel:是memory_order_acquire和memory_order_release的合并,这条语句前后的语句都不能被reorder
memory_order_seq_cst :比memory_order_acq_rel更加严格的顺序保证,memory_order_seq_cst执行完毕后,所有其cpu都是确保可以看到之前修改的最新数据的。如果前面的几个memory order模式允许有缓冲存在的话,memory_order_seq_cst指令执行后则保证真正写入内存。一个普通的读就可以看到由memory_order_seq_cst修改的数据,而memory_order_acquire则需要由memory_order_release配合才能看到,否则什么时候一个普通的load能看到memory_order_release修改的数据是不保证的。
x86的memory order是一种strong memory order,它保证:
LoadLoad是顺序的
一个cpu上前后两条load指令是顺序执行的,前面一条没执行完毕,后面一条不能执行
StoreStore是顺序的
一个cpu上前后两条store指令是顺序执行的,前面一条没执行完毕,后面一条不能执行
LoadStore
一个cpu上前面一条是Load指令,这条指令没执行完毕,后面一条store不能执行
x86不保证StoreLoad的顺序,一条Store指令在前,后面一条不相关的load指令可以先执行。因为这个顺序的不保证,导致Peterson lock实际上需要使用mfence指令才能在x86上实现