V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
CrazyRain0001
V2EX  ›  问与答

老哥们请教个基础问题, c/c++ 对基础数据类型的赋值是原子操作吗?

  •  
  •   CrazyRain0001 · 244 天前 · 927 次点击
    这是一个创建于 244 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前景提要

    之前我写代码同步多线程访问时,基础数据类型都加的有 atomic 关键字,后来领导看到了说基础数据类型不加也是原子操作。 今天面试时,面试官说基数数据类型访问不是原子的,而且和编译器架构无关。

    我的理解

    应该加 atomic 关键字,但在现代 x86 等架构的 cpu 上对 bool ,int 类型的操作是原子的,或者说视同原子的。

    18 条回复    2023-08-30 10:37:09 +08:00
    mtrec
        2
    mtrec  
       244 天前
    面试官是对的 atomic 之后是原子的 里面还涉及更深一层的 memory order

    “在现代 x86 等架构的 cpu 上对 bool ,int 类型的操作是原子的,或者说视同原子的”
    不对 在多核多线程情况下 每个核都有自己的独占的寄存器/L1/L2 cache 不能保证原子性
    billlee
        3
    billlee  
       244 天前
    是原子的,原子意味着着写一个 memory word 不会出现高位写入完成,而低位没完成写入的情况
    inhzus
        4
    inhzus  
       244 天前
    不用 atomic 有可见性问题
    ajaxgoldfish
        5
    ajaxgoldfish  
       244 天前 via Android
    我记得有本书讲的是和 CPU 的位数有关,还和是否为浮点数有关。其中在某些条件下是原子的,超过限定条件就有可能不是原子的。虽然记得不清楚但是应该能否定面试官说的
    hanguofu
        6
    hanguofu  
       244 天前 via Android
    取决于硬件是否支持?
    shawnsh
        7
    shawnsh  
       243 天前 via Android
    怎么牵扯到编译器的架构了
    CrazyRain0001
        8
    CrazyRain0001  
    OP
       243 天前
    @shawnsh 写漏了,编译器优化和 cpu 架构
    CrazyRain0001
        9
    CrazyRain0001  
    OP
       243 天前
    @inhzus 对,这点同意
    CrazyRain0001
        10
    CrazyRain0001  
    OP
       243 天前
    @xtreme1 看文档我的理解是做了内存一致性保证的?
    https://img.cxlljj.top/images/2023/08/29/image.png
    CrazyRain0001
        11
    CrazyRain0001  
    OP
       243 天前
    @mtrec 我看这边祖传代码一直是直接用的,不能保证的话不是很容易崩吗?
    sghwn2
        12
    sghwn2  
       243 天前
    @mtrec 那如果加了 volatile 可以吗
    Caturra
        13
    Caturra  
       243 天前
    你让面试官翻译翻译这段话

    8.1.1 Guaranteed Atomic Operations

    The Intel486 processor (and newer processors since) guarantees that the following basic memory operations will always be carried out atomically:
    - Reading or writing a byte
    - Reading or writing a word aligned on a 16-bit boundary
    - Reading or writing a doubleword aligned on a 32-bit boundary

    The Pentium processor (and newer processors since) guarantees that the following additional memory operations will always be carried out atomically:
    - Reading or writing a quadword aligned on a 64-bit boundary
    - 16-bit accesses to uncached memory locations that fit within a 32-bit data bus

    The P6 family processors (and newer processors since) guarantee that the following additional memory operation will always be carried out atomically:
    - Unaligned 16-, 32-, and 64-bit accesses to cached memory that fit within a cache line
    mtrec
        14
    mtrec  
       243 天前 via Android
    @sghwn2 加了 volatile 也不行 volatile 是提醒编译器别优化 可能别的地方也会改这个变量 每次用到的话从内存里重新取值 但是还是没解决多线程下可能的编译器 CPU 指令重排 memory order 能提供更精细的重排控制
    mtrec
        15
    mtrec  
       243 天前 via Android
    @CrazyRain0001 我不了解你那边代码的情况无法回答你 建议你可以看看 std atomic 相关的内容 cppcon 有一期就是解释这个原理的
    CrazyRain0001
        16
    CrazyRain0001  
    OP
       243 天前
    @mtrec
    > 是这个吗? https://www.bilibili.com/video/BV1Vx411V7Rd/?p=31
    简单看了下,他确实指出了代码里对类似 int i 的基础操作是非原子的,包含了不同的 CPU 指令。但看 13 楼引用的这个 intel 开发文档也确实说明了某些 CPU 对于 bool(byte)或者 int(doubleword aligned on a 32-bit boundary)的读写是原子操作 Certain basic memory transactions (such as reading
    or writing a byte in system memory),所以可以认为这是一个语言层面未作保证只是某些 CPU 支持的特性吗?
    mtrec
        17
    mtrec  
       243 天前 via Android
    @CrazyRain0001 对 是这些视频 这个跟 13 楼讲的不冲突 就用 cppcon 里两个线程跑++i 的例子 CPU 可以保证两次都原子性的从内存读到 i 的值 然后分别一步步写到两个线程各自的 L2/L1 cache 和寄存器里 两个自增也能在 1 tick 完成 原子性的 然后再一步步地 commit 回 L3 再内存 就可能出现覆盖而得不到你想要结果 因为两个线程没有同步机制 而 std atomic 相当于一种硬件同步机制或者硬件锁 底层是通过 CPU 指令来实现的 现在在 ARM 或者 GPU 上支持还不算完善 这些 atomic 操作也是很多 lock free 数据结构的基础
    CrazyRain0001
        18
    CrazyRain0001  
    OP
       242 天前
    @mtrec #17 好的!感谢回答!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1072 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 18:44 · PVG 02:44 · LAX 11:44 · JFK 14:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.