Java 是否仅更改缓存中已修改字段的值?
Does Java change the value of only the modified fields from cache?
按照我的理解,当cache回写到主存的时候,会写整个cache block。这可能包括未修改的 bytes/words,因为脏位是在整个缓存块上设置的。
在此,我假设 CPU 架构通常不会在字节级别上跟踪 'dirtiness'。如果 所有 目前的体系结构确实在字节级别上进行跟踪,请随时纠正我的假设。
比如说,两个 java 字段,比如 a
和 b
并排存在并且具有相同的标签。因此,在缓存时,它们将被放置在同一个缓存块中。
假设核心中有一个线程 运行,它只更新 a
的值,而不更新 b
的值。那么, a
和 b
的值实际上是否会从缓存中更新到主内存中?
或者 java 是否有一些东西可以确保只有 a
的值被更新,假设只有 a
被改变了?
java在这里也有作用吗?还是完全依赖于 CPU 架构?
我最关心的问题
最初假设,a=1
,b=1
假设我们有两个线程 T1 和 T2。 T1 只做一件事,它设置 a=2
。同样,T2 做 b=2
.
假设我们有一个多核环境,其核心分别为 C1 和 C2 运行 T1 和 T2。两者都缓存值 a=1, b=1
.
假设 T1 先完成。 C1的缓存被写回。
所以,现在,在主内存中,a=2, b=1
。
现在,T2 完成了。现在当缓存被写回时,它是否设置 a=1, b=2
因为 C2 在其缓存中有 a=1
?
或者Java对此有任何保证吗?
假设没有 Happens Before/After 关系成立。没有同步或易失性或任何其他类似的东西。
欢迎随时纠正我的任何假设。
吹毛求疵:理论上写不需要去主存;它们可以无限期地保留在缓存中,具体取决于所使用的缓存一致性算法。
您提到的问题称为单词撕裂,JVM 应该防止它。
查看以下链接:
- https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.6
- https://shipilev.net/blog/2014/jmm-pragmatics/#_part_ii_word_tearing
我不熟悉其他体系结构,但在 X86 上可以在字节级别完成加载和存储。一个 n 字节字段,总是 n 字节对齐;所以它永远不会被分割成 2 个缓存行。由于 Java 中的布尔值存储在一个字节中,因此在 X86 上不会发生字撕裂。
按照我的理解,当cache回写到主存的时候,会写整个cache block。这可能包括未修改的 bytes/words,因为脏位是在整个缓存块上设置的。
在此,我假设 CPU 架构通常不会在字节级别上跟踪 'dirtiness'。如果 所有 目前的体系结构确实在字节级别上进行跟踪,请随时纠正我的假设。
比如说,两个 java 字段,比如 a
和 b
并排存在并且具有相同的标签。因此,在缓存时,它们将被放置在同一个缓存块中。
假设核心中有一个线程 运行,它只更新 a
的值,而不更新 b
的值。那么, a
和 b
的值实际上是否会从缓存中更新到主内存中?
或者 java 是否有一些东西可以确保只有 a
的值被更新,假设只有 a
被改变了?
java在这里也有作用吗?还是完全依赖于 CPU 架构?
我最关心的问题
最初假设,a=1
,b=1
假设我们有两个线程 T1 和 T2。 T1 只做一件事,它设置 a=2
。同样,T2 做 b=2
.
假设我们有一个多核环境,其核心分别为 C1 和 C2 运行 T1 和 T2。两者都缓存值 a=1, b=1
.
假设 T1 先完成。 C1的缓存被写回。
所以,现在,在主内存中,a=2, b=1
。
现在,T2 完成了。现在当缓存被写回时,它是否设置 a=1, b=2
因为 C2 在其缓存中有 a=1
?
或者Java对此有任何保证吗?
假设没有 Happens Before/After 关系成立。没有同步或易失性或任何其他类似的东西。
欢迎随时纠正我的任何假设。
吹毛求疵:理论上写不需要去主存;它们可以无限期地保留在缓存中,具体取决于所使用的缓存一致性算法。
您提到的问题称为单词撕裂,JVM 应该防止它。
查看以下链接:
- https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.6
- https://shipilev.net/blog/2014/jmm-pragmatics/#_part_ii_word_tearing
我不熟悉其他体系结构,但在 X86 上可以在字节级别完成加载和存储。一个 n 字节字段,总是 n 字节对齐;所以它永远不会被分割成 2 个缓存行。由于 Java 中的布尔值存储在一个字节中,因此在 X86 上不会发生字撕裂。