问题标签 [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 - 内存屏障和缓存刷新
即使缓存刷新,是否有任何实现内存屏障的拱门?我读到内存屏障仅影响 CPU 重新排序,但我阅读了与内存屏障相关的语句:确保所有 cpu 都会看到值...,但对我来说,这意味着缓存刷新/失效。
c++ - C++ 中内存屏障的例子有哪些?
我看到 C++11 互斥锁不是void lock() volatile
. 编译器如何知道哪些函数是内存屏障,哪些不是?即使它们不是易失性的,所有功能都是障碍吗?有哪些鲜为人知的记忆屏障和大家应该知道的记忆屏障?
x86 - 内存重新排序:可以将加载与较早的存储重新排序到不同但包含的位置吗?
在英特尔的处理器手册:第 8.2.3.4 节中的链接中,声明可以将负载重新排序,早期存储到不同位置,但不能将早期存储重新排序到相同位置。
所以我明白以下两个操作可以重新排序:
并且以下两个操作不能重新排序:
但是当存储和负载位于不同的位置时会发生什么,但负载完全包含存储,例如:
那么在这种情况下'y'可以为0吗?
编辑(@Hans Passant)为了进一步解释这种情况,我试图看看我是否可以使用这种技术在不使用锁定指令的情况下设计一种线程之间的准同步。
所以一个更具体的问题是,给定一个全局变量:
两个线程执行以下代码:
线程 1:
线程 2:
'y' 可以为两个线程都为 1 吗?
注意:__builtin_popcountl 是内置的 gcc 内在函数,用于计算变量中设置的位数。
c - 编译器级别和硬件级别的内存防护
我在这里读到了关于内存围栏的信息......我需要对此进行一些澄清
asm volatile ("" : : : "内存")
这提供了编译器级别的内存栅栏,并且处理器在使用它时仍然可以进行重新排序。
无论如何,我可以使用类似的指令同时实现编译器级别的防护和处理器级别的防护吗?
我碰到,
asm volatile("sfence" : : : "memory")
这是做什么的?它是否仅提供编译器级别的存储防护?
对此的任何输入都将非常有帮助。
谢谢
c++ - 最快的内联组装自旋锁
我正在用 c++ 编写一个多线程应用程序,其中性能至关重要。在线程之间复制小型结构时,我需要使用大量锁定,为此我选择使用自旋锁。
我对此进行了一些研究和速度测试,我发现大多数实现大致同样快:
- Microsoft 的 CRITICAL_SECTION,SpinCount 设置为 1000,得分约 140 个时间单位
- 使用 Microsoft 的 InterlockedCompareExchange实现此算法的得分约为 95 个时间单位
- 我还尝试使用一些内联汇编来
__asm {}
使用类似此代码的内容,它的得分约为 70 个时间单位,但我不确定是否已创建适当的内存屏障。
编辑:这里给出的时间是 2 个线程锁定和解锁自旋锁 1,000,000 次所需的时间。
我知道这并没有太大的区别,但是由于自旋锁是一个被大量使用的对象,人们会认为程序员会同意最快的方法来制作自旋锁。然而,谷歌搜索它会导致许多不同的方法。如果使用内联汇编并使用指令而不是比较 32 位寄存器来实现,我认为上述方法将是最快的。此外,必须考虑内存屏障,这可以通过 LOCK CMPXHG8B (我认为?)来完成,它保证了内核之间共享内存的“独占权”。最后[有人建议]对于繁忙的等待应该伴随着 NOP:REPCMPXCHG8B
这将使超线程处理器能够切换到另一个线程,但我不确定这是否属实?
从我对不同自旋锁的性能测试来看,没有太大区别,但出于纯粹的学术目的,我想知道哪一个最快。但是,由于我在汇编语言和内存屏障方面的经验非常有限,如果有人可以为我提供的最后一个示例编写汇编代码,我会很高兴,并在以下模板中提供了 LOCK CMPXCHG8B 和适当的内存屏障:
gcc - mfence 和 asm volatile ("" : : : "memory") 的区别
据我了解,mfence
是硬件内存屏障,asm volatile ("" : : : "memory")
而是编译器屏障。但是,可以asm volatile ("" : : : "memory")
用来代替 mfence。
我感到困惑的原因是这个链接
c - 无锁队列中的内存屏障使用
我最近阅读了 Paul McKenney 的 2010 年白皮书“内存屏障:软件黑客的硬件视图”。
我非常感谢关于下面给出的一小部分 C 代码的反馈/评论/指导,这些代码实现了 M&S 队列入队功能,特别是在内存和编译器障碍方面。
这段代码使用指针-计数器对来处理ABA,为了这篇文章,应该被认为是为 x86/x64 编写的,并且只为 x86/x64 编写。
内联评论现在都是为这篇文章写的,并且是这篇文章的一部分,因为它们表达了我目前的想法。
为简洁起见,我已经剥离了结构中的断言代码和缓存行填充等。
目前,我认为代码很糟糕,但我想确保我这样认为是出于正确的原因。
c# - Are memory-barriers required when joining on a thread?
If a thread A spawns another thread B with the single purpose of writing to a variable V and then waits for it to terminate, are memory-barriers required to ensure that subsequent reads of V on thread A are fresh? I'm unsure if there any implicit barriers in the termination / joining operations that make them redundant.
Here's an example:
Are are either / both (or more) of the barriers in the above snippet required?
c - 如何为 TMS320F2812 DSP 编写内存屏障?
我浏览了 TI C/C++ 编译器 v6.1 用户指南 ( spru514e ) 但没有找到任何东西。
该asm
声明在这方面似乎没有提供任何内容,手册甚至警告不要更改变量值(p132)。未实现用于声明对变量的影响的 GNU 扩展 (p115)。
我也没有发现任何内存屏障的内在特性(比如__memory_changed()
在 Keil 的 armcc 中)。
搜索网络或 TI 论坛也一无所获。
任何其他提示如何进行?
synchronization - 线程同步:如何保证写入的可见性
已经有很多关于软件和硬件内存模型、内存栅栏、存储/加载重新排序等的信息。然而,这一切似乎都集中在保证读写共享内存的相对顺序上。
这样的系统将线程的写入完全延迟很长时间是否是合法行为?
例如,考虑一个线程对内存中的数据结构进行一些更新,然后引发一个应该通知其他线程更新的标志:
根据我读过的大多数内存模型,内存屏障保证任何其他线程都无法将 dataWritten 视为 true,同时仍读取过时的值 1、2 或 3,即它使这些写入原子。
但是我能确定这些写的东西会被看到吗?只要标志的写入时间不早于值,在内存模型下无限期延迟写入是否合法?
用数据库术语来说,内存模型可以用来推理持久性(除了原子性和一致性,这可以通过使用上面示例中的内存围栏和标志来保证)?
更新: 关于可见性及时性的 volatile 详细语义解决了 Java 内存模型上下文中的同一主题,以及内存模型排序和可见性?对于 C++11。该讨论是否也适用于硬件内存模型,即 CPU ISA 是否只为正确的可见性序列提供硬保证,但为延迟可见性提供“软”保证?