memory-barriers相关内容
Linux 内核使用lock;addl $0,0(%%esp) 作为写屏障,而 RE2 库使用 xchgl (%0),%0 作为写屏障.有什么区别,哪个更好? x86 是否也需要读屏障指令?RE2 将其读取屏障功能定义为 x86 上的无操作,而 Linux 将其定义为 lfence 或无操作,具体取决于 SSE2 是否可用.什么时候需要lfence? 解决方案 The "lock;a
..
我发现 x86 CPU 具有以下内存屏障指令:mfence、lfence 和 sfence. x86 CPU 是否只有这三个内存屏障指令,还是还有更多? 解决方案 sfence (SSE1) 和 mfence/lfence (SSE2) 是唯一以其内存栅栏/屏障功能命名的指令.除非您使用 NT 加载或存储和/或 WC 内存,否则只需要 mfence 进行内存排序. (请注意,l
..
正如我们从之前对 在 x86/x86_64 处理器中指令 LFENCE 有意义吗?我们不能使用 SFENCE 代替 MFENCE 来实现顺序一致性. 那里的答案表明 MFENCE = SFENCE+LFENCE,即 LFENCE 做了一些我们没有的事情不能提供顺序一致性. LFENCE 无法重新排序: SFENCELFENCEMOV 注册,[地址] -- 至 --> MOV re
..
在“C# 4 in a Nutshell"中,作者展示了这个类有时可以在没有MemoryBarrier的情况下写0,虽然我在我的Core2Duo中无法重现: 公共类Foo{int_answer;布尔_完成;公共无效 A(){_answer = 123;//Thread.MemoryBarrier();//屏障 1_完成 = 真;//Thread.MemoryBarrier();//屏障 2}公共
..
我阅读了“英特尔架构的英特尔优化指南指南". 然而,我仍然不知道我应该什么时候使用 _mm_sfence()_mm_fence()_mm_mfence() 谁能解释一下在编写多线程代码时应该何时使用这些? 解决方案 警告:我不是这方面的专家.我仍在尝试自己学习这一点.不过这两天没有人回复,看来内存栅栏指令的高手并不多.所以这是我的理解...... 英特尔是一个弱序内存系统.
..
我对以下代码中的操作顺序有疑问: std::atomicX;std::atomicy;国际r1;国际r2;无效线程1(){y.exchange(1, std::memory_order_acq_rel);r1 = x.load(std::memory_order_relaxed);}无效线程2(){x.exchange(1, std::memory_order_acq_rel);r2 = y.l
..
考虑原子读-修改-写操作,例如 x.exchange(..., std::memory_order_acq_rel).出于对其他对象的加载和存储进行排序的目的,这是否被视为: 具有获取-释放语义的单个操作? 如果它是 #2,那么尽管在加载之前或存储之后不能对同一线程中的其他操作进行重新排序,但仍然存在在两者之间重新排序的可能性. 举一个具体的例子,考虑: std::atomic
..
通常在互联网上,我发现 LFENCE 在 x86 处理器中毫无意义,即它什么也不做,因此我们可以完全轻松地使用 SFENCE,因为 MFENCE = SFENCE + LFENCE = SFENCE + NOP =SFENCE. 但是如果 LFENCE 没有意义,那么为什么我们有四种方法可以在 x86/x86_64 中实现顺序一致性: LOAD(无围栏)和 STORE + MFENCE
..
我的测试代码如下,我发现只有memory_order_seq_cst禁止编译器重新排序. #include 使用命名空间标准;整数 A, B = 1;无效功能(无效){A = B + 1;atomic_thread_fence(memory_order_seq_cst);乙 = 0;} 其他选择,例如memory_order_release、memory_order_acq_rel,根本没有产
..
8.1.2 总线锁定 Intel 64 和 IA-32 处理器提供一个 LOCK# 信号,该信号被断言在某些关键内存操作期间自动锁定系统总线或等效链路.当这个输出信号被断言时,来自其他处理器或总线代理的总线控制请求被阻止.软件可以指定其他场合当LOCK语义之后是将 LOCK 前缀添加到说明. 它来自英特尔手册,第 3 卷 听起来像内存上的原子操作将直接在内存(RAM)上执行.我很
..
英特尔内存模型保证: 商店不会与其他商店重新订购 负载不会与其他负载重新排序 http://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/ 我看到有人声称由于 Intel 内存模型,SFENCE 在 x86-64 上是多余的,但从来没有 LFENCE.上述内存模型规则是否使任一指令变得多余?
..
假设重复获取操作,尝试加载或交换一个值,直到观察到的值是所需的值. 让我们以 cppreference 原子标志示例为起点:> void f(int n){for (int cnt = 0; cnt 我希望 x86 不会有任何变化. 我在想: 在存在差异的平台 (ARM) 上,此更改有好处还是坏处? 是否会干扰使用或不使用yield指令的决定? 我不仅对 atomi
..
TL;DR:在生产者-消费者队列中放置一个不必要的(从 C++ 内存模型的角度来看)内存栅栏或不必要的强内存顺序是否有意义以牺牲可能更差的吞吐量来获得更好的延迟? C++ 内存模型是在硬件上执行的,方法是为更强的内存顺序设置某种内存栅栏,而不是在较弱的内存顺序上设置它们. 特别是,如果生产者做了store(memory_order_release),而消费者用load(memory_o
..
TL;DR:在生产者-消费者队列中放置一个不必要的(从 C++ 内存模型的角度来看)内存栅栏或不必要的强内存顺序是否有意义以牺牲可能更差的吞吐量来获得更好的延迟? C++ 内存模型是在硬件上执行的,方法是为更强的内存顺序设置某种内存栅栏,而不是在较弱的内存顺序上设置它们. 特别是,如果生产者做了store(memory_order_release),而消费者用load(memory_o
..
我想知道为什么需要内存屏障,我已经阅读了一些关于这个主题的文章. 有人说是因为cpu乱序执行而 其他人说是因为缓存一致性问题导致存储缓冲区和队列失效. 那么,需要内存屏障的真正原因是什么?cpu乱序执行还是缓存一致性问题?或两者?cpu乱序执行和缓存一致性有关系吗?x86 和 arm 有什么区别? 解决方案 当 ISA 的内存排序规则弱于您的算法所需的语义时,您需要屏障来排序此核心/线
..
我不是 ARM 专家,但至少在某些 ARM 架构上不会对这些存储和加载进行重新排序吗? atomic原子变量;int nonAtomic_var;int nonAtomic_var2;空 foo(){atomic_var.store(111, memory_order_relaxed);atomic_var.store(222, memory_order_relaxed);}空栏(){nonA
..
ARM 允许使用后续存储重新排序加载,因此以下伪代码: //CPU 0 |//CPU 1温度0 = x;|温度 1 = y;y = 1;|x = 1; 可能导致 temp0 == temp1 == 1(并且,这在实践中也是可以观察到的).我无法理解这是如何发生的;似乎按顺序提交会阻止它(据我所知,几乎所有 OOO 处理器中都存在这种情况).我的推理是“负载在提交之前必须有它的值,它在存
..
我正在试验非时间指令,并且已经熟悉带有普通加载/存储的栅栏如何操作. Intel 定义了一个与非时间操作相关的内在 _mm_sfence,手册将其定义为: 保证每个前面的商店在任何后续商店之前都是全局可见的. 我对此操作有一些疑问. 这只是插入 SFENCE 指令吗?如果不是,这意味着什么? 如果这不仅仅是一个 SFENCE,那么 SFENCE 指令是否也带有非临时存储的
..
非临时存储(例如movnti),到同一线程发出的同一缓存行,是否按程序顺序到达内存? 因此,对于具有 NVRAM 的系统(例如具有英特尔 3D XPoint NVRAM 的英特尔 Cascade Lake 处理器),在发生崩溃时,缺少重新排序保证了写入的 前缀相同的缓存行占优势? 解决方案 假设非临时存储的解析内存类型是 WC(或 WC+),这就是我认为您要问的问题,答案是大多数情况
..
让我们考虑以下 C++ 中的双线程并发程序: x,y 是全局变量,r1,r2 是线程本地的,store 和 load 到 int 是原子的.内存模型 = C++11 int x = 0, int y = 0r1 = x |r2 = yy = r1 |x = r2 允许编译器将其编译为: int x = 0, int y = 0r1 = x |r2 = 42y = r1 |x = r2|
..