JIT是否可以在某些表达式中将两个易失性读取折叠为一个?

JIT是否可以在某些表达式中将两个易失性读取折叠为一个?,第1张

JIT是否可以在某些表达式中将两个易失性读取折叠为一个?

简短答案:

是的,允许这种优化。折叠两个顺序的读取 *** 作将产生可观察到的 原子 序列行为,但不会表现为 *** 作的 重新排序
。在单个执行线程上执行的任何动作序列都可以作为原子单元执行。通常,很难确保一系列 *** 作以原子方式执行,并且很少会导致性能提高,因为大多数执行环境都会
引入开销 以原子方式执行项目。

在原始问题给出的示例中,所讨论的 *** 作序列如下:

read(a)read(a)

原子地执行这些 *** 作可确保第一行读取的值等于第二行读取的值。此外,这意味着在第二行读取的值是

a
在执行第一次读取时包含的值(反之亦然,因为根据程序的可观察执行状态,两个原子读取 *** 作都同时发生)。所讨论的优化将第一读取的值重用于第二读取,该优化等效于编译器和/或JIT以原子方式执行该序列,因此是有效的。


原来较长的答案:

Java内存模型使用 部分排序 之前发生的事件来
描述 *** 作。为了表达的限制,即第一次读

r1
和二读
r2
a
,不能折叠,则需要证明一些 *** 作语义需要在它们之间出现。

使用

r1
和进行的线程 *** 作
r2
如下:

--> r(a) --> r(a) --> add -->

为了表达的需要的东西(比如说

y
之间)的谎言
r1
r2
,你需要要求
r1
的之前发生
y
y
之前发生
r2
。碰巧的是,没有规则在“ 先发生后发生” 关系的左侧出现读取 *** 作。您可以得到的最接近的说法是:
y
before-before
r2
,但是部分顺序也可以
y
发生在before之前
r1
,因此会破坏读取 *** 作。

如果不存在 要求 运算符介于

r1
和之间的方案
r2
,那么您可以声明 没有运算符
出现在之间
r1
r2
并且不违反语言的必需语义。使用单个读取 *** 作将等同于此声明。

编辑 我的答案被否决了,所以我将进一步探讨其他细节。

以下是一些相关问题:

  • 是Java编译器或JVM 需要 折叠这些读取 *** 作?

否。在add表达式中使用的表达式

a
a
表达式不是常数表达式,因此不需要将它们折叠。

  • __JVM 是否 折叠这些读取 *** 作?

为此,我不确定答案。通过编译程序并使用

javap-c
,很容易看出Java编译器不会折叠这些读取 *** 作。不幸的是,要证明JVM不会折叠 *** 作(甚至更难于处理器本身)并不容易。

  • __JVM 是否应该 折叠这些读取 *** 作?

可能不是。每次优化都需要花费时间才能执行,因此在分析代码所花费的时间与您期望获得的收益之间是一个平衡。事实证明,某些优化(例如数组边界检查消除或检查空引用)对现实应用程序具有
广泛的 好处。该特定优化可能会提高性能的唯一情况是两个相同的读取 *** 作顺序出现的情况。

此外,如对此答案的响应以及其他答案所示,此特定更改将导致用户可能不希望的某些应用程序发生 意外的 行为更改。

编辑2:
关于拉斐尔(Rafael)的描述,它声称两个读取 *** 作无法重新排序。该语句旨在突出显示以下事实,即

a
按以下顺序缓存的读取 *** 作可能会产生错误的结果:

a1 = read(a)b1 = read(b)a2 = read(a)result = op(a1, b1, a2)

假设最初

a
b
有其默认值0。然后你执行只是第一
read(a)

现在,假设另一个线程执行以下序列:

a = 1b = 1

最后,假设第一个线程执行line

read(b)
。如果要缓存的原始读取值
a
,将以以下调用结束:

op(0, 1, 0)

这是不正确的。由于更新后的值

a
是在写入之前存储的
b
,因此无法读取该值
b1 = 1
,然后再 读取该值
a2 =0
。如果不进行缓存,则正确的事件顺序将导致随后的调用。

op(0, 1, 1)

但是,如果您要问“是否有任何方法

a
可以缓存读取的内容?”,答案是肯定的。如果您可以作为 原子单位 在第一个线程序列中执行 所有三个
读取 *** 作,则可以缓存该值。虽然很难跨多个变量进行同步,并且很少能提供机会优化优势,但是可以肯定遇到异常。例如,假设和分别为4个字节,并且它们在内存中顺序出现,并在8字节边界上对齐。64位进程可以将序列实现为原子64位加载 *** 作,这将允许
__
a``b``a``read(a) read(b)``a
被缓存(有效地将所有三个读取 *** 作视为一个原子 *** 作,而不仅仅是前两个)。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5507667.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-13
下一篇 2022-12-13

发表评论

登录后才能评论

评论列表(0条)

保存