关于 volatile 保证的有序性 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
luxinfl
V2EX    程序员

关于 volatile 保证的有序性

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

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

    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     Solana     4289 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 04:07 PVG 12:07 LAX 20:07 JFK 23:07
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86