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

0 投票
2 回答
772 浏览

linux - 自旋锁真的需要 DMB 吗?

我正在使用双 Cortex-A9 系统,我一直在尝试准确了解为什么自旋锁功能需要使用 DMB。似乎只要合并存储缓冲区被刷新,锁定值就应该在解锁核心的 L1 中结束,并且 SCU 应该使另一个核心的 L1 中的值无效或更新。这足以保持一致性和安全锁定对吗?STREX 不会跳过合并存储缓冲区,这意味着我们甚至不需要刷新吗?

DMB 似乎是一把钝锤,特别是因为它默认为系统域,这可能意味着一直写入主内存,这可能很昂贵。

锁中的 DMB 是否可以作为未正确使用 smp_mb 的驱动程序的解决方法?

根据性能计数器,我目前看到大约 5% 的系统周期在由 DMB 引起的停顿中消失。

0 投票
2 回答
522 浏览

android - Java程序的ARM多核惩罚

我想知道在多核 ARM 芯片与单核芯片上运行 Dalvik+JIT 是否会受到惩罚?

例如,如果我在我的 Android 系统构建中禁用多核支持并使用单个 CPU 内核执行整个手机,在运行单线程 Java 基准测试时我会获得更高的性能吗?

多核上内存屏障和同步的成本是多少?

我之所以问,是因为我隐约记得看到单核手机与双核手机的单线程基准测试分数。只要 Mhz 差不多,这两款手机就没有太大区别。我曾预计双核手机会放缓....

0 投票
2 回答
1594 浏览

c++ - 内存屏障:如何确保工作线程看到初始化写入?

我对使用内存屏障/围栏进行编程相当陌生,我想知道我们如何保证设置写入在随后在其他 CPU 上运行的工作函数中可见。例如,考虑以下情况:

之后(不是同时)运行很多次:

在 CPU 2 上,如果mySetup为 1,sheep则保证为 9——但我们如何保证它mySetup不是 0?

到目前为止,我能想到的只是在 CPU 2 上旋转等待直到setup1。但这似乎很丑陋,因为旋转等待只需要等待第一次ManipulateSheep()被调用。肯定有更好的方法吗?

请注意,未初始化代码还有一个对称问题:假设您正在编写一个无锁数据结构,该结构在其生命周期内分配内存。在析构函数中(假设所有线程都已完成调用方法),您想要释放所有内存,这意味着您需要运行析构函数的 CPU 具有最新的变量值。在这种情况下甚至不可能旋转等待,因为析构函数无法知道“最新”状态是什么来检查它。

编辑:我想我要问的是:有没有办法说“等待我的所有商店传播到其他 CPU”(用于初始化)和“等待所有商店传播到我的 CPU”(用于未初始化)?

0 投票
1 回答
1069 浏览

c - 在这种情况下,轻(est)重量的 GCC 内存屏障是什么?

我有以下 C 代码:

该代码不受锁保护(其他人只是读取dataindex),我想确保data[index]在更新index. 这段代码周围有其他变量的内存写入和读取,但它们并不重要,因此 GCC 可以自由地重新排序它们(我希望这样做是为了优化)。只要保证data[index]and的顺序index就足够了。应该如何a_write_memory_barrier()实施才能实现这一目标?

0 投票
1 回答
2381 浏览

c++ - 使用 std::mutex 发布和获取

这是关于 C++ 标准的问题。我只能访问标准草案,所以如果这与官方标准不同,我深表歉意。另外,如果我误解了它的工作原理,请随时纠正我。

假设我有两个线程,一个写入字符串,一个复制该字符串的内容。我使用std::mutex myMutex; 我知道您通常应该将 RAII 类用于锁来保护对它们的访问,我只是显式地使用了 lock 和 unlock 以使示例更加明确。

我的理解是,为了在线程之间可靠地工作,线程一必须在设置字符串后执行释放操作,而线程二必须在读取字符串之前执行获取操作。

阅读 C++11 的标准草案,我看不到任何说明这样std::mutex做的内容,尽管很明显它是预期的,否则互斥锁对任何事情都无用。

有人可以将我指向相关部分以查看吗?对于普通读者来说,标准中的措辞通常并不完全清楚:)

0 投票
1 回答
1207 浏览

gcc - 编译时间障碍 - 编译器代码重新排序 - gcc 和 pthreads

AFAIK 有充当内存屏障的 pthread 函数(例如,此处clarifications-on-full-memory-barriers-involved-by-pthread-mutexes)。但是编译时障碍呢,即编译器(尤其是 gcc)是否意识到这一点?
换句话说 - 例如 - pthread_create() 是 gcc 不执行重新排序的原因吗?

例如在代码中:

