问题标签 [memory-model]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - Thread.VolatileRead 实现
我正在研究VolatileRead/VolatileWrite方法的实现(使用 Reflector),我对某些事情感到困惑。
这是 VolatileRead 的实现:
读取“地址”的值后如何放置内存屏障?不应该是相反的吗?(在读取值之前放置,因此在我们进行实际读取时,任何对“地址”的挂起写入都将完成。同样的事情发生在 VolatileWrite,其中内存屏障放置在值分配之前。为什么会这样? 另外,为什么这些方法有NoInlining属性?如果它们被内联会发生什么?
c++ - C++0x 内存模型和推测加载/存储
所以我正在阅读有关即将推出的 C++0x 标准的一部分的内存模型。但是,我对允许编译器执行的某些限制感到有些困惑,特别是关于推测加载和存储的限制。
首先,一些相关的东西:
Hans Boehm 关于线程和 C++0x 中的内存模型的页面
Sutter,“棱镜:微软本机代码平台的基于原则的顺序内存模型”,N2197
现在,基本思想本质上是“无数据争用程序的顺序一致性”,这似乎是在易于编程和允许编译器和硬件机会优化之间的一个不错的折衷。如果不同线程对同一内存位置的两次访问没有排序,则定义为发生数据竞争,其中至少一次存储到内存位置,并且至少一次不是同步操作。这意味着对共享数据的所有读/写访问都必须通过某种同步机制,例如互斥锁或对原子变量的操作(好吧,可以仅对专家以宽松的内存顺序对原子变量进行操作,但默认提供为了顺序一致性)。
鉴于此,我对普通共享变量上的虚假或推测加载/存储的限制感到困惑。例如,在 N2338 中,我们有示例
不允许编译器转换成
因为如果 y == 2 存在对 x 的虚假写入,如果另一个线程同时更新 x,这可能是一个问题。但是,为什么这是一个问题?这是一场数据竞赛,无论如何都是被禁止的;在这种情况下,编译器通过两次写入 x 只会使情况变得更糟,但即使是一次写入也足以进行数据竞争,不是吗?即一个合适的 C++0x 程序需要同步对 x 的访问,在这种情况下将不再存在数据竞争,并且虚假存储也不会成为问题?
I'm similarly confused about Example 3.1.3 in N2197 and some of the other examples as well, but maybe an explanation for the above issue would explain that too.
EDIT: The Answer:
The reason why speculative stores are a problem is that in the switch statement example above, the programmer might have elected to conditionally acquire the lock protecting x only if y != 2. Hence the speculative store might introduce a data race that was not there in the original code, and the transformation is thus forbidden. The same argument applies to Example 3.1.3 in N2197 as well.
java - 正在 64 位 VM 上编写参考原子
Java 内存模型要求写入 aint
是原子的:也就是说,如果您在一个线程中向它写入一个值(由 4 个字节组成)并在另一个线程中读取它,您将获得所有字节或没有,但永远不会获得 2 个新字节和2个旧字节左右。
对于long
. 在这里,写入之前0x1122334455667788
保存的变量0
可能会导致另一个线程读取0x112233440000000
或0x0000000055667788
.
现在规范不要求对象引用是 int 或 long-sized。出于类型安全的原因,我怀疑它们可以保证以原子方式编写,但在 64 位 VM 上,这些引用可能是非常好的 64 位值(仅仅是内存地址)。
现在这是我的问题:
- 是否有任何涵盖此的内存模型规格(我还没有找到)?
- 长写操作在 64 位虚拟机上是否具有原子性?
- 虚拟机是否强制将引用映射到 32 位?
问候, 史蒂芬
c# - .NET 多线程、易失性和内存模型
假设我们有以下代码:
是错!主要问题是为什么......我想CPU重新排序操作 flag1 = true; 和 if(flag2) 语句,但变量 flag1 和 flag2 标记为易失性字段...
java - Java中的彼得森算法?
在Java中是否有用于互斥的Peterson算法的示例实现?
c++ - C++0x:内存排序
当前的C++0x 草案在第 29.3.9 节和第 29.3.10 节第 1111-1112 页上说明了以下示例:
结果r1 = r2 = 1
是可能的,因为每个线程的操作都被放宽并且指向不相关的地址。现在我的问题是关于以下(类似)示例的可能结果:
我认为在这种情况下,结果r1 = r2 = 1
是不可能的。如果可能,y 的负载将与存储同步(因此发生在之前)到 y。与 x 类似,x 的加载会发生在存储到 x 之前。但是 y 的加载是在存储到 x 之前(因此也发生在之前)排序的。这会创建一个循环的先发生关系,我认为这是不允许的。
java - Java 内存模型 (JSR-133) 是否暗示进入监视器会刷新 CPU 数据缓存?
Java内存模型有一些让我烦恼的东西(如果我什至正确理解了所有内容)。如果有两个线程 A 和 B,则不能保证 B 会看到 A 写入的值,除非 A 和 B 在同一个监视器上同步。
对于任何保证线程间缓存一致性的系统架构,都没有问题。但是如果架构在硬件上不支持缓存一致性,这实质上意味着每当一个线程进入一个监视器,之前所做的所有内存更改都必须提交到主内存,并且缓存必须失效。它必须是整个数据缓存,而不仅仅是几行,因为监视器没有信息它保护内存中的哪些变量。但这肯定会影响任何需要频繁同步的应用程序的性能(尤其是诸如具有短运行作业的作业队列之类的东西)。那么,Java 能否在没有硬件缓存一致性的架构上运行得相当好呢?如果不是,为什么内存模型不对可见性做出更强有力的保证?如果该语言需要监视器所保护的信息,那不是更有效吗?
正如我所看到的,内存模型为我们提供了两全其美的条件,即绝对需要同步,即使在硬件中保证了缓存一致性,另一方面,在不连贯的架构上性能不佳(完全缓存刷新)。那么它不应该更严格(需要由监视器保护的信息)还是更多地丢失并将潜在平台限制为缓存一致的架构?
就目前而言,这对我来说没有太大意义。有人可以弄清楚为什么选择这种特定的内存模型吗?
编辑:回想起来,我使用严格和失败是一个糟糕的选择。我用“严格”表示保证较少的情况,而“失败”表示相反的情况。为了避免混淆,最好用更强或更弱的保证来说话。
c++ - 在 C/C++ 中,是否保证 volatile 变量在线程之间具有最终一致的语义?
是否有任何普遍遵循的标准(ISO C 或 C++,或任何 POSIX/SUS 规范)保证一个变量(可能标记为 volatile),不受互斥锁保护,被多个线程访问,最终将变得一致如果它被分配到?
举一个具体的例子,考虑两个线程共享一个变量 v,初始值为零。
线程 1:v = 1
线程 2:while(v == 0) yield();
线程 2 是否保证最终终止?或者它可以想象永远旋转,因为缓存一致性永远不会启动并使分配在线程 2 的缓存中可见?
我知道 C 和 C++ 标准(在 C++0x 之前)根本没有谈到线程或并发性。但我很好奇 C++0x 内存模型、pthreads 或其他任何东西是否能保证这一点。(显然,这确实适用于 32 位 x86 上的 Windows;我想知道它是否是可以普遍依赖的东西,或者它是否恰好在那里工作)。
python - python线程:内存模型和可见性
python 线程是否像 Java 那样暴露了内存可见性和语句重新排序的问题?由于我找不到对“Python 内存模型”或类似内容的任何引用,尽管事实上很多人都在编写多线程 Python 代码,我猜这些陷阱在这里不存在。例如,没有volatile关键字。但似乎并没有在任何地方明确说明,例如,一个线程中变量的更改对所有其他线程立即可见。
也许这些东西对 Python 程序员来说都是显而易见的,但作为一个可怕的 Java 程序员,我需要一点额外的保证:)
java - Java 内存模型和成功的布尔值
我是 Java 线程的新手,最近才开始阅读内存模型。根据我的理解,Java 内存模型允许编译器进行优化。
这可能会使多线程代码和同步变得复杂,但我的问题是要简单得多。举这个例子,因为这两个语句不相互依赖,编译器是否有可能改变 try 语句中代码的顺序,从而中断检查?