V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
luxinfl
V2EX  ›  程序员

关于 volatile 保证的有序性

  •  
  •   luxinfl · 2023-02-01 00:07:22 +08:00 · 2530 次点击
    这是一个创建于 659 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有个情况,感觉查出来的都不太对的样子。

    volatile 写会在之前加上一个 StoreStore 屏障、在后面加上一个 StoreLoad 屏障。 StoreLoad 的屏障不是代表禁止 volatile 写与后面可能有的 volatile 读和写重排序吗?

    但是好多博文的表格,在 volatile 写后面的普通读写都没有写 NO

    是否能重排序 第二个操作 第二个操作 第二个操作
    第一个操作 普通读 /写 volatile 读 volatile 写
    普通读 /写 NO
    volatile 读 NO NO NO
    volatile 写 NO NO

    所以到底可不可以重排

    13 条回复    2023-02-01 18:37:44 +08:00
    Azzsanjin
        1
    Azzsanjin  
       2023-02-01 00:59:02 +08:00   ❤️ 1
    奶奶滴,真滴卷,没必要搞这个吧,谁用个 volidate 还考虑读写屏障
    GeruzoniAnsasu
        2
    GeruzoniAnsasu  
       2023-02-01 01:25:32 +08:00
    volatile 阻止编译器重排序

    这与阻止 CPU 乱序执行

    是两回事。
    iseki
        3
    iseki  
       2023-02-01 02:37:28 +08:00 via Android
    你最好说清楚是什么语言的 volatile ,Java 和 C 里的完全不一样
    dangyuluo
        4
    dangyuluo  
       2023-02-01 06:28:31 +08:00   ❤️ 2
    C++里,volatile 只会起到两个作用:该变量不会被放进寄存器里,compiler will not reorder operations across the operation of this volatile variable.

    你说的东西是 CPU 层面的乱序执行,volatile 并不能起到 mfense, lfense, sfense 的效果
    Mogugugugu
        5
    Mogugugugu  
       2023-02-01 08:54:54 +08:00   ❤️ 1
    StoreLoad 屏障禁止 volatile 写与后面可能有的 volatile 读和写重排序,与第二个操作的普通读写无关啊。
    weidaizi
        6
    weidaizi  
       2023-02-01 09:57:52 +08:00
    楼主没说明语言,c/c++ 和 c#/java 中的 volatile 语义是不一样的。
    就 CPU 乱序执行来说:c/c++ 使用 volatile 是让编译器别来优化,但是并不提供多线程间的顺序和可见性保证;而如果是 c#/java ,使用 volatile 则可以保证变量在多线程间可见性,可以用于并发编程。
    zifangsky
        7
    zifangsky  
       2023-02-01 10:52:40 +08:00
    Java 中的 volatile 关键字应该只能保证原子性和可见性,有序性是不能保证的
    leonshaw
        8
    leonshaw  
       2023-02-01 11:07:31 +08:00
    默认你说的是 Java 。Spec 对 volatile 只要求了 release/acquire 语义以及 volatile 写 happens before 后续的 volatile 读。store-release 只需要前一个屏障,而后一个屏障是为了实现第二点 volatile 写-读保序,副作用是同时禁止了普通读写的重排。屏障不是 spec 的要求,只是一种实现方式。
    e9pWeUbh9PGCnp95
        9
    e9pWeUbh9PGCnp95  
       2023-02-01 12:05:20 +08:00
    c 标准原话
    Every access (both read and write) made through an lvalue expression of volatile-qualified type is considered an observable side effect for the purpose of optimization and is evaluated strictly according to the rules of the abstract machine (that is, all writes are completed at some time before the next sequence point). This means that within a single thread of execution, a volatile access cannot be optimized out or reordered relative to another visible side effect that is separated by a sequence point from the volatile access

    c 艹标准原话
    Every access (read or write operation, member function call, etc.) made through a glvalue expression of volatile-qualified type is treated as a visible side-effect for the purposes of optimization (that is, within a single thread of execution, volatile accesses cannot be optimized out or reordered with another visible side effect that is sequenced-before or sequenced-after the volatile access. This makes volatile objects suitable for communication with a signal handler, but not with another thread of execution, see std::memory_order). Any attempt to refer to a volatile object through a non-volatile glvalue (e.g. through a reference or pointer to non-volatile type) results in undefined behavior.

    Java 的标准原话等楼下补充
    joshu
        10
    joshu  
       2023-02-01 12:24:59 +08:00
    根据 cppref 上 atomic 章节的原话
    除了 ms vc++的 volatile 是携带有部分原子语义的,其它的编译器你均不能认为有原子语义
    另外,不要试图在 C 类语言上做自以为是的性能优化,C 的 atomic 库已经帮你在基于处理架构的优化了
    普通写是否原子,和体系结构有关

    java 不了解
    mmdsun
        11
    mmdsun  
       2023-02-01 13:07:42 +08:00 via iPhone
    楼主说的是什么语言?写 paper 还是?
    深入的话参考这个论文:
    http://www.rdrop.com/users/paulmck/scalability/paper/whymb.2010.06.07c.pdf
    b1ghawk
        12
    b1ghawk  
       2023-02-01 18:35:33 +08:00
    Re: volatile 写会在之前加上一个 StoreStore 屏障、在后面加上一个 StoreLoad 屏障。StoreLoad 的屏障不是代表禁止 volatile 写与后面可能有的 volatile 读和写重排序吗?

    StoreLoad 是否有效存在两个充分条件:
    1:后续指令是否是 volatile 读(决定是否需要 “插入” 或称 "执行" StoreLoad 屏障)。
    2:架构是否存在 StoreLoad 重排(决定被执行的 StoreLoad 屏障是有效操作还是空操作)。
    b1ghawk
        13
    b1ghawk  
       2023-02-01 18:37:44 +08:00
    另外 TSO + StoreLoad 差不多就是 SC 了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2856 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 14:49 · PVG 22:49 · LAX 06:49 · JFK 09:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.