以原子方式读取非原子变量?
Read a non-atomic variable, atomically?
我有一个非原子的 62 位双精度数,它在一个线程中定期递增。此访问不需要是原子的。然而,这个变量偶尔会被另一个线程读取(而不是写入)。如果我在 64 位边界上对齐变量,则读取是原子的。
但是,有什么方法可以确保我不会在增量期间中途读取变量?我可以调用一个 CPU 指令来序列化管道或其他东西吗?内存障碍?
我想在我的关键线程中声明变量 atomic 并使用 std::memory_order::memory_order_relaxed
(并在稀有线程中使用更严格的内存屏障),但它似乎同样昂贵。
由于您标记了 x86,因此这将是特定于 x86 的。
一个增量本质上是三个部分,读,加,写。增量不是原子的,但只要变量不跨越缓存行边界(这种情况比必须对齐要弱到它的自然对齐方式,从 P6 开始就是这样,在四字必须对齐之前)。
所以你已经无法读取撕裂值。您可以做的最糟糕的事情是在读取变量和写入新值之间覆盖变量,但您只是在读取它。
我有一个非原子的 62 位双精度数,它在一个线程中定期递增。此访问不需要是原子的。然而,这个变量偶尔会被另一个线程读取(而不是写入)。如果我在 64 位边界上对齐变量,则读取是原子的。
但是,有什么方法可以确保我不会在增量期间中途读取变量?我可以调用一个 CPU 指令来序列化管道或其他东西吗?内存障碍?
我想在我的关键线程中声明变量 atomic 并使用 std::memory_order::memory_order_relaxed
(并在稀有线程中使用更严格的内存屏障),但它似乎同样昂贵。
由于您标记了 x86,因此这将是特定于 x86 的。
一个增量本质上是三个部分,读,加,写。增量不是原子的,但只要变量不跨越缓存行边界(这种情况比必须对齐要弱到它的自然对齐方式,从 P6 开始就是这样,在四字必须对齐之前)。
所以你已经无法读取撕裂值。您可以做的最糟糕的事情是在读取变量和写入新值之间覆盖变量,但您只是在读取它。