1

当我怀疑 java 语言规范允许某些指令重新排序时,我想在 jcstress 测试中重现它。我怎样才能做到这一点?例如,在下面的代码中,加载和存储指令(我相信)允许在某些运行时环境中重新排序执行。但是,当我在 Intel x84_64 Ubuntu 中运行 jcstress 时,结果并未显示发生任何重新排序。

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

@JCStressTest
@Outcome(id = "0", expect = Expect.ACCEPTABLE,
         desc = "Default outcome.")
@Outcome(id = "2", expect = Expect.ACCEPTABLE_INTERESTING,
         desc = "Load-Store reordering happens.")
@State
public class ReorderingTest {

    int d;
    int e;
    int f;

    @Actor
    public void actor1() {
        int ee = e;     // Load
        d = 1;          // Store

        if (ee == 2) {
            f = 2;
        }
    }

    @Actor
    public void actor2() {
        if (d == 1) {
            e = 2;
        }
    }

    @Arbiter
    public void arbiter(I_Result r) {
        r.r1 = f;
    }
}
4

1 回答 1

1

我终于设法使用显式 JVM 选项观察原始 jcstress 测试中的重新排序,并用更多小时的时间运行它。

java -jar 目标/jcstress.jar -f 20 -XX:-TieredCompilation, -XX:+UnlockDiagnosticVMOptions, -XX:+StressLCM, -XX:+StressGCM

但是,在以下测试之一中,无论我运行测试多长时间,都不会观察到重新排序,尽管它看起来与其他测试相同。

// reordering can be observed!
@Actor
    public void actor1() {
        int ee = e;     // Load
        d = 1;          // Store

        if (ee == 2) {
            f = 2;
        }
    }
// reordering can be observed!
@Actor
    public void actor1() {
        f = e;          // Load & Store
        d = 1;          // Store
    }
// reordering NEVER observed!
@Actor
    public void actor1() {
        if (e == 2) f = 2;     // Load & conditionally Store
        d = 1;          // Store
    }
于 2019-05-20T19:14:43.190 回答