问题标签 [memory-barriers]
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# - lock 语句的内存屏障
我最近阅读了有关内存障碍和重新排序问题的信息,现在我对此有些困惑。
考虑以下场景:
在
Update
方法;该_usingMethod1 = true
语句是否总是在获取或设置属性之前执行?还是由于重新订购问题我们无法保证?我们应该使用
/li>volatile
like如果我们使用
/li>lock;
can we 保证,那么锁中的每个语句都将按如下顺序执行:
concurrency - 内存屏障与联锁操作
我正在努力提高我对记忆障碍的理解。假设我们有一个弱记忆模型,我们采用Dekker 算法。是否可以通过添加内存屏障使其在弱内存模型下正常工作?
我认为答案是一个令人惊讶的否定。原因(如果我是正确的)是,尽管可以使用内存屏障来确保读取不会超过另一个,但它不能确保读取不会看到陈旧的数据(例如缓存中的数据)。因此,它可能会在过去某个时间看到关键部分被解锁(根据 CPU 的缓存),但当前其他处理器可能会将其视为已锁定。如果我的理解是正确的,则必须使用互锁操作,例如通常称为测试和设置或比较和交换的操作,以确保多个处理器之间内存位置的值同步一致。
因此,我们是否可以正确地期望没有弱内存模型系统只会提供内存屏障?系统必须提供诸如测试和设置或比较和交换之类的操作才能有用。
我意识到流行的处理器,包括 x86,提供的内存模型比弱内存模型强得多。请集中讨论弱记忆模型。
(如果 Dekker 算法是一个糟糕的选择,如果可能,请选择另一个内存屏障可以成功实现正确同步的互斥算法。)
assembly - 顺序和障碍:在 x86 上,PowerPC 上“lwsync”的等效指令是什么?
我的代码很简单,如下所示。我找到了用于读写的rmb和wmb ,但没有找到通用的。lwsync在 PowerPC 上可用,但是 x86 的替代品是什么?提前谢谢。
c# - 为什么需要内存屏障?
C# 4 in a Nutshell(强烈推荐顺便说一句)使用以下代码来演示 MemoryBarrier 的概念(假设 A 和 B 在不同的线程上运行):
他们提到障碍 1 和 4 阻止此示例写入 0,障碍 2 和 3 提供新鲜度保证:他们确保如果 B 在 A 之后运行,读取_complete将评估为true。
我真的不明白。我想我理解为什么需要设置障碍 1 和 4:我们不希望对_answer的写入进行优化并放置在写入_complete之后(障碍 1),我们需要确保_answer没有被缓存(障碍 4) . 我也认为我理解为什么需要屏障 3:如果 A 运行到刚刚写入_complete = true之后,B 仍然需要刷新_complete才能读取正确的值。
我不明白为什么我们需要屏障 2!我的一部分说这是因为线程 2(运行 B)可能已经运行到(但不包括)if(_complete),所以我们需要确保_complete被刷新。
但是,我不明白这有什么帮助。_complete是否仍然有可能在 A 中设置为 true ,但 B 方法会看到_complete的缓存(错误)版本?即,如果线程 2 运行方法 B 直到第一个 MemoryBarrier 之后,然后线程 1 运行方法 A 直到_complete = true但没有进一步,然后线程 1 恢复并测试if(_complete) -如果不导致false吗?
c# - 为什么我们需要 Thread.MemoryBarrier()?
在“C# 4 in a Nutshell”中,作者展示了这个类有时可以写 0 而没有MemoryBarrier
,尽管我无法在我的 Core2Duo 中重现:
这种需求对我来说似乎很疯狂。我如何识别所有可能发生这种情况的情况?我认为如果处理器改变操作顺序,它需要保证行为不会改变。
您是否费心使用障碍?
multithreading - C++ 中的内存栅栏/障碍:boost 或其他库有吗?
这些天,我正在阅读有关内存栅栏和屏障的信息,以作为同步多线程代码和避免代码重新排序的一种方式。
我通常在 Linux 操作系统下用 C++ 开发,我boost
大量使用库,但我找不到任何与之相关的类。你知道提升中是否存在栅栏的内存屏障,或者是否有办法实现相同的概念?如果没有,我可以看看什么好的图书馆?
assembly - x86 上哪个写屏障更好:lock+addl 还是 xchgl?
Linux 内核lock; addl $0,0(%%esp)
用作写屏障,而 RE2 库xchgl (%0),%0
用作写屏障。有什么区别,哪个更好?
x86 是否也需要读屏障指令?RE2 将其读取屏障功能定义为 x86 上的无操作,而 Linux 将其定义为要么lfence
或无操作,具体取决于 SSE2 是否可用。什么时候lfence
需要?
c# - C# 中的易失性和 Thread.MemoryBarrier
为了实现多线程应用程序的无锁代码,我使用了volatile
变量,
理论上:该volatile
关键字仅用于确保所有线程都能看到 volatile 变量的最新值;因此,如果线程A
更新变量值并且线程B
在更新发生后立即读取该变量,它将看到最近从线程 A 写入的最新值。正如我在Nutshell书中的 C# 4.0 中读到的那样,这是不正确的,因为
应用 volatile 不会阻止交换写入后读取。
这个问题是否可以通过Thread.MemoryBarrier()
在每次获取volatile
变量之前解决,例如:
如果这解决了问题;考虑我们有一个 while 循环,该循环在其条件之一处依赖于该值;在while循环之前放置Thread.MemoryBarrier()
是解决问题的正确方法吗?例子:
更准确地说,我希望_foo
变量在任何线程随时要求它时提供其最新值;因此,如果Thread.MemoryBarrier()
在调用变量之前插入可以解决问题,那么我可以使用Foo
属性而不是在该属性的获取中_foo
执行 a就像:Thread.MemoryBarrier()
language-agnostic - 同步,发生前关系和获取释放语义
我需要帮助来理解同步关系。我越读它试图理解的例子,我就越觉得我什么都不懂。有时我觉得这就是它,我明白了,但在看了另一个例子之后,我再次感到困惑。请帮我把它做对。
据说操作 A 与操作 B 同步 - 如果 A 是对某个原子变量 m 的存储,具有释放语义,B 是来自同一个变量 m 的加载,具有获取语义,并且 B 读取 A 存储的值。也有人说,操作 A 发生在操作 B 之前,如果
- A 在与 B 相同的线程上执行,并且 A 在程序顺序中位于 B 之前,或者
- A 与 B 同步,或
- A 发生在其他操作 C 之前,C 发生在 B 之前
好的。如果我们看这个例子
thread0 执行 | thread1 执行
商店 x (发布) | 加载 x(获取)
此处存储到 x 是否与来自 x 的负载同步?如果我们在这里确实有同步关系,那么存储到 x 发生在从 x 加载之前,所以在线程 0 中存储到 x 之前排序的所有内容都发生在线程 1 中从 x 加载之前。这意味着这里有强制排序。这样对吗?但在这种情况下,我不明白定义部分的“和 B 读取 A 存储的值”是什么意思?如果线程 1 比线程 0 更快,它可能会读取旧值。那么这里的关系是什么,有什么关系吗?如果没有,我该如何提供这种关系?
提前致谢。
c++ - 我什么时候应该使用 _mm_sfence _mm_lfence 和 _mm_mfence
我阅读了“英特尔架构的英特尔优化指南指南”。
但是,我仍然不知道应该何时使用
任何人都可以解释在编写多线程代码时何时应该使用这些?