memory-barriers相关内容

线程同步:如何保证写操作的可见性

已经有很多关于软件和硬件内存模型、内存栅栏、存储/加载重新排序等的信息。然而,这些信息似乎都集中在确保对共享内存的读取和写入的相对顺序。 这样的系统将线程的写入完全延迟很长时间是否合法? 例如,假设一个线程对内存中的数据结构进行了一些更新,然后引发了一个应该将更新通知其他线程的标志: (dataWritten is initially false) store value1 st ..

内存屏障的传递性/累积性属性是如何在微体系结构上实现的?

我一直在阅读x86内存模型的工作原理和x86上屏障指令的重要性,并将其与其他体系结构(如ARMv8)进行比较。在x86和ARMv8体系结构中,似乎(没有双关语意思)内存模型尊重传递性/累积性,即,如果CPU1通过CPU0看到存储,并且CPU2通过CPU1看到只有在CPU1看到CPU0存储时才可能发生的存储,那么CPU2也必须看到CPU0的存储。我提到的例子是Paul McKenney的著名论文6. ..

现代英特尔x86 CPU如何实现商店的总订单

由于其TSO内存模型,x86保证了所有存储的总顺序。我的问题是,有没有人知道这实际上是如何实施的。 我对所有4个围栏是如何实施的印象很好,所以我可以解释当地的秩序是如何保持的。但4个栅栏只会给出程序顺序;它不会给您提供TSO(我知道TSO允许较旧的商店跳到新负载之前,因此只需要4个栅栏中的3个)。 在单个地址上的所有内存操作的总顺序是一致性的责任。但我想知道英特尔(尤其是Skylake)如 ..
发布时间:2022-05-08 19:13:37 其他开发

为什么内存重新排序在单核/处理器机器上不是问题?

考虑以下取自 Wikipedia 的示例,稍作修改,其中程序的步骤对应于各个处理器指令: x = 0;f = 0;线程#1:而(f == 0);打印 x;线程#2:x = 42;f = 1; 我知道,由于无序执行,当线程在两个不同的物理内核/处理器上运行时,print 语句可能会打印不同的值(42 或 0). 但是我不明白为什么这在单核机器上不是问题,因为这两个线程在同一个核心上运行(通 ..

由于 cpu 乱序执行或缓存一致性问题,是否需要内存屏障?

我想知道为什么需要内存屏障,我已经阅读了一些关于这个主题的文章. 有人说这是因为 cpu 乱序执行,而 others 说是因为缓存一致性问题导致存储缓冲区和队列失效. 那么,需要内存屏障的真正原因是什么?cpu乱序执行还是缓存一致性问题?或两者?cpu乱序执行和缓存一致性有关系吗?x86和arm有什么区别? 解决方案 当 ISA 的内存排序规则弱于您的算法所需的语义时,您需要屏障来排序 ..
发布时间:2022-01-17 14:10:21 其他开发

如何使用按顺序提交进行加载-> 存储重新排序?

ARM 允许使用后续存储重新排序加载,因此以下伪代码: //CPU 0 |//CPU 1温度0 = x;|温度1 = y;y = 1;|x = 1; 可以导致 temp0 == temp1 == 1 (并且,这在实践中也是可以观察到的).我无法理解这是如何发生的;似乎按顺序提交会阻止它(据我了解,几乎所有 OOO 处理器中都存在这种情况).我的推理是“负载在提交之前必须有它的值,它在存 ..
发布时间:2022-01-17 13:24:28 其他开发

链接构造函数时,JVM 的隐式内存屏障如何表现?

参考我的之前关于不完全构造对象的问题,我有一个第二个问题.正如 Jon Skeet 指出的那样,构造函数末尾有一个隐式内存屏障,可确保 final 字段对所有线程都是可见的.但是如果一个构造函数调用另一个构造函数呢?他们每个人的末尾是否有这样的内存屏障,或者仅在首先被调用的那个末尾?也就是说,当“错误"的解决方案是: 公共类 ThisEscape {public ThisEscape(Event ..

分析 volatile 上下文中 JIT 生成的 x86 输出

我写这篇文章是为了深入理解Java中的volatile 公共类 Main {私人int x;私人易失性int g;公共无效actor1(){x = 1;g = 1;}公共无效actor2(){put_on_screen_without_sync(g);put_on_screen_without_sync(x);}} 现在,我正在分析 JIT 为上述代码生成的内容.根据我们在上一篇文章中的讨论, ..
发布时间:2022-01-16 12:06:16 Java开发

内存屏障和 TLB

内存屏障保证数据缓存是一致的.但是,它是否保证 TLB 是一致的? 我看到一个问题,即在线程之间传递 MappedByteBuffer 时,JVM(java 7 update 1)有时会因内存错误(SIGBUS、SIGSEG)而崩溃. 例如 final AtomicReferencembbQueue = new AtomicReference();//在后台线程中.MappedB ..
发布时间:2022-01-13 21:32:14 Java开发

如果第二个线程等待第一个线程的终止,是否需要内存屏障?

