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

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

  •  
  •   CrazyRain0001 · 2023-08-28 18:07:25 +08:00 · 1165 次点击
    这是一个创建于 451 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前景提要

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

    我的理解

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

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

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

    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  
       2023-08-29 12:14:10 +08:00 via Android
    @sghwn2 加了 volatile 也不行 volatile 是提醒编译器别优化 可能别的地方也会改这个变量 每次用到的话从内存里重新取值 但是还是没解决多线程下可能的编译器 CPU 指令重排 memory order 能提供更精细的重排控制
    mtrec
        15
    mtrec  
       2023-08-29 12:16:21 +08:00 via Android
    @CrazyRain0001 我不了解你那边代码的情况无法回答你 建议你可以看看 std atomic 相关的内容 cppcon 有一期就是解释这个原理的
    CrazyRain0001
        16
    CrazyRain0001  
    OP
       2023-08-29 14:36:54 +08:00
    @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  
       2023-08-29 18:59:28 +08:00 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
       2023-08-30 10:37:09 +08:00
    @mtrec #17 好的!感谢回答!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1158 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 18:08 · PVG 02:08 · LAX 10:08 · JFK 13:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.