【发布时间】:2015-08-13 09:30:44
【问题描述】:
我有一个非原子的 62 位双精度数,它在一个线程中定期递增。这种访问不需要是原子的。然而,这个变量偶尔会被另一个线程读取(而不是写入)。如果我在 64 位边界上对齐变量,则读取是原子的。
但是,有什么方法可以确保在增量过程中不会中途读取变量?我可以调用一个 CPU 指令来序列化管道吗?内存屏障?
我曾想过在我的关键线程中声明变量 atomic 并使用 std::memory_order::memory_order_relaxed(并在稀有线程中使用更严格的内存屏障),但它似乎同样昂贵。
【问题讨论】:
-
使用
<atomic>设施。其他任何事情都会导致未定义的行为。如果您知道对齐的 64 位读取是原子的,那么您可能也可以相信您的编译器也知道这一点。 -
@Kerrek SB:你是对的(尽管库编写者在多线程方面出了名的糟糕,但他们终于赶上了)。但是,在使用
时,需要了解“幕后”发生的事情,否则性能损失可能会很大。 harold 的回答可能被视为为什么在使用原子时某些事情会更快的解释(例如,我希望由于这个事实,许多平台上的良好实现将使 store(load( )+1) 比原子增量快一个数量级,尽管它确实有不同的语义并且并不总是合适的)。
标签: c++ multithreading performance x86 atomic