假设线程 Alpha 正在写入变量 A 而没有锁定.第二个线程 Beta 正在等待 Alpha 终止,然后依次读取变量 A. A的内容会不会是新鲜的?内存写入可以延迟到线程生命周期之外吗?等待线程 Alpha 终止的标准机制不会隐含地充当内存屏障吗? 更新 1 有没有不包括内存屏障的等待示例? 解决方案 几乎可以肯定(用于等待线程终止的 API 需要为自己的目的使用内存屏 ..

当线程被调度在不同的 CPU 内核上时,预期的内存语义(例如写入后读取)会发生什么情况?

单线程中的代码具有一定的内存保证,例如先写后读(即,将一些值写入内存位置,然后将其读回应该给出您写入的值). 如果线程被重新调度以在不同的 CPU 内核上执行,这种内存保证会发生什么情况?假设一个线程将 10 写入内存位置 X,然后被重新调度到不同的核心.该内核的 L1 缓存可能具有不同的 X 值(来自之前在该内核上执行的另一个线程),因此现在读取 X 不会像线程预期的那样返回 10.当线程 ..

LFENCE 是否在 AMD 处理器上进行序列化?

在最近的英特尔 ISA 文档中,lfence 指令被定义为序列化指令流(防止其乱序执行).特别是,指令的说明包括这一行: 具体来说,LFENCE 在所有先前的指令在本地完成之前不会执行,并且在 LFENCE 完成之前不会有后续指令开始执行. 请注意,这适用于所有指令,而不仅仅是内存加载指令,使lfence 更多不仅仅是内存排序栅栏. 虽然这现在出现在 ISA 文档中,但不清楚它是 ..

如果我不使用围栏,一个核心需要多长时间才能看到另一个核心的写入?

我一直在尝试用 Google 搜索我的问题,但老实说我不知道​​如何简洁地陈述问题. 假设我在多核 Intel 系统中有两个线程.这些线程在同一个 NUMA 节点上运行.假设线程 1 写入 X 一次,然后只是偶尔向前读取它.进一步假设,除其他外,线程 2 连续读取 X.如果我不使用内存栅栏,线程 1 写入 X 和线程 2 看到更新的值之间可以间隔多长时间? 我知道 X 的写入将进入存储 ..
发布时间:2022-01-06 12:36:15 其他开发

全局不可见加载指令

由于存储加载转发,某些加载指令是否永远不会全局可见?换句话说,如果加载指令从存储缓冲区获取其值,则它永远不必从缓存中读取. 正如通常所说的那样,当从 L1D 缓存读取时,负载是全局可见的,不从 L1D 读取的负载应该使其全局不可见. 解决方案 加载全局可见性的概念很棘手,因为加载不修改内存的全局状态,而其他线程不能直接 观察它. 但是一旦乱序/推测执行后尘埃落定,我们可以知道如果线 ..
发布时间:2022-01-06 12:14:34 其他开发

确定使用障碍物(围栏)的位置

x86 指令 lfence/sfence/mfence 用于在 Linux 内核中实现 rmb()/wmb()/mb() 机制.很容易理解这些用于序列化内存访问.然而,在编写代码时——在遇到运行时行为中的错误之前,确定何时何地使用它们要困难得多. 我很想知道在编写/审查代码时是否有可以检查的已知警告,这可以帮助我们确定必须插入障碍的位置.我知道这太复杂了,但是否有经验法则或清单可以帮助我们确 ..

线程安全类是否应该在其构造函数的末尾有一个内存屏障?

当实现一个线程安全的类时,我是否应该在其构造函数的末尾包含一个内存屏障,以确保任何内部结构在可以访问之前已经完成初始化?还是消费者有责任在使实例可用于其他线程之前插入内存屏障? 简化问题: 下面的代码中是否存在可能由于初始化和线程安全类访问之间缺少内存屏障而导致错误行为的竞争风险?还是线程安全类本身应该防止这种情况发生? ConcurrentQueue队列 = 空;Parallel. ..
发布时间:2021-12-30 21:07:16 C#/.NET

原子的 C++ 内存屏障

我是新手.任何人都可以提供以下内存屏障之间差异的简化解释吗? 窗口 MemoryBarrier(); 围栏_mm_mfence(); 内联汇编asm volatile(""::"memory"); 内在的_ReadWriteBarrier(); 如果没有简单的解释,一些指向好文章或书籍的链接可能会帮助我弄清楚.到现在为止,我只使用其他人编写的对象来包装这些调用还可以,但我想比我目 ..
发布时间:2021-12-22 18:28:27 C/C++开发

为什么要刷新由其他逻辑处理器引起的内存顺序违规的管道?

Memory Order Machine Clear 性能事件是vTune 文档描述为: 内存排序 (MO) 机器清除发生在来自另一个处理器的监听请求与管道中数据操作的源匹配时.在这种情况下,管道在进行中的加载和存储退出之前被清除. 但是我不明白为什么会这样.不同逻辑处理器上的加载和存储之间没有同步顺序. 处理器可以假装在所有当前正在进行的数据操作都提交之后发生了窥探. 该问题 ..