假设我有一个时间戳计数器。
static uint32_t _Atomic timestamp = 0U;
static inline uint32_t get_ts(void) {
return atomic_fetch_add_explicit(×tamp, 1, memory_order_acquire);
}
假设我有一些并发代码,并且我想试验性地测试和记录内存的重新排序。
for (;;) {
uint32_t ts1 = get_ts();
struct result result_a = do_a();
uint32_t ts2 = get_ts();
struct result result_b = do_b();
log(ts1, &result_a);
log(ts2, &result_b);
}
在c11内存模型下,
do_a
可能会通过get_ts
重新排序到do_b()
之后。 for (;;) {
uint32_t ts1 = get_ts();
uint32_t ts2 = get_ts();
struct result result_b = do_b();
struct result result_a = do_a();
log(ts1, &result_a);
log(ts2, &result_b);
}
但是,假设编译器不对x86
lock xadd
上的内容进行重新排序,则会成为所有装入和存储的障碍。因此,实际上x86(而不是编译器)不可能进行这种重新排序,因为get_ts
调用充当了获取释放的屏障。在x86上是否有一种方法可以获取和获取真正的语义?
最佳答案
fetch_add的“ lock xadd”实现中有什么不正确?
如果您不希望锁定的RWM op提供的完整屏障的语义更强,那么在x86上,您确实别无选择。对于加载,普通加载MOV指令确实提供了“ true”获取语义,因为由于存储缓冲,在MOV之前按程序顺序执行的存储可能被其后的其他CPU观察到。
关于x86 - x86是否获取语义并递增?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44617003/