这与这个问题有关
不过,考虑到这一点,在现代英特尔CPU上,SEC阶段是以微码实现的,这意味着将有一个检查,其中使用刻录的密钥来验证PEI ACM上的签名。如果不匹配,那么它需要做一些事情,如果它匹配,它需要做其他事情。鉴于这是作为MSROM过程实现的,因此必须有一种分支方式,但鉴于MSROM指令没有RIP。
通常,当分支错误预测为被采用时,当指令停用时,ROB 将检查异常代码,从而将指令长度添加到 ROB 行的 RIP 中,或者仅使用下一个 ROB 条目的 IP,这将导致前端在分支预测更新中被重新定位到该地址。在 BOB 中,此功能现已借给跳转执行单元。显然,MSROM 例程不会发生这种情况,因为前端与它无关。
我的想法是,有一个特定的跳转指令,只有 MSROM 例程才能发出跳转到 MSROM 中的不同位置,并且可以对其进行配置,以便始终预测 MSROM 分支指令而不被采用,并且当分支执行单元遇到此指令并获取分支时, 它生成一个异常代码,并可能将特殊的跳转目标连接到它,并在停用时发生异常。或者,执行单元可以处理它,它可以使用 BOB,但我的印象是 BOB 是由分支指令 RIP 索引的,那么还有一个事实是,生成 MSROM 代码的异常通常在退休时处理;分支错误预测不需要我不认为的 MSROM,而是所有操作都是在内部形成的。
微码分支显然很特别。
英特尔的 P6 和 SnB 家族不支持微码分支的动态预测,根据 Andy Glew 对原始 P6 的描述(REP 做什么设置? 鉴于SnB系列rep
字符串指令的类似性能,我认为这个PPro事实甚至适用于最新的Skylake/CoffeeLake CPU1。
但是微码分支的错误预测是有惩罚的,所以它们是静态(?)预测的。 (这就是为什么rep movsb
ECX 中的低/中/高计数的启动成本以 5 个周期为增量,并且对齐与未对齐。
微编码指令在 uop 缓存中获取一整行。当它到达 IDQ 的前端时,它会接管问题/重命名阶段,直到完成发布微码 uops。(有关更多详细信息,另请参阅在指令周期中如何执行微码?,以及来自 perf 事件描述的一些证据,例如idq.dsb_uops
显示 IDQ 可以在问题/重命名阶段从微码序列器读取时接受来自 uop 缓存的新 uop
。对于rep
字符串指令,我认为循环的每次迭代都必须通过前端实际发出,而不仅仅是在后端内部循环并重用这些 uop。 因此,这涉及来自 OoO 后端的反馈,以了解指令何时完成执行。
我不知道当问题/重命名切换到从 MS-ROM 而不是 IDQ 读取 uops 时会发生什么细节。
即使每个uop没有自己的RIP(作为单个微编码指令的一部分),我猜分支错误预测检测机制的工作方式与普通分支类似。
某些 CPU 上的rep movs
设置时间似乎以 5 个周期为步长,具体取决于情况(小与大、对齐等)。 如果这些来自微码分支错误预测,这似乎意味着错误预测惩罚是固定数量的周期,除非这只是rep movs
的特例。 可能是因为OoO后端能跟上前端? 从 MS-ROM 读取比从 uop 缓存读取更缩短路径,使未命中损失如此之低。
对rep movsb
周围有多少 OoO exec 进行一些实验会很有趣,例如使用两个依赖imul
指令链,看看它是否(部分)像lfence
一样序列化它们。 我们希望不会,但要实现 ILP,后期的imul
uops 必须在不等待后端耗尽的情况下发布。
我在Skylake(i7-6700k)上做了一些实验。 初步结果:95字节或更小的复制大小很便宜,并且被IMUL链的延迟所隐藏,但它们基本上完全重叠。96 字节或更大的复制大小会耗尽 RS,序列化两个 IMUL 链。无论是 RCX=95 与 96 的rep movsb
,还是 RCX=23 与 24 的rep movsd
都没有关系。 有关我的发现的更多摘要,请参阅评论中的讨论;如果我有时间,我会发布更多详细信息。
测量"耗尽 RS"行为时,rs_events.empty_end:u
甚至变为每rep movsb
1 个,而不是 ~0.003。other_assists.any:u
是零,所以它不是"助攻",或者至少不算作助攻。
也许无论涉及什么uop,如果微码分支不支持通过BoB快速恢复,那么在退休时才会检测到错误预测? 96字节阈值可能是某些替代策略的截止点。 RCX=0 也会耗尽 RS,大概是因为它也是一个特例。
用rep scas
进行测试会很有趣(它没有快速字符串支持,只是缓慢而愚蠢的微码。
英特尔 1994 年的快速字符串专利描述了 P6 中的实现。 它没有 IDQ(因此在阶段和 uop 缓存之间确实有缓冲区的现代 CPU 会有一些变化是有道理的),但他们描述的避免分支的机制是整洁的,可能仍然用于现代 ERMSB:前n
复制迭代是后端的预测 uop,因此它们可以无条件地发布。 还有一个 uop 会导致后端将其 ECX 值发送到微码排序器,微码排序器使用它在此之后提供正确数量的额外复制迭代。 只是复制 uops(也许还有 ESI、EDI 和 ECX 的更新,或者可能只在中断或异常时这样做),而不是微码分支 uops。
这个初始n
uops与读取RCX后输入更多可能是我看到的96字节阈值;它每rep movsb
额外增加idq.ms_switches:u
(从4增加到5)。
https://eprint.iacr.org/2016/086.pdf 表明微码在某些情况下可以触发辅助,这可能是更大副本大小的现代机制,并且可以解释耗尽 RS(显然是 ROB),因为它仅在提交 uop 时触发(停用),所以它就像一个没有快速恢复的分支。
执行单元可以通过将事件代码与微操作的结果相关联来发出辅助或发出故障信号。提交微操作时 (§ 2.10),事件代码会导致无序调度程序压缩 ROB 中所有正在进行的微操作。事件代码被转发到微码排序器,后者在相应的事件处理程序中读取微操作"
这与 P6 专利的区别在于,这种辅助请求可以在后续指令中的一些非微码 uop 已经发出后发生,因为预计微编码指令仅使用第一批 uop 完成。 或者,如果它不是微码批处理中的最后一个 uop,则可以像分支一样使用它来选择不同的策略。
但这就是为什么它必须冲洗 ROB。
我对 P6 专利的印象是,对 MS 的反馈发生在从后面的指令中发出 uops 之前,以便在需要时及时发布更多的 MS uops。 如果我错了,那么也许它已经是2016年论文中仍然描述的相同机制。
通常,当一个分支错误地预测被采用时,当指令退休时,
自Nehalem以来,英特尔一直有"快速恢复",当一个错误预测的分支执行时开始恢复,而不是像例外一样等待它退休。
这就是在通常的 ROB 停用状态之上有一个分支-订单-缓冲区的要点,它允许您在任何其他类型的意外事件变得非推测时回滚。 (当Skylake CPU错误预测分支时,究竟会发生什么?
脚注1:IceLake应该具有"快速短代表"功能,这可能是处理rep
字符串的不同机制,而不是对微码的更改。 例如,也许像Andy提到的那样,他希望自己首先设计硬件状态机。
我没有任何关于性能特征的信息,但是一旦我们知道了一些东西,我们就可以对新的实现进行一些猜测。
英特尔已经为微码申请了一些非常类似于汇编的功能的专利,其中包括:
从 L1、L2 或 L3(!!!!!!!!!!!!!!!!!!!!!!) 执行。 哎呀,他们申请了专利,将"大"微码更新从大容量存储加载到 L3 然后从那里更新......——请注意,"专利"和"实现"是不同的,我不知道他们目前是否实现了从 L1 执行以外的任何东西。
MCU软件包中的操作码和Ucode(!)部分(统一微处理器更新) - 我们称之为"微码更新"的东西,但实际上可以包含各种东西,包括PMU固件更新,MCROM补丁,非内核参数更改,PWC固件等,在处理器固件/ucode更新过程之前/之后执行。
类似子例程的行为,包括Ucode 上的参数。 条件分支,或者至少是条件循环,他们已经有一段时间了。
微码的压缩和解压缩(不知道它是否可以直接从压缩状态"运行",但专利似乎暗示它至少会用于优化MCU包)。
WRMSR/RDMSR实际上更像是UCODE中的RPC,而不是现在的其他任何东西,我想当他们发现他们需要一个新的MSR或对架构MSR行为进行复杂的更改时,这真的很有帮助(就像LAPIC基本寄存器,必须"把关"才能绕过几年前成为新闻的LAPIC内存天坑SMM安全漏洞)。
因此,只需将其视为实现"公共"指令架构的硬件加速图灵完备RISC机器。
我现在知道的是,分支是由 MSROM 静态预测的,它在下一个微码行的下一个 IP 逻辑中使用该预测。这些预测可能已经在存储在MSROM中的uops中提供。
对于更小且更频繁的 MSROM 例程,复杂的解码器可以发出 1-4 个 uops,然后再将控制权传递给 MSROM 以完成解码。否则,它会延迟将控制权传递给 MSROM。
在优选实施例中,一些更常用的宏指令由XLAT PLA 510-516解码为微操作序列中的1、2、3或4个,其以XLAT PLA 510-516中的附加最小项为代价提供高性能。或者,对于一些不太常用的宏指令,四个XLAT PLA 510-516不发出Cuops,而只是允许MS单元534发出所有Cuops。第二种替代方案的缺点是性能较低(即,至少损失一个时钟周期),但可以节省XLAT PLA 510-516中的最小项(条目),这是一种设计权衡,以降低性能为代价减少芯片空间。这种权衡对于不太常用的指令或长微码流非常有用,在这些流中,一个额外时钟的重要性会降低。
来自宏指令502的操作码被提供给入口点PLA 530,PLA 530对操作码进行解码以生成进入微码ROM的入口点地址。生成的入口点地址被提供给MS单元534,该单元响应于入口点,生成一系列Cuop。MS单元534包括一个微码ROM("UROM"),该微码例程包括为长指令流提供UROM Cuops的微码例程,在某些示例中可能需要超过一百个UROM Cuops。UROM 还包括辅助处理例程和其他微码。
其余的在这里回答:https://stackoverflow.com/a/65796517/7194773