原子操作(c ++)冻结cpu

时间:2014-03-09 03:42:34

标签: c++ x86 atomic

如果我们在多核cpu上执行原子操作,原子指令是否会冻结所有其他内核上的操作?

示例如果我们对原子变量进行增量: ++的AtomicInteger; 这会冻结其他核心上的所有其他操作吗? 我专注于x86处理器。

我知道读取或写入内存对齐的本机类型是原子的,不会影响任何其他内核执行。

2 个答案:

答案 0 :(得分:1)

x86允许写入跨越两个缓存行(即跨越两个64字节块)的未对齐数据,但结果不保证是原子的。这意味着您可以从addr 0x1003c读取8字节,例如,要求CPU获取2行(0x100000x10040),获取相关的4字节块并将它们拼接在一起。但是,这两行可以存储在不同的位置 - 一个可以缓存,另一个可以存储在主存储器中。在极端情况下(页面拆分),理论上甚至可以换掉它。因此,您可能会从不同时间获得2个数据块(更好的术语是观察点),其中来自其他进程的商店可能在中间更改了一个。

另一方面,一旦你添加了锁前缀(或者添加一个std :: atomic定义,它应该包含你的那个),x86确保结果来自一个观察点,并且与观察结果一致从所有其他线程。为了实现这一点,CPU很可能会强制执行所有核心的完整块(例如总线锁定),直到两条线路都在请求核心中被保护。如果你不这样做,那么你冒着一个活塞的风险,你不断得到一条线,当你获得第二条线时,它会失去另一条线。

P.S。 - user3286380提出了一个好点,++atomicInteger不是原子的,即使你是这样声明的。 std :: atomic保证原子读取和原子写入(每个都在它自己的观察点上),但它不保证原子读 - 修改 - 写,除非你明确说明。

答案 1 :(得分:0)

原子操作是多个处理器无法同时完成的操作。如果你想以原子方式进行添加,那么只有一个线程可以执行该操作。

  

如果我们在多核cpu上执行原子操作,那就是原子操作   所有其他核心上的指令冻结操作?

没有。不一定,如果您碰巧有多个线程尝试执行相同的原子操作,那么除了第一个到达该原子语句之外,它们将被暂停。

  

我知道读取或写入内存对齐的本机类型是原子的   并且不会影响任何其他核心执行。

你在哪里读到这个?这对我来说听起来不对。此操作的结果可能取决于体系结构。但是,如果您在x86上有多个线程,并且这些线程尝试写入同一位置,则默认情况下该操作不是原子操作。因此,线程编辑的地址的最终值可以是任何值。

以下是您可能感兴趣的类似讨论:pthreads: If I increment a global from two different threads, can there be sync issues?