相关疑难解决方法(0)

对于WB/WC标记的区域,MOVDQA和MOVNTDQA以及VMOVDQA和VMOVNTDQ有什么区别?

通过使用内存标记为WB指令之间的主要区别是什么(回写)和WC(写入合并):什么是之间的不同MOVDQAMOVNTDQA,什么是之间的不同VMOVDQAVMOVNTDQ

是不是对于内存标记为WC - 指令与[NT]通常没有区别(没有[NT]),并且内存标记为WB - 指令[NT]与它一起工作就好像它是一个内存WC?

x86 assembly sse simd avx

6
推荐指数
1
解决办法
2879
查看次数

x86 CPU是否重新排序指令?

我已经读过一些CPU重新排序指令,但这对于单线程程序来说不是问题(指令仍会在单线程程序中重新排序,但看起来好像指令是按顺序执行的),这只是一个问题用于多线程程序.

为了解决指令重新排序的问题,我们可以在代码中的适当位置插入内存屏障.

但x86 CPU是否重新排序指令?如果没有,那么就没有必要使用内存屏障了吧?

x86 assembly multithreading cpu-architecture memory-barriers

6
推荐指数
1
解决办法
1225
查看次数

为什么(或不是?)SFENCE + LFENCE相当于MFENCE?

正如我们从之前的回答中所知道的,它是否在处理器x86/x86_64中指示LFENCE?我们不能使用SFENCE而不是MFENCE顺序一致性.

这里的答案表明MFENCE= SFENCE+ LFENCE,即LFENCE没有我们不能提供顺序一致性的东西.

LFENCE 无法重新排序:

SFENCE
LFENCE
MOV reg, [addr]
Run Code Online (Sandbox Code Playgroud)

- 到 - >

MOV reg, [addr]
SFENCE
LFENCE
Run Code Online (Sandbox Code Playgroud)

例如重新排序MOV [addr], reg LFENCE- > LFENCE MOV [addr], reg机制提供- 存储缓冲区,它重新排序存储 - 负载以提高性能,并且因为LFENCE它不会阻止它.并SFENCE 禁用此机制.

什么机制禁用LFENCE无法重新排序(x86没有机制 - Invalidate-Queue)?

并且只是在理论上或者在现实中重新排序SFENCE MOV reg, [addr]- > MOV reg, [addr] SFENCE可能吗?如果可能,实际上,什么机制,它是如何工作的?

x86 assembly x86-64 memory-fences memory-barriers

5
推荐指数
3
解决办法
1091
查看次数

xchg 如何在英特尔汇编语言中工作

有人可以解释一下 xchg 在这段代码中是如何工作的吗?鉴于 arrayD 是一个 1,2,3 的 DWORD 数组。

mov eax, arrayD ; eax=1
xchg eax, [arrayD+4]; eax=2 arrayD=2,1,3
Run Code Online (Sandbox Code Playgroud)

为什么 xchg 之后的数组不是 1,1,3?

x86 assembly

5
推荐指数
1
解决办法
9001
查看次数

锁定指令是否在弱有序访问之间提供了障碍?

在x86上,除了原子操作之外,还提供了lock诸如lock cmpxchg提供屏障语义之类的前缀指令:对于回写内存区域的正常内存访问,读取和写入不是lock按照第3卷第8.2.2节中的预定指令重新排序的英特尔SDM:

无法使用I/O指令,锁定指令或序列化指令对读取或写入进行重新排序.

本节仅适用于回写内存类型.在同一个列表中,您会发现一个例外情况,它指出没有订购弱排序的商店:

  • 读取不会与其他读取重新排序.
  • 写入不会与较旧的读取重新排序.
  • 写入内存不会与其他写入重新排序,但以下情况除外: -

    使用非时间移动指令(MOVNTI,MOVNTQ,MOVNTDQ,MOVNTPS和MOVNTPD)执行的流存储(写入); 而且 -

    字符串操作(参见第8.2.4.1节).

注意,列表中的任何其他项目中的非时间指令没有例外,例如,在涉及锁定前缀指令的项目中.

在本指南的各种其他部分中,提到当使用弱有序(非时间)指令时,mfence和/或sfence指令可用于命令存储器.这些部分通常不提及lock- 作为替代的前缀指令.

所有这一切都让我不确定:do lock-prefixed指令提供了相同的完整屏障,它mfence提供了WB内存上的弱有序(非时间)指令之间的?同样的问题再次适用于WC内存的任何类型的访问.

x86 multithreading intel memory-model memory-fences

5
推荐指数
2
解决办法
253
查看次数

内存防护会阻止多核 CPU 中的线程吗?

我正在阅读英特尔指令集指南 64-ia-32指南 以了解内存栅栏。我的问题是,以 SFENCE 为例,为了确保所有存储操作都是全局可见的,多核 CPU 是否会停放所有线程甚至在其他内核上运行,直到实现缓存一致性?

