如果我们在多核cpu上执行原子操作,原子指令是否会冻结所有其他内核上的操作?
示例如果我们对原子变量进行增量: ++的AtomicInteger; 这会冻结其他核心上的所有其他操作吗? 我专注于x86处理器。
我知道读取或写入内存对齐的本机类型是原子的,不会影响任何其他内核执行。
答案 0 :(得分:1)
x86允许写入跨越两个缓存行(即跨越两个64字节块)的未对齐数据,但结果不保证是原子的。这意味着您可以从addr 0x1003c
读取8字节,例如,要求CPU获取2行(0x10000
和0x10040
),获取相关的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?