问题标签 [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.

0 投票
2 回答
339 浏览

java - 在数据竞争期间,线程可以读取 volatile 变量的初始空值吗?特别是在构造函数中为其分配了非空值时?

  • 让我困惑的是这个。

ConcurrentHashMap中HashEntry的Java文档(jdk1.6.0_16)

...因为值字段是易失性的,而不是最终的,所以在 Java 内存模型中,非同步读取器在通过数据竞争读取时看到 null 而不是初始值是合法的。尽管导致这种情况的重新排序实际上不太可能发生,但 Segment.readValueUnderLock 方法用作备份,以防在未同步的访问方法中看到空(预初始化)值。

  • 这是ConcurrentHashMap#Segment的get方法的实现

    /li>
  • 和 readValueUnderLock

  • 根据我的阅读和理解,每个线程都会读取 volatile 变量的最新值。

  • 那么线程什么时候会读取初始空值呢?特别是在构造函数完成之前赋值的 HashEntry 中。(还要注意 HashEntry 的引用永远不会逃脱它的构造函数。)

  • 我很难过,有人能解释一下 ConcurrentHashMap (jdk1.6.0_16) 中 HashEntry 的上述 java doc。为什么需要额外的预防锁定?

0 投票
3 回答
5018 浏览

java - Dalvik 的内存模型和 Java 的一样吗?

Dalvik 的内存模型和Java 的一样吗?long我对引用和非/非原始变量的读写是否double是原子的特别感兴趣,但我也想知道两个平台的内存模型之间是否有任何差异。

0 投票
2 回答
2258 浏览

cpu-architecture - 了解内存模型

我最近一直在阅读内存模型,我对它的工作原理有点困惑。

引用http://cis.poly.edu/muller/CS623/weakmemory.htm

如果处理器写入一个新的 X 然后写入一个新的 Y,所有其他随后执行读取 Y 然后读取 X 的处理器将访问新 Y 和新 X、旧 Y 和新 X 或旧 X 和旧Y:但是没有处理器会访问新的 Y 和旧的 X。这种强排序假设曾经是合理的。然而,当前的计算机制造商建议程序员不要依赖内存排序。这是因为较新的内存管理系统尝试重新排序内存访问以进行优化。允许对内存请求重新排序的系统称为弱排序内存系统(模型)。要检查如何使用重新排序来提高性能,请考虑以下汇编代码 [2]。

如果我们假设位置 B 当前在缓存中并且位置 A 没有缓存,那么加载 A 将比 B 花费更长的时间。CPU 可以从其缓存中获取 B,而不是等待 A,隐藏 B 的延迟:因此 CPU 可以执行A 可用时立即添加。通过放宽执行的强(顺序)内存模型(即,A 必须首先加载,然后是 B),可以获得更高的性能——但重新排序可能对软件不透明。考虑下面的代码片段,它是可用于实现自旋锁信号量的代码的一部分 [2]。

我的问题是,较弱的内存模型怎么可能导致处理器可以访问新 Y 和旧 X 的情况。它不是写入同一个内存(ram)还是工作方式不同?我假设如果一个进程修改了一个变量,然后另一个进程读取它,它会读取最新的值。

我不确定的另一件事是哪个组件允许内存访问重新排序,我现在的假设是允许编译器重新排序指令。但是 CPU 也可以重新排序它们吗?

谢谢

0 投票
1 回答
582 浏览

vb.net - 取消引用字段时是否需要内存屏障(.net x86 或 x64)?

在如下代码中,如果 Proc1 和 Proc2 在不同的处理器上同时执行,ThingVal2 是否有可能获得 5 以外的值(例如零)?

我知道在像 IA64 这样的弱模型中,Proc2 很有可能会看到 ThingRef 发生了变化,但没有看到 Thing2 的字段 X 发生了变化。在 x86 或 x64 上运行的 .Net 应用程序是否存在这种风险?如果 Proc1 创建了一个 SimpleThing 的新实例,将其 X 字段设置为 5,然后将 ThingRef 设置为指向它,这是否足以避免危险,或者是否有可能将新事物分配在缓存行上与 Proc2 线程访问过的其他东西共享?

多线程代码的一个常见范例是构造一个不可变对象并设置一个可变引用来指向它(可能使用 Interlocked.CompareExchange)。在 x86/x64 下读取不可变类型而不考虑线程是否总是安全的,还是会导致问题?如果是后者,在 vb.net 中保证可靠行为的首选方式是什么?

此外,是否有任何方法可以指定代码必须以不会发生此类问题的方式运行(例如,将执行限制在诸如 IA64 之类的单个内核上,否则无法保证正确运行)?

0 投票
2 回答
2623 浏览

c++ - 我在哪里可以找到 C++0x 同步原语的良好、可靠的文档?

我看过关于::std::thread::std::forward之类的文章,但我没有看到关于::std::atomic. 当然,有标准提案文件,但我没有看到任何适合只想使用该设施的人的好的文档。

有没有?我在哪里可以找到它?

0 投票
3 回答
2676 浏览

assembly - x86 上的顺序一致的原子负载

我对 x86 上的顺序一致的加载操作很感兴趣。

据我从汇编程序列表中看到的,由编译器生成它是作为 x86 上的普通加载实现的,但是据我所知,普通加载保证具有获取语义,而普通存储保证具有释放。

顺序一致的存储实现为锁定的 xchg,而加载为普通加载。这听起来很奇怪,你能详细解释一下吗?

添加

刚刚在互联网上发现,只要使用锁定的 xchg 完成存储,就可以像简单的 mov 一样完成顺序一致的原子加载,但是没有证据,也没有文档链接。

0 投票
5 回答
582 浏览

java - 使用布尔值仔细检查习语

采取以下java代码:

诀窍是doSomeProcessing仅在某些条件下才被调用。初始化列表是一个非常昂贵的过程,可能根本不需要它。

我已经阅读了关于为什么双重检查习语被破坏的文章,当我看到这段代码时我有点怀疑。然而,这个例子中的控制变量是一个布尔值,所以据我所知,需要一个简单的写指令。

另外,请注意someList已被声明为final并保留对并发列表的引用,该列表的writes 发生之前 reads;如果不是一个ConcurrentLinkedQueue列表是一个简单的ArrayListor LinkedList,即使它已被声明为finalwrites也不需要在 .之前发生reads

那么,上面给出的代码是否没有数据竞争?

0 投票
3 回答
805 浏览

sdk - 关于Cuda 4.0和统一内存模型的问题

Nvidia 似乎在吹捧 Cuda 4.0 允许程序员在 CPU 和 GPU 之间使用统一的内存模型。这不会取代在 GPU 和 CPU 中手动管理内存以获得最佳性能的需要,但它是否允许更简单的实现,可以进行测试、验证和优化(手动管理 GPU 和 CPU 内存)?我想听听意见或意见:)

