![]() |
1
6
将变量标记为“volatile”有两种效果。 1) 读和写具有获取和释放语义,因此其他内存位置的读和写不会相对于该内存位置的读和写“在时间上向前和向后移动”(这是一种简化,但你接受我的观点。) 2) 抖动生成的代码不会“缓存”逻辑上似乎不变的值。
但在我看来,后一点似乎非常相关。如果在非易失性变量上有自旋锁:
jitter在其权限范围内生成此代码,就像您编写的代码一样
不管它是否真的这样做,我不知道,但它有权利这样做。如果您希望代码在循环的每一次循环中实际重新检查属性,那么将其标记为volatile是正确的方法。 |
![]() |
2
4
问题是阅读线程是否会 曾经 看到变化了吗。这不仅仅是它是否看到它的问题 立即 . 坦率地说,我已经放弃了试图理解波动性——我知道这并不完全是我过去认为的那样。。。但我也知道,如果在阅读过程中没有任何记忆障碍,你可能永远都在阅读相同的旧数据。 |
![]() |
3
2
|
![]() |
4
2
最后 请参阅对内存地址的更改。即使没有锁或内存障碍。锁和屏障只会确保它以相对顺序(w.r.t其他指令)发生,这样它对您的程序来说似乎是正确的。 问题不在于缓存一致性(我希望Joe Duffy的书不会犯这个错误)。缓存保持一致性——只是这需要时间,处理器不必等待这种情况发生——除非您强制执行。因此,处理器将继续执行下一条指令,这可能会发生,也可能不会发生 之前 因为 因此,读取可能看起来很旧或来自过时的缓存,但实际上它发生的时间比预期的要早(通常是因为前瞻和分支预测)。当它真的 读,缓存是一致的,从那时起它就改变了。因此,当您阅读它时,该值并不陈旧,但当您需要它时,它就已经存在了。你只是读得太快了-(
或者两者兼而有之。 最后 在C#中,我对CLR了解不够,无法知道一个值可以在寄存器中保留多长时间,也无法确保从内存中获得真正的重读。您已经失去了“弱”易失性。
但我看不到任何保证。如果您可以将易失性读取限制在代码中的某个特定点,该点通常是,但不太经常(即在一段时间内开始下一个任务(things_to_do)循环),那么这可能是您所能做的最好方法。 |
![]() |
5
1
|
![]() |
6
1
被缓存中有内存的其他CPU看到)。在这方面,volatile将有助于确保优化器不会通过读取寄存器中缓存的值来优化内存访问(无论如何都要通过缓存)。C#文档似乎很清楚这一点。同样,应用程序程序员通常不必自己处理缓存一致性问题。 我强烈建议阅读免费提供的论文《每个程序员都应该了解内存》。很多魔法在引擎盖下进行,主要是防止射中自己的脚。 |
![]() |
7
0
在C#中
因为您说过只有一个线程向它写入,所以您永远不应该对正确的值有争用,并且只要您正在缓存本地副本,就永远不会得到脏数据。 volatile 如果操作系统线程将执行更新。
还要记住,有些
操作
不是
原子的
|
|
Robert King · Unity C#语法问题-转换位置 1 年前 |
![]() |
JBryanB · 如何从基本抽象类访问类属性 1 年前 |
|
law · 检查答案按钮的输入字符串格式不正确 2 年前 |
![]() |
i_sniff_ket · 在unity之外使用unity类 2 年前 |