VarHandle get/setOpaque [英] VarHandle get/setOpaque

查看:91
本文介绍了VarHandle get/setOpaque的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力了解 VarHandle :: setOpaque VarHandle :: getOpaque 到底在做什么.到目前为止,这并不容易-我认为有一些事情(但是我不会在问题本身中提出它们,而不是为了弄混水而已),但是总的来说,这充其量只能说是误导性的对我来说.

I keep fighting to understand what VarHandle::setOpaque and VarHandle::getOpaque are really doing. It has not been easy so far - there are some things I think I get (but will not present them in the question itself, not to muddy the waters), but overall this is miss-leading at best for me.

文档:

返回按程序顺序访问的变量的值...

Returns the value of a variable, accessed in program order...

请理解,如果我有以下情况:

Well in my understanding if I have:

int xx = x; // read x
int yy = y; // read y

这些读取可以重新排序.另一方面,如果我有:

These reads can be re-ordered. On the other had if I have:

// simplified code, does not compile, but reads happen on the same "this" for example
int xx = VarHandle_X.getOpaque(x); 
int yy = VarHandle_Y.getOpaque(y);

这次不能重新订购吗?这就是程序顺序"的意思吗?我们是否在谈论在这里插入障碍物以禁止这种重新排序?如果是这样,由于这是两个负载,是否会达到相同的效果?通过:

This time re-orderings are not possible? And this is what it means "program order"? Are we talking about insertions of barriers here for this re-ordering to be prohibited? If so, since these are two loads, would the same be achieved? via:

 int xx = x;
 VarHandle.loadLoadFence()
 int yy = y;

但这变得更加棘手:

...但是不能保证相对于其他线程的内存排序效果.

... but with no assurance of memory ordering effects with respect to other threads.

我无法拿出一个例子来假装我理解这部分.

I could not come up with an example to even pretend I understand this part.

在我看来,本文档针对的是那些确切知道他们在做什么的人(而我绝对不是一个人)...所以有人可以在这里阐明一些观点吗?

It seems to me that this documentation is targeted at people who know exactly what they are doing (and I am definitely not one)... So can someone shed some light here?

推荐答案

请问我是否理解:

Well in my understanding if I have:

int xx = x; // read x
int yy = y; // read y

这些读物可以重新排序.

These reads can be re-ordered.

这些读取可能不仅碰巧被重新排序,而且可能根本不发生.该线程可能使用一个旧的,先前读取的 x 和/或 y 值,或者它先前已写入这些变量的值,而实际上,写入可能不是尚未执行,因此读取线程"可能会使用值,那时没有其他线程会知道并且不在堆内存中(也许永远不会).

These reads may not only happen to be reordered, they may not happen at all. The thread may use an old, previously read value for x and/or y or values it did previously write to these variables whereas, in fact, the write may not have been performed yet, so the "reading thread" may use values, no other thread may know of and are not in the heap memory at that time (and probably never will).

另一方面,如果我有:

On the other had if I have:

// simplified code, does not compile, but reads happen on the same "this" for example
int xx = VarHandle_X.getOpaque(x); 
int yy = VarHandle_Y.getOpaque(y);

这次不能重新订购吗?这就是程序顺序"的意思吗?

This time re-orderings are not possible? And this is what it means "program order"?

简单地说,不透明读写的主要特征是它们实际上会发生.这意味着它们不能相对于至少具有相同强度的其他内存访问进行重新排序,但这对普通的读写没有影响.

Simply said, the main feature of opaque reads and writes, is, that they will actually happen. This implies that they can not be reordered in respect to other memory access of at least the same strength, but that has no impact for ordinary reads and writes.

术语程序顺序由JLS定义:

t 程序顺序是一个总顺序,反映了根据 t的线程内语义执行这些动作的顺序..

… the program order of t is a total order that reflects the order in which these actions would be performed according to the intra-thread semantics of t.

这是评估顺序为表达式和语句指定.只要只涉及一个线程,我们感知效果的顺序就可以.

That’s the evaluation order specified for expressions and statements. The order in which we perceive the effects, as long as only a single thread is involved.

我们是否在谈论在这里插入障碍物以禁止这种重新排序?

Are we talking about insertions of barriers here for this re-ordering to be prohibited?

不,不涉及任何障碍,这可能是短语"……但不能保证相对于其他线程的内存排序效果"的意图.

No, there is no barrier involved, which might be the intention behind the phrase "…but with no assurance of memory ordering effects with respect to other threads".

也许我们可以说不透明访问的作用类似于Java之前的 volatile ,它强制执行读取访问以查看最新的堆内存值(这只有在写入端也使用时才有意义)不透明或什至更强的模式),但对其他读取或写入没有影响.

Perhaps, we could say that opaque access works a bit like volatile was before Java 5, enforcing read access to see the most recent heap memory value (which makes only sense if the writing end also uses opaque or an even stronger mode), but with no effect on other reads or writes.

一个典型的用例是一个取消或中断标志,该标志不应该建立先发生"关系.通常,已停止的后台任务对在发出信号之前已停止的任务所感知的动作没有兴趣,但是只会结束其自身的活动.因此,以不透明模式写入和读取标志足以确保最终注意到信号(与正常访问模式不同),但不会对性能造成任何其他负面影响.

A typical use case would be a cancellation or interruption flag that is not supposed to establish a happens-before relationship. Often, the stopped background task has no interest in perceiving actions made by the stopping task prior to signalling, but will just end its own activity. So writing and reading the flag with opaque mode would be sufficient to ensure that the signal is eventually noticed (unlike the normal access mode), but without any additional negative impact on the performance.

同样,后台任务可以编写进度更新(如百分比数字),报告线程应该及时注意到该进度更新,而在发布以下内容之前不需要 happens-before 关系.最终结果.

Likewise, a background task could write progress updates, like a percentage number, which the reporting (UI) thread is supposed to notice timely, while no happens-before relationship is required before the publication of the final result.

如果您只想对 long double 进行原子访问,而又没有任何其他影响,这也很有用.

It’s also useful if you just want atomic access for long and double, without any other impact.

由于使用 final 字段的真正不可变对象不受数据争夺的影响,因此您可以使用不透明模式及时发布不可变对象,而没有发布/获取模式发布的广泛影响.

Since truly immutable objects using final fields are immune to data races, you can use opaque modes for timely publishing immutable objects, without the broader effect of release/acquire mode publishing.

一种特殊情况是定期检查状态以获取期望值更新,并在可用时以更强的模式查询该值(或显式执行匹配的fence指令).原则上,无论如何都只能在写入和后续读取之间建立先于关系,但是由于优化程序通常没有能力识别这种线程间用例,因此性能至关重要代码可以使用不透明访问来优化这种情况.

A special case would be periodically checking a status for an expected value update and once available, querying the value with a stronger mode (or executing the matching fence instruction explicitly). In principle, a happens-before relationship can only be established between the write and its subsequent read anyway, but since optimizers usually don’t have the horizon to identify such a inter-thread use case, performance critical code can use opaque access to optimize such scenario.

这篇关于VarHandle get/setOpaque的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