0 投票
3 回答
2267 浏览

c# - 绑定视图模型属性在后台线程中更新;UI 总是会看到更新的值吗?

如果我有一些(非易失性)数据通过视图模型绑定到 UI,并且我从后台线程更新这些数据而不锁定任何内容并触发PropertyChanged事件,我是否保证UI 会看到此更新?如果我是,那为什么?

我可以看到CLRBindingWorker调用Dispatcher.BeginInvoke,从而确保从 UI 线程读取属性。我想知道的是属性值在 UI 线程中是否总是“新鲜”的(例如,是否会发生类似于http://www.yoda.arachsys.com/csharp/threads/volatility.shtml的场景)。

先前的答案表明确实如此,但没有任何解释。

例子:

0 投票
2 回答
322 浏览

c# - 写锁定是否保证在另一个线程中重新读取?(.Net,内存模型)

假设我有一个属性,其设置器受锁保护,但在 getter 周围没有任何锁,例如

除了同步写入(但不是读取)之外,锁,或者更确切地说 Monitor.Exit,应该会导致volatile write。现在假设我们有两个线程 A 和 B,并且发生以下序列:

  1. A 读取 的当前值MyProperty
  2. B 将新值写入MyProperty
  3. A 再次读取 的当前值MyProperty

问:A 现在可以保证看到新值吗?还是我们的锁只是确保 B 及时写入主内存,而不是确保其他线程读取新值?或者答案甚至取决于我们是在 .Net 2+ 还是“较弱”的 ECMA 实现中运行?