MSROM过程中的条件跳转指令?

时间:2019-04-23 14:04:01

标签: x86 intel branch-prediction

这与this问题有关

尽管如此,在现代的Intel CPU上,SEC阶段是以微码实现的,这意味着将进行检查,从而使用烧入的密钥来验证PEI ACM上的签名。如果不匹配,则需要执行某些操作;如果不匹配,则需要执行其他操作。如果将其实现为MSROM过程,则必须有一种分支方式,但考虑到MSROM指令不具有RIP。

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

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

3 个答案:

答案 0 :(得分:5)

微代码分支显然很特殊。

英特尔的P6和SnB系列不支持微代码分支的动态预测,根据安迪·格莱夫(Andy Glew)对原始P6(What setup does REP do?)的描述。鉴于SnB系列rep字符串指令的性能相似,我认为此PPro事实甚至适用于最新的Skylake / CoffeeLake CPU 1

但是微代码分支预测错误会受到惩罚,因此它们是静态预测的? (这就是rep movsb的启动成本针对ECX中的低/中/高计数以5个周期为增量,对齐还是未对齐的原因。)


微码指令在uop缓存中占据了整行。 当它到达IDQ的最前面时,它将接管发出/重命名阶段,直到完成发出微代码uops为止。(有关更多详细信息,以及来自perf事件描述的一些证据,另请参见How are microcodes executed during an instruction cycle?idq.dsb_uops一样,显示IDQ可以从uop缓存接受新的uop,而则是从微码序列器读取问题/重命名阶段。)

对于rep字符串指令,我认为循环的每次迭代实际上必须通过前端发出,而不仅仅是在后端内部循环并重用这些微指令。因此,这涉及到来自OoO后端的反馈,以找出指令何时完成执行。

我不知道当问题/重命名切换到从MS-ROM而不是IDQ读取uops时会发生什么情况的细节。

即使每个uop都没有自己的RIP(属于单个微码指令),但我猜想分支错误预测检测机制的工作原理与普通分支类似。

在某些CPU上,

rep movs的设置时间似乎以5个周期为步长,具体取决于具体情况(小与大,对齐等)。如果这些是来自微码分支的错误预测,则这似乎意味着该错误预测惩罚是固定数量的循环,除非这只是rep movs的特例。可能是因为OoO后端可以跟上前端吗?而且,从MS-ROM读取数据比从uop缓存读取数据更能缩短路径,从而降低丢失率。

有趣的是,对rep movsb 周围可能有多少OoO执行程序进行一些实验,例如带有两条相关的imul相关指令链,以查看它是否(部分)serializes them like lfence。我们希望不会,但是要实现ILP,以后的imul指令将不得不发布而不必等待后端耗尽。

我在Skylake(i7-6700k)上做了一些实验。初步结果:95字节及更少字节的副本大小便宜,并且被IMUL链的延迟所掩盖,但它们基本上完全重叠。 副本大小为96字节或更多的字节会耗尽RS,从而将两个IMUL链串行化。 RCX = 95的rep movsb与96的rep movsd还是RCX = 95的rs_events.empty_end:u RCX = 23 vs.24。有关评论的更多摘要,请参见评论中的讨论;如果有时间,我会发布更多详细信息。

使用rep movsb甚至每other_assists.any:u变为1而不是〜0.003来测量“使RS吸水”的行为。 rep scas为零,因此它不是“助手”,或者至少不算作一个。

如果微代码分支不支持通过BoB进行快速恢复,也许涉及的任何uop只会在退休时检测到错误预测? 96字节阈值可能是某些替代策略的临界点。 RCX = 0也会耗尽RS,大概是因为这也是一种特殊情况。

使用n(不支持快速字符串,只是慢而笨拙的微代码)进行测试会很有趣。

Intel's 1994 Fast Strings patent描述了P6中的实现。它没有IDQ(因此在阶段之间具有缓冲区和uop缓存的现代CPU会有一些变化是有意义的),但是它们描述的避免分支的机制很简洁,也许仍用于现代ERMSB:最初的n复制迭代是后端的uoop谓词,因此可以无条件地发出它们。还有一个uop会导致后端将其ECX值发送到微码定序器,该定序器将使用它在此之后正确输入正确数量的额外副本迭代。只是复制代码(可能是ESI,EDI和ECX的更新,或者可能只是在中断或异常上执行),而不是微代码分支代码。

最初的idq.ms_switches:u运维与读取RCX之后的更多反馈可能是我所看到的96字节阈值;每rep movsb每增加一个rep(从4增加到5)。

https://eprint.iacr.org/2016/086.pdf建议在某些情况下,微代码 可以触发辅助,这可能是用于较大副本大小的现代机制,并且可以解释耗竭RS(显然是ROB)的原因,因为它仅当uop是 committed (已退休)时才触发,因此它就像是一个没有快速恢复的分支。

  

