代码之家  ›  专栏  ›  技术社区  ›  Ruslan PiotrNycz

有没有可能从另一个线程写入的内存中读取一个值,这样它既不是原始值,也不是最终值?

  •  1
  • Ruslan PiotrNycz  · 技术社区  · 7 年前

    假设我们在内存中有一个变量,它通过执行以下操作不断被执行线程更新: MOV

    如果可能的话,我如何再现这种情况?错位或变量的其他特殊放置是否有助于实现这一点?

    1 回复  |  直到 2 年前
        1
  •  4
  •   Peter Cordes    7 年前

    跨缓存线边界拆分变量。然后,加载和存储都不是原子的,在所有真正的CPU上都会被撕裂。

    e、 g.在NASM语法中:

    section .bss
    align 64
           resb 63   ; reserve 63 bytes
    myvar: resd 1    ; reserve 1 dword (32 bits)
    

    要制作一个在实践中演示这一点的测试程序,请参阅 SSE instructions: which CPUs can do atomic 16B memory operations?

    此外,80位x87 long double fld fstp 解码为2个单独的加载或存储UOP(加上一些ALU UOP)( on Intel Sandybridge-family 例如),因此可能64位部分和16位部分是单独的缓存访问,您可能会在 长双人 movaps [mem], xmm0

    任何Intel或AMD x86手册都不能保证任何大于64位的内容的原子性(除了 lock cmpxchg16b

    Why is integer assignment on a naturally aligned variable atomic? 对于规则。违反其中任何一项,你都可以看到撕裂


    对于保证的非原子性 全部的 跨越64B边界的SMP系统将始终工作

    超级保证始终工作(除了在与当前设计根本不同的CPU设计上):分割1GiB边界,因为这是最大的hugepage大小。(即使2MB hugepage中的4k拆分也算作页面拆分,需要进行两次TLB检查,以确定它们都在同一个hugepage中,并在当前硬件上产生相关的性能损失。当然,任何4k拆分也是缓存线拆分)。


    mov 存储或加载要么发生在中断之前,要么不发生。(单处理器甚至使读-修改-写类似于 add [mem], 1 原子与其他线程有关,尽管它与DMA或MMIO观察器无关。请参阅上的supercat的答案 Can num++ be atomic for 'int num'? )