并发编程困难的解决

普通的变量读写在编译器 + 处理器的双重优化下行为变得复杂

retry:
  if (locked != UNLOCK) {
    goto retry;
  }
  locked = LOCK;

解决方法:编译器和硬件共同提供不可优化、不可打断的指令

  • “原子指令” + compiler barrier

实现正确的求和

for (int i = 0; i < N; i++)
  asm volatile("lock incq %0" : "+m"(sum));

“Bus lock”——从 80386 开始引入 (bus control signal)

🌶️ 编译器和硬件的协作

Acquire/release semantics

  • 对于一对配对的 release-acquire
  • std::atomic
    • std::memory_order_acquire: guarantees that subsequent loads are not moved before the current load or any preceding loads.
    • std::memory_order_release: preceding stores are not moved past the current store or any subsequent stores.
    • x.load()/x.store() 会根据 memory order 插入 fence
    • x.fetch_add() 将会保证 cst (sequentially consistent)