首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JCStress -奇怪的易失性和静态关键字行为

JCStress -奇怪的易失性和静态关键字行为
EN

Stack Overflow用户
提问于 2021-10-10 17:22:39
回答 1查看 116关注 0票数 1

我有一个简单的Jc应激测试:

代码语言:javascript
复制
package io.denery;


import org.openjdk.jcstress.annotations.*;
import org.openjdk.jcstress.infra.results.IIII_Result;

@JCStressTest
@Outcome(expect = Expect.ACCEPTABLE_INTERESTING)
@State
public class RaceIRIWTest {
    volatile int x, y;

    @Actor
    public void actor1() {
            x = 1;
    }

    @Actor
    public void actor2() {
            y = 1;
    }

    @Actor
    public void actor3(IIII_Result r) {
            r.r1 = x;
            r.r2 = y;
    }

    @Actor
    public void actor4(IIII_Result r) {
            r.r3 = y;
            r.r4 = x;
    }
}

但这项测试的结果是:

OK io.denery.RaceIRIWTest (JVM args:-XX:+UnlockDiagnosticVMOptions,-XX:+WhiteBoxAPI,-XX:-RestrictContended,-Dfile.coding=UTF-8,-Duser.country=RU,-Duser.language=en,-Duser.variant,-XX:-TieredCompilation,-XX:+StressLCM,-XX:+StressGCM,-XX:+StressIGVN)观察到状态事件的期望解释

0,0,0,0,0 22,180,923 ACCEPTABLE_INTERESTING

0,0,0,1721,581 ACCEPTABLE_INTERESTING

0,0,1,0 13,347 ACCEPTABLE_INTERESTING

0,0,1,1 456,971 ACCEPTABLE_INTERESTING

0,1,0,0,0 344,068 ACCEPTABLE_INTERESTING

0,1,0,1 36 ACCEPTABLE_INTERESTING

0,1,1,0 528,641 ACCEPTABLE_INTERESTING

0,1,1,1258,265 ACCEPTABLE_INTERESTING

1,0,0,0,0 204,088 ACCEPTABLE_INTERESTING

1,0,0,1 667,580 ACCEPTABLE_INTERESTING

1,0,1,1 94,877 ACCEPTABLE_INTERESTING

1,1,0,0 663,159 ACCEPTABLE_INTERESTING

1,1,0,1 306,251 ACCEPTABLE_INTERESTING

1,1,1,0 128,608 ACCEPTABLE_INTERESTING

1,1,1,1 18,838,186 ACCEPTABLE_INTERESTING

我们看到了竞争条件,但是如果我将static放到volatile int x, y中并删除volatile关键字,那么jc应激测试的结果将是:

OK io.denery.RaceIRIWTest (JVM args:-XX:+UnlockDiagnosticVMOptions,-XX:+WhiteBoxAPI,-XX:-RestrictContended,-Dfile.coding=UTF-8,-Duser.country=RU,-Duser.language=en,-Duser.variant,-XX:-TieredCompilation,-XX:+StressLCM,-XX:+StressGCM,-XX:+StressIGVN)观察到状态事件的期望解释

1,1,1,1 100,299,061 ACCEPTABLE_INTERESTING

为什么不修复竞争条件,但静态关键字修复它?还是Jc应激的问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-11 06:14:34

我不是JCStress专家。

但是您所缺少的是,您需要指定法律结果,请参阅下面的链接以获得一个示例。

https://github.com/openjdk/jcstress/blob/master/jcstress-samples/src/main/java/org/openjdk/jcstress/samples/concurrency/mutex/Mutex_02_DekkerAlgorithm.java

禁例

在IRIW测试中,您希望防止不同CPU对不同地址的存储出现故障。因此,您希望防止参与者3看到r1=1, r2=0 (在y之前看到x )。演员4看到r3=1, r4=0 ( yx之前也是如此)。所以被禁止的案例是1,0,1,0

易失性

当我用易失性检查结果时,不会遇到禁止的情况。其原因是,带有volatile的示例不存在数据竞争,因此它只产生连续一致(SC)执行。对于SC,在加载/存储上总是会有一些总订单来解释执行。由于有一个总订单,它还将订购存储到不同的地址,由不同的CPU发出。此外,SC将防止负载被重新排序,因为SC执行需要与程序顺序(PO)保持一致。

静态不挥发

带有静态的示例包含一个数据竞赛,因为在读和写之间的边界之前没有发生。因此,只有使用静态时,才允许查看禁止执行的1,0,1,0

一个简单的解释是,如果JIT或CPU允许无序负载(例如ARM),那么JIT或CPU会重新排序这两个负载。我的猜测是,您只看到1,1,1,1,因为xy并没有被JCStress取消设置;但是,我对JCStress还不够了解。

多余

为了使这个例子更有趣,我将使两个商店变得不透明,加载不透明的负载,并在这两个负载之间设置一个LoadLoad围栏,以确保它们按照顺序执行。不透明将确保加载/存储不会被优化,它将提供原子性(基本保证),但不会为不同地址的加载/存储提供任何排序保证。因此,您将测试CPU的内存一致性保证。

IRIW不应该在现代CPU上失败,因为它们是多拷贝原子的,我所知道的唯一能够显示这种行为的CPU就是PowerPC。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69517384

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档