执行单元可以通过将事件代码与微操作的结果相关联来发出帮助或发出故障信号。提交微操作(第2.10节)时,事件代码使乱序调度程序挤压ROB中所有进行中的微操作。事件代码被转发到微码定序器,后者在相应的事件处理程序中读取微操作。”

此专利与P6专利之间的区别在于,这种辅助请求可以在以后的指令中已发出一些非微码指令之后发生,因为预期只有第一批指令才能完成微码指令。或者,如果它不是微代码批处理中的最后一个uop,则可以像分支一样使用它来选择其他策略。

但这就是为什么它必须刷新ROB的原因。

我对P6专利的印象是,对MS的反馈发生在以后的指令发出uops之前,如果需要,可以及时发布更多的MS uops。如果我错了,那么也许它已经是2016年论文中描述的相同机制。


  

通常,当分支错误地预测为采用时,然后当指令退休时,

自从Nehalem拥有​​“快速恢复”功能以来,英特尔便在错误预测的分支执行 时开始恢复,而不是像异常一样等待它退役。

这是在通常的ROB退出状态之上设置一个Branch-Order-Buffer的要点,当任何其他类型的意外事件成为非推测性事件时,它可以使您回滚。 (What exactly happens when a skylake CPU mispredicts a branch?


脚注1 :IceLake应该具有“快速简短表示”功能,这可能是用于处理{{1}}字符串的另一种机制,而不是更改微码。例如也许像安迪(Andy)那样的硬件状态机提到他希望自己首先设计。

我没有任何有关性能特征的信息,但是一旦我们知道了一些信息,我们便可以对新的实现方式做出一些猜测。

答案 1 :(得分:2)

英特尔已为微代码申请了一些非常类似于汇编的功能,其中包括:

从L1,L2或L3执行(!!!!!!!!!!!!!!!!!!!!!!!!!!)。哎呀,他们申请了从大容量存储中将“大型”微代码更新 加载到L3,然后从那里进行更新的专利……-请注意,“已专利”和“已实现”是截然不同的,我不知道除了从L1执行之外,他们目前还实现了其他任何操作。

MCU程序包中的

Opcode和Ucode(!)部分(统一的微处理器更新)-我们称之为“微代码更新”,但实际上内部具有/可以包含各种内容,包括PMU固件更新,MCROM补丁,uncore在处理器固件/ ucode更新过程之前/之后执行的参数更改,PWC固件等。

Up上的

类似于子例程的行为包括参数。有条件分支或至少有条件循环已经有一段时间了。

微码的压缩和解压缩(未知是否可以直接从压缩状态“运行”,但是该专利似乎暗示着至少将其用于优化MCU封装)。

与现在相比,WRMSR / RDMSR实际上更像是将RPC转换成Ucode的Ucode,我想当他们发现自己需要新的MSR或在其上进行复杂的更改时,它们真的很有帮助。 MSR的体系结构行为(例如LAPIC基址寄存器,必须“保持”状态才能解决LAPIC内存漏洞SMM安全漏洞,该漏洞在几年前成为新闻)。

因此,只需将其视为实现“公共”指令体系结构的硬件加速的图灵完整RISC计算机。

答案 2 :(得分:2)

我现在知道的是,分支是由 MSROM 静态预测的,它在下一个微代码行的下一个 IP 逻辑中使用该预测。这些预测可能已经在存储在 MSROM 中的 uops 中提供了。

对于更小和更频繁的 MSROM 例程,复杂解码器可以在将控制权传递给 MSROM 以完成解码之前发出 1-4 个 uops。否则,它会延迟将控制权交给 MSROM。

<块引用>

在优选实施例中,一些更常用的宏指令由 XLAT PLAs 510-516 解码为微操作序列中的第一个 Cuops 中的一个、两个、三个或四个,从而提供高性能XLAT PLAs 510-516 中额外最小项的成本。或者,对于一些不太常用的宏指令,四个 XLAT PLA 510-516 不发出 Cuop,而只是允许 MS 单元 534 发出所有 Cuop。第二种替代方案的缺点是性能较低(即损失至少一个时钟周期),但可以节省 XLAT PLA 510-516 中的最小项(条目),这是一种设计权衡,可减少芯片空间降低性能的代价。这种权衡对于不太常用的指令或较长的微代码流(其中一个额外时钟的重要性降低了)非常有用。

<块引用>

来自宏指令502的操作码被提供给入口点PLA 530,该入口点PLA 530对操作码进行解码以生成进入微码ROM的入口点地址。所产生的入口点地址被提供给MS单元534,其响应于入口点而产生一系列Cuop。 MS单元534包括微码ROM(“UROM”),其包括微码例程以提供用于长指令流的UROM Cuop,在一些示例中可能需要超过一百个UROM Cuop。 UROM 还包括辅助处理例程和其他微代码。

其余的在这里回答:https://stackoverflow.com/a/65796517/7194773