问题标签 [micro-architecture]

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 投票
1 回答
326 浏览

x86 - 在 x86 Intel VT-X 非根模式下,是否可以在每个指令边界传递中断?

除了没有将中断传递到虚拟处理器(cli、if=0 等)的某些正常指定条件之外,来宾中的所有指令实际上都是可中断的吗?

也就是说,当传入的硬件中断被提供给 LAPIC,然后被提供给处理器时,据说一些内部魔法恰好将其转换为虚拟中断给来宾(使用虚拟 APIC,不退出)。发生这种情况时,当前执行的指令是否会像典型的中断传递一样立即序列化 OOO 流并跳转到向量,还是 VT-x 的虚拟中断传递会导致发生其他类型的解析?

背景是使用模拟器对竞争条件和同步原语进行压力测试通常非常有价值。人们希望您的仿真器能够在任何指令处接收中断,以触发“有趣的行为”。

这就引出了一个问题,VT-x 虚拟化是否提供了相同的指令级中断粒度,以便像纯指令仿真器一样触发“有趣的行为”?

英特尔 SDM 确实注意到虚拟中断是在指令边界上传递的,但仍然存在一些问题,即芯片上通常有效的所有边界是否始终在 VT-x 模式下检查中断。

0 投票
3 回答
460 浏览

x86 - MSROM 程序中的条件跳转指令?

这与这个问题有关

考虑到这一点,在现代英特尔 CPU 上,SEC 阶段是在微码中实现的,这意味着将进行检查,使用烧录的密钥来验证 PEI ACM 上的签名。如果不匹配,则需要做某事,如果匹配,则需要做其他事情。鉴于这是作为 MSROM 过程实现的,因此必须有一种分支方式,但鉴于 MSROM 指令没有 RIP。

通常,当一个分支错误预测为被采用时,当指令退出时,ROB 将检查异常代码,因此将指令长度添加到 ROB 行的 RIP 或仅使用下一个 ROB 条目的 IP,这将导致前端在分支预测更新中被重新引导到该地址。对于 BOB,此功能现在已借给跳转执行单元。显然,这不会发生在 MSROM 例程中,因为前端与它无关。

我的想法是,有一个特定的跳转指令,只有 MSROM 例程可以发出,它跳转到 MSROM 中的不同位置,并且可以配置为始终预测 MSROM 分支指令不会被执行,并且当分支执行单元遇到这个指令和分支被采用,它产生一个异常代码,并可能将特殊跳转目标连接到它,并且在退出时发生异常。或者,执行单元可以处理它并且它可以使用 BOB,但我的印象是 BOB 由分支指令 RIP 索引,然后还有一个事实是生成 MSROM 代码的异常通常在退休时处理;分支错误预测不需要我不认为的 MSROM,而是所有操作都是在内部执行的。

0 投票
2 回答
504 浏览

x86 - 关于 RIDL 漏洞和负载的“重放”

我正在尝试了解RIDL类漏洞。

这是一类能够从各种微架构缓冲区读取陈旧数据的漏洞。
今天已知的漏洞利用:LFB、加载端口、eMC 和存储缓冲区。

链接的论文主要集中在 LFB。

我不明白为什么 CPU 会用 LFB 中的陈旧数据来满足负载。
我可以想象,如果负载在 L1d 中命中,它会在内部“重放”,直到 L1d 将数据带入 LFB 信号通知 OoO 核心停止“重放”它(因为读取的数据现在有效)。

但是我不确定“重播”实际上是什么意思。
我认为负载被分派到具有负载能力的端口,然后记录在负载缓冲区(在 MOB 中),并最终根据需要保持,直到它们的数据可用(由 L1 发出信号)。
所以我不确定“重播”是如何发挥作用的,此外,为了让 RIDL 工作,每次“播放”负载的尝试也应该解除阻塞相关指令。
这对我来说似乎很奇怪,因为 CPU 需要跟踪加载正确完成后要重播的指令。

关于 RIDL 的论文使用此代码作为示例(不幸的是,我不得不将其粘贴为图像,因为 PDF 布局不允许我复制它):

RIDL 片段

它可以工作的唯一原因是,如果 CPU 将首先用过时的数据满足第 6 行的负载,然后重放它。
这似乎证实了以下几行:

具体来说,我们可能期望两个访问速度很快,而不仅仅是与泄露信息对应的一个。毕竟,当处理器发现错误并在第 6 行以正确的值重新启动时,程序也会使用该索引访问缓冲区。

