JCStress的结果是否可以被描述为缓存而非重排序的结果?

huangapple go评论64阅读模式
英文:

Can JCStress outcome can be described as the result of caching instead of reordering?

问题

I modified one of JCStress examples:

@JCStressTest
@Outcome(id = "0, 0", expect = ACCEPTABLE, desc = "Doing both reads early.")
@Outcome(id = "1, 1", expect = ACCEPTABLE, desc = "Doing both reads late.")
@Outcome(id = "1, 0", expect = ACCEPTABLE, desc = "First is visible but not second.")
@Outcome(id = "0, 1", expect = ACCEPTABLE_INTERESTING, desc = "Second is visible but not first.")
@State
public class Reordering {
    int first;
    int second;

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

    @Actor
    public void actor2(II_Result r) {
        r.r2 = second;
        r.r1 = first;
    }
}

which gave me the following result:

RESULT SAMPLES FREQ EXPECT DESCRIPTION
0, 0 737,822,067 26.75% Acceptable Doing both reads early.
0, 1 1,838,578 0.07% Interesting Second is visible but not first.
1, 0 13,081,701 0.47% Acceptable First is visible but not second.
1, 1 2,005,604,406 72.71% Acceptable Doing both reads late.

The Acceptable results are easy to understand, but I have some questions regarding the Interesting outcome. From what I understood, JVM can optimize the code and change the order of instructions, meaning the first function could roughly be translated to:

public void actor1() {
    second = 1;
    first = 1;
}

which could explain why the Interesting result was achieved. My question is: is it possible that the Interesting result was achieved not due to the code reordering done by JVM but rather by "caching" the first and not making it visible to the thread running actor2 method since the field was not a volatile one? By caching I am talking about storing it in the CPU register/store buffer and making it not visible to the other thread.

英文:

I modified one of JCStress examples:

@JCStressTest
@Outcome(id = "0, 0", expect = ACCEPTABLE, desc = "Doing both reads early.")
@Outcome(id = "1, 1", expect = ACCEPTABLE, desc = "Doing both reads late.")
@Outcome(id = "1, 0", expect = ACCEPTABLE, desc = "First is visible but not second.")
@Outcome(id = "0, 1", expect = ACCEPTABLE_INTERESTING, desc = "Second is visible but not first.")
@State
public class Reordering {
    int first;
    int second;

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

    @Actor
    public void actor2(II_Result r) {
        r.r2 = second;
        r.r1 = first;
    }
}

which gave me the following result:

RESULT SAMPLES FREQ EXPECT DESCRIPTION
0, 0 737,822,067 26.75% Acceptable Doing both reads early.
0, 1 1,838,578 0.07% Interesting Second is visible but not first.
1, 0 13,081,701 0.47% Acceptable First is visible but not second.
1, 1 2,005,604,406 72.71% Acceptable Doing both reads late.

The Acceptable results are easy to understand but I have some questions regarding the Interesting outcome. From what I understood, JVM can optimize the code and change the order of instructions meaning the first function could roughly be translated to:

public void actor1() {
    second = 1;
    first = 1;
}

which could explain why the Interesting result was achieved. My question is: is it possible that the Interesting result was achieved not due to the code reordering done by JVM but rather by "caching" the first and not making it visible to the thread running actor2 method since the field was not a volatile one? By caching I am talking about storing it in the CPU register/store buffer and making it not visible to the other thread.

答案1

得分: 0

在X86上,存储操作不能与其他存储操作重新排序,加载操作也不能与其他加载操作重新排序(只有较旧的存储操作和较新的加载操作到不同地址可以重新排序)。因此,如果编译器不打乱顺序,那么在X86上不会出现这种情况。这是因为X86的强内存模型:TSO(总存储顺序)。

然而,如果您选择了具有较弱内存模型的CPU,例如ARM或RISC-V,那么此类重新排序可能会发生。

英文:

On the X86 stores can't be reordered with other stores and loads can't be reordered with other loads (only an older store and a newer load to a different address can be reordered). So if the compiler would not mess up the order, then on the X86 this can't fail. This is because of the strong memory model of X86: TSO (Total Store Order).

However, if you would go for a CPU with a weaker memory model e.g. ARM or RISC-V, then such reordering could happen.

huangapple
  • 本文由 发表于 2023年3月31日 21:40:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75899212.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定