【问题标题】:Do LoadStore and StoreStore are both needed for a final variable and lazySet implementation?最终变量和lazySet实现都需要LoadStore和StoreStore吗?
【发布时间】:2014-11-16 10:14:34
【问题描述】:

我正在阅读 Hans 的一篇文章,他认为 LoadStore 在lazySet 或最终变量写入之前也需要。

他展示了一个我无法理解的特定比赛条件。

http://www.hboehm.info/c++mm/no_write_fences.html 见 收件人写入对象。

x.a = 43 的线程 1 存储如何通过 StoreStore 屏障完成是非常违反直觉的,因为这样就完全违背了 StoreStore 屏障的目的。

这里有类似的论点http://shipilev.net/blog/2014/all-fields-are-final/

在此处复制 Shiplev:

“JSR 133 Cookbook 仅需要 StoreStore,但可能还需要 LoadStore 屏障。这涵盖了一个极端情况,即 final 字段正在从其他经历激烈更新的字段中初始化。 这种极端情况可以通过运行时优化来启用,它会发现不需要最终存储,将值放在局部变量中,从而打破 StoreStore 单独的排序保证“

*运行时如何确定不需要最终存储,如果负载正在通过/重新排序 StoreStore 屏障,那么存储到本地变量也正在通过/重新排序与 storeStore 屏障,这是我不需要的部分很明白,为什么store to local variable可以用StoreStore Barrier重新排序。运行时如何/何时可以确定存储到局部变量就足够了 *

如果有人可以通过一些简单的例子更详细地解释他们都提到的竞争条件是什么,那将是非常有帮助的。

【问题讨论】:

    标签: java performance concurrency compiler-optimization volatile


    【解决方案1】:

    我帖子中的引用令人困惑和过时,我很久以前就修复了;对困惑感到抱歉。欢迎您在下次发生时给我发邮件。真的,它遵循Hans Boehm's example,这很简单:

    x.a = 0; x.a++;
    x_init.store_write_release(true);
    

    并且在线程 2 中使用 x 的代码会更新它,例如

    if (x_init.load_acquire())
        x.a = 42;
    

    如果线程 1 中的发布存储被限制为仅确保 完成先前的存储(写入),线程 1 中 x.a 的负载(部分 x.a++) 可以通过赋值 x_init 有效地重新排序, 因此可以看到一个值 42,导致 x.a 被初始化为 43.

    【讨论】:

    • 谢谢,我已经在并发邮件列表中得到了你的答复 :)
    猜你喜欢
    • 1970-01-01
    • 2014-06-20
    • 2014-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-07
    • 2021-06-08
    • 1970-01-01
    相关资源
    最近更新 更多