但我希望 CPU 在转发 LFB(或任何其他内部缓冲区)中的数据之前检查负载的地址。
除非 CPU 实际重复执行加载,直到它检测到加载的数据现在有效(即重放)。
但是,为什么每次尝试都会解除对相关指令的阻塞?

重放机制究竟是如何工作的(如果它存在的话),以及它如何与 RIDL 漏洞交互?

0 投票
0 回答
25 浏览

x86 - 分支如何在来自微码定序器的代码中工作?

我对英特尔前端的高级理解如下。它大多是模糊的,可能是错误的。

  • 分支预测器确定要从中获取指令的下一个地址。

  • 有时来自后端的信号“分支 foo 被预测错误”,导致管道刷新和重新引导。

  • 取指令单元一次最多取 16 个字节

  • 这些经历了解码的各个阶段,直到最终,解码单元发出微操作,流向 RAT、ROB,然后是后端。

  • div但是,任何解码单元都不能直接发出与复杂指令类似的微操作。当解码单元检测到其中之一时,它会向微码定序器 ROM 发出信号,并从那里发出微指令,直到指令完成解码。

我的问题是:MSROM 可以发布分支吗?如果是这样,它们是如何工作的?由于这一切都发生在分支预测器的下游,它适用于(架构)指令,它怎么知道要走哪条路?它是否只是在发出分支后停止,直到后端完成执行它并且它知道条件是否为真?它有某种基本的静态预测吗?或者它实际上是由“真正的”分支预测器以某种方式提供的,就像实际的架构指令流一样?

0 投票
0 回答
218 浏览

x86 - 指令解码队列 (IDQ) 中的微操作如何排列?

我一直想知道有一段时间,但首先,一个假设是宏操作产生的所有微操作都可能与rip宏操作相同(我很确定 IQ 会rip为每个IFETCH 块和解码器可以根据长度信息轻松地将rip+ 宏操作的偏移量转换为宏操作的偏移量)。ripIDQ 是 SnB 上每个逻辑核心的 8 行 32 字节(在最近的微架构中可能是 64 字节,但我不确定),这引出了 IDQ 中微操作格式的问题——是否有地址每个 IDQ 行和一条jmp指令都会启动一个新行,类似于μop 缓存;在哪里,根据我从第 47 页的解释在优化手册中,一个 32 字节对齐的区域可以跨越 3 路,但最后的路必须以 a 结尾,jmp以便它可以通过将流水线引导到该地址来重新启动下一个指令窗口的获取(也可以跳回μop 缓存或可能必须启动旧的解码管道)。如果 IDQ 具有相同的结构,它将允许将 μop 缓存方式轻松移动到 IDQ(所以我觉得 IDQ 可以在每行的开头而不是每条指令都有一个地址,因为它没有如果线路上的说明连续,则需要rips 和分支、返回等之后的指令将在新行上)。它还允许 LSD 更有效地锁定和检测循环,因为它只需要扫描行开头的 8 个地址以检查它是否与例如jmp地址相同。但同样,我不确定 LSD 是如何精确实现的。消息来源似乎将 28 μops 的值固定为可以检测到的最大环路。

还有 Stack Engine 的复杂性以及它如何放置同步操作;阅读 Stack Engine 上 microarchitecture.pdf 中Agner fog 的部分显示同步 μop 插入在movor之前add导致它需要同步,rsp因此如果在原始or之前rip有 a ,则必须采用该指令可以将其与检查任何端口句柄的 RSB 预测进行比较retmovaddrspret, BEU?(*))。我还建议堆栈引擎与解码器一起工作,以便它在解码器插入的同时插入,这样它就不必稍后沿着指令移动以插入它。同步操作上还必须有一个位指示,以通知分配器在计算rip相对于行首地址的 s 时将其字节折扣,然后将它们发布到 ROB。它也可以在同步操作之后为指令开始一个新行,但这似乎很昂贵。

阻止这个逻辑死在它的轨道上的事情很简单,rip因为宏操作的长度不是与μops的长度相同。这可以通过让每个 IDQ 行对应一个宏操作来解决(将任何同步操作附加到行的末尾,即mov+synchop 在一行上,ret而我之前提到的,在下面的地形上,带有ripat每行的开头),我想这似乎很浪费。我能想到的唯一选择是为每个看起来很混乱的宏操作内联标记地址。

有没有人有任何关于如何实施的补充或更正?

