假设我有一个时间戳计数器。

 static uint32_t _Atomic timestamp = 0U;

 static inline uint32_t get_ts(void) {
       return atomic_fetch_add_explicit(&timestamp, 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/

10-11 15:42
查看更多