是否确定不会进行重新排序?
来自不同函数的调用怎么样:

fun() 是否也编译时间障碍(假设 pthread_create() 是)?
不同翻译单元的功能如何?

请注意,我对一般 gcc 和 pthreads 行为规范感兴趣,不一定是特定于 x86 的(关注各种不同的嵌入式平台)。
我也对其他编译器/线程库的行为不感兴趣。

0 投票
0 回答
100 浏览

multithreading - 模拟器如何处理翻译记忆障碍(隐式和显式)?

假设源架构和目标架构不同,模拟器如何有效地转换内存屏障?我知道通常现代仿真器将使用 JIT 将源ISA转换为目标 ISA,但是要知道哪些代码可以被多个程序计数器访问,哪些似乎不是很棘手,然后知道哪些指令可以安全地重新排序(由于 ISA 差异,JIT 可能需要生成一些有效的东西)并且这似乎不是非常棘手。

您甚至不能保证在指令流中找到显式的内存屏障,例如 x86 上的许多人依赖对齐的字写入是原子的。模拟器是否保守地假设每个对齐的单词写入都不能重新排序?这似乎是一个潜在的巨大开销,这让我想知道是否有任何已知的分析来解决这类问题。

0 投票
1 回答
373 浏览

c++ - 我应该在 FIFO 队列中添加内存屏障吗?

我正在使用链表实现非锁定 FIFO。

EnqueueFIFO的基本是:

我想知道如果它是单线程的,是否需要添加内存屏障(即,编译器/处理器可以重新排列上面两行的顺序吗?)。如果它是多线程的(即,像单读单写案例一样简单)怎么办?

编辑:根据here,这是一种数据反依赖的情况,不应重新排序语句。所以我假设 CPU 应该总是按照给定的顺序访问内存。是对的吗?

0 投票
8 回答
2295 浏览

c++ - 单处理器上的其他线程是否可以看到内存重新排序?

现代 CPU 架构通常会采用性能优化,这可能会导致无序执行。在单线程应用程序中,内存重新排序也可能发生,但它对程序员来说是不可见的,就好像内存是按程序顺序访问的一样。对于 SMP,内存屏障来拯救它,用于强制执行某种内存排序。

我不确定的是单处理器中的多线程。考虑以下示例:当线程 1 运行时,存储 tof可能发生在存储 to 之前x。假设上下文切换发生在f写入之后,就在x写入之前。现在线程 2 开始运行,它结束循环并打印 0,这当然是不可取的。

上面描述的场景可能吗?或者是否可以保证在线程上下文切换期间提交物理内存?

根据这个维基

当程序在单 CPU机器上运行时,硬件会执行必要的簿记,以确保程序执行就像所有内存操作都按照程序员指定的顺序(程序顺序)执行一样,因此不需要内存屏障。

虽然它没有明确提到单处理器多线程应用程序,但它包括了这种情况。

我不确定它是否正确/完整。请注意,这可能高度依赖于硬件(弱/强内存模型)。因此,您可能希望在答案中包含您知道的硬件。谢谢。

PS。设备 I/O 等不是我关心的问题。它是一个单核单处理器。

编辑:感谢 Nitsan 的提醒,我们假设这里没有编译器重新排序(只是硬件重新排序),并且线程 2 中的循环没有被优化掉。再次,魔鬼在细节中。

0 投票
3 回答
299 浏览

concurrency - 以一致的顺序看到的并发商店

英特尔架构软件开发人员手册, 2012 年 8 月,第一卷。3A 节。8.2.2:

除了那些执行存储的处理器之外,任何两个存储都以一致的顺序被处理。

但可以这样吗?

我问的原因是:考虑一个具有超线程的双核 Intel i7 处理器。根据手册的卷。如图 1 所示,图 2-8,i7 的逻辑处理器 0 和 1 共享一个 L1/L2 缓存,但其逻辑处理器 2 和 3 共享一个不同的 L1/L2 缓存——而所有逻辑处理器共享一个 L3 缓存。假设逻辑处理器 0 和 2(不共享 L1/L2 高速缓存)几乎在同一时间写入相同的内存位置,并且目前写入的深度不超过 L2。逻辑处理器 1 和 3(它们是“执行存储的处理器以外的处理器”)不能看到“两个存储顺序不一致”吗?

为了实现一致性,逻辑处理器 0 和 2 是否必须发出 SFENCE 指令,而逻辑处理器 1 和 3 是否必须发出 LFENCE 指令?尽管如此,该手册似乎不这么认为,它对此事的看法并不仅仅是印刷错误。看起来是故意的。我很困惑。

更新

根据@Benoit 的回答,提出以下问题:因此,L1 和 L2 的唯一目的是加速负载。加速存储的是 L3。是对的吗?