(*) 这确实与如何处理分支错误预测的问题相关联,例如,当将预测采用的分支指令分配给 RS 时,其中一个参数可能是rip该指令的 ROB 条目在 BEU 之后的引导错误预测的管道。分配a 时ret,其中一个参数必须是它之后的 uop 的 ROB 条目,另一个参数是 the ,rsp以便可以与它进行比较。

0 投票
1 回答
102 浏览

iphone - 关于 Apple 处理器如何在内部工作的细节,公众知道多少?

编辑:为了避免这个问题作为参考请求被关闭(尽管我仍然希望参考!),为了具体起见,我将给出一些一般性的、非仅链接的问题。我会接受任何这些的答案,但越多越好。

  1. A12 是有序的还是无序的?
  2. 每个周期可以引退多少条指令?
  3. 它有多少个流水线阶段?
  4. 它有什么样的缓存层次结构?
  5. 它在架构上是否类似于现代英特尔处理器,如果不是,主要区别是什么?

原始问题:有很多关于当前主流英特尔核心设计(Pentium Pro 及其所有后代)如何工作的公开文档。Intel 自己的优化手册,以及 WikiChip 和 Agner Fog 发布的描述。

任何好奇的人都可以了解管道阶段是什么,核心的每个部分做了什么,等等。

我找不到与 Apple Ax 系列类似的东西。它存在吗?

0 投票
1 回答
185 浏览

cpu-architecture - AMD Zen 2 处理器系列的 L1 缓存大小是多少?

我尝试了 AMD 的网站、wikichip、wikipedia、google、几个评论网站,为了上帝的爱和一切神圣的东西,他们都忽略了 L1 缓存大小,但提到了 L2 和 L3。所以,如果你拥有这些新处理器,你能运行“lscpu”和“/proc/cpuinfo”并发布结果吗?谢谢你。

0 投票
1 回答
155 浏览

x86 - 内存屏障的传递性/累积性属性是如何在微架构上实现的?

我一直在阅读有关 x86 内存模型的工作原理以及 x86 上屏障指令的重要性以及与 ARMv8 等其他架构的比较。在 x86 和 ARMv8 架构中,内存模型似乎(没有双关语)尊重传递性/累积性,即如果 CPU 1 看到 CPU0 的存储,而 CPU2 看到 CPU1 的存储,这只有在 CPU1 看到 CPU0 存储时才会发生,那么 CPU2 也必须看到 CPU0 的存储。我所指的例子是 Paul McKenney 着名论文第 6.1 节中的示例 1 和 2(虽然很旧,但在他最新的 perf 烹饪书http://www.puppetmastertrading.com/images/hwViewForSwHackers 中也存在同样的内容。 pdf)。如果我理解正确,x86 使用存储队列(或存储顺序缓冲区)在存储全局可见(即写入 L1D)之前对存储进行排序(以及其他微架构优化)。我的问题是 x86 拱门(和其他拱门)如何实现(微架构)传递性属性?存储队列确保特定 CPU 的存储以特定顺序全局可见,但是如何确保由一个 CPU 生成的存储与由不同 CPU 生成的存储排序?

0 投票
1 回答
645 浏览

x86 - 屏障/栅栏和获取、释放语义是如何在微架构上实现的?

很多问题SO和文章/书籍如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 上或之后获得的?如果第一次加载在缓存中未命中并正在等待数据,而第二次加载命中并获取其值怎么办?当 load 1 获得它的值时,它如何确保它获得的值不是来自加载 2 的 value 的新商店?如果负载可以乱序执行,如何检测到违反内存顺序的情况?

类似地,加载存储屏障(隐含在 x86 的所有加载中)是如何实现的,以及存储加载屏障(例如 mfence)是如何实现的?即 dmb ld/st 和 just dmb 指令在 ARM 上做了什么微架构,每次加载和每次存储都做了什么,mfence 指令在 x86 上做微架构以确保内存排序?

0 投票
1 回答
1466 浏览

x86 - 现代英特尔处理器有多少种超标量方式?

我刚刚了解了超标量处理器(https://en.wikipedia.org/wiki/Superscalar_processor)。

我还了解到,随着超标量处理器宽度/方式数量的增加,事情变得更加复杂,复杂性增加得如此之快,以至于最好添加更多内核而不是更多宽度。我的导师说,在 4 路和 8 路超标量之间添加更多方法是不值得的。

这让我想知道:英特尔在哪里停止添加方式并开始添加内核?我的英特尔第 8 代酷睿 i7 的每个核心有多少种方式?

方法的概念甚至适用于这些处理器吗?