x86 multithreading multicore cpu-architecture memory-barriers

5
推荐指数
1
解决办法
845
查看次数

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

在最近的英特尔ISA文档中,该lfence指令被定义为序列化指令流(防止指令流无序执行).特别是,该指令的描述包括以下行:

具体来说,LFENCE不会执行,直到所有先前的指令在本地完成,并且在LFENCE完成之前没有后续指令开始执行.

请注意,这适用于所有的指令,不只是内存加载指令,使得lfence 更多的不仅仅是一个存储排序防护.

虽然这现在出现在ISA文档中,但不清楚它是否是"架构",即所有x86实现都遵守,或者它是否特定于Intel.特别是AMD处理器是否也将lfence序列化为指令流?

x86 amd intel cpu-architecture memory-barriers

5
推荐指数
2
解决办法
723
查看次数

如何通过微体系结构实现障碍/栅栏以及获取,释放语义?

因此还有很多问题,例如https://mirrors.edge.kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.2018.12.08a.pdf和Preshing的文章如https:/ /preshing.com/20120710/memory-barriers-are-like-source-control-operations/及其整个系列文章就不同的障碍类型提供的排序和可见性保证方面抽象地讨论了内存排序。我的问题是,如何在x86和ARM微体系结构上实现这些障碍和内存排序语义?

对于商店-商店壁垒,好像在x86上,商店缓冲区保持商店的程序顺序并将它们提交到L1D(因此使它们以相同的顺序在全局可见)。如果存储缓冲区未排序,即未按程序顺序维护它们,那么如何实现存储障碍?它只是以这样的方式“标记”存储缓冲区,即在屏障提交之前将存储提交到缓存一致性域,然后在屏障之后提交?还是存储屏障实际上刷新了存储缓冲区并暂停了所有指令,直到刷新完成?可以同时实现吗?

对于负载障碍,如何防止负载重新排序?很难相信x86将按顺序执行所有加载!我假设加载可以乱序执行,但是可以按顺序提交/退出。如果是这样,如果一个cpu在2个不同的位置执行2次加载,那么一个加载如何确保它从T100中得到一个值,而下一个加载在T100上或之后得到它?如果第一个负载未命中高速缓存并正在等待数据,而第二个负载命中并获取其值,该怎么办。当负载1获得其值时,如何确保它获得的值不是来自该负载2的值的较新商店?如果负载可以无序执行,如何检测到违反内存排序的情况?

类似地,如何实现负载存储屏障(在x86的所有负载中都是隐含的)以及如何实现存储负载屏障(例如mfence)?即dmb ld / st和dmb指令在ARM上是如何微体系结构的?每个负载和每个存储区以及mfence指令在x86上如何进行微体系结构,以确保内存排序?

x86 x86-64 cpu-architecture memory-barriers micro-architecture

5
推荐指数
1
解决办法
72
查看次数

为什么具有顺序一致性的std :: atomic存储使用XCHG?

为什么是std::atomic store:

std::atomic<int> my_atomic;
my_atomic.store(1, std::memory_order_seq_cst);
Run Code Online (Sandbox Code Playgroud)

xchg请求具有顺序一致性的商店时执行?


从技术上讲,具有读/写内存屏障的普通商店不应该足够吗?相当于:

_ReadWriteBarrier(); // Or `asm volatile("" ::: "memory");` for gcc/clang
my_atomic.store(1, std::memory_order_acquire);
Run Code Online (Sandbox Code Playgroud)

我明确地谈论x86和x86_64.商店有隐含的获取围栏.

c++ x86 assembly lock-free stdatomic

4
推荐指数
1
解决办法
683
查看次数

推测执行的 CPU 分支是否可以包含访问 RAM 的操作码?

据我了解,当 CPU 推测性地执行一段代码时,它会在切换到推测性分支之前“备份”寄存器状态,以便如果预测结果错误(使分支无用)——寄存器状态将是安全恢复,而不会破坏“状态”。

所以,我的问题是:推测执行的 CPU 分支是否可以包含访问 RAM 的操作码?

我的意思是,访问 RAM 不是“原子”操作——如果数据当前不在 CPU 缓存中,那么从内存中读取一个简单的操作码可能会导致实际的 RAM 访问,这可能会变成一个非常耗时的操作,从 CPU 的角度来看。

如果在推测分支中确实允许这种访问,它是否仅用于读取操作?因为,我只能假设,如果一个分支被丢弃并执行“回滚”,根据它的大小恢复写操作可能会变得非常缓慢和棘手。而且,可以肯定的是,至少在某种程度上支持读/写操作,因为寄存器本身,在某些 CPU 上,据我所知,物理上位于 CPU 缓存上。

所以,也许更精确的表述是:推测执行的一段代码有什么限制?

cpu cpu-architecture speculative-execution

4
推荐指数
1
解决办法
518
查看次数