![AMD 微处理器中如何定义不同的指令类型来识别 DirectPath 与 VectorPath 流?](https://linux22.com/image/1296406/AMD%20%E5%BE%AE%E5%A4%84%E7%90%86%E5%99%A8%E4%B8%AD%E5%A6%82%E4%BD%95%E5%AE%9A%E4%B9%89%E4%B8%8D%E5%90%8C%E7%9A%84%E6%8C%87%E4%BB%A4%E7%B1%BB%E5%9E%8B%E6%9D%A5%E8%AF%86%E5%88%AB%20DirectPath%20%E4%B8%8E%20VectorPath%20%E6%B5%81%EF%BC%9F.png)
在 AMD 10h 架构(例如 Opteron)中,对齐后的预取指令被分为 2 个流程:DirectPath(或 Fastpath)和 VectorPath(微码引擎)。之后这些流程可用于整数或浮点执行路径。
提取的指令以何种方式标记用于任一流程?是否有标志位或某种类型?
AMD 文档对区分机制的描述非常模糊。唯一提到的是:
当从L1指令缓存中获取目标32字节指令窗口时,检查指令字节确定要进行的基本解码类型是 DirectPath 还是 VectorPath。
答案1
TL:DR:不同的路径其实并没有太大区别。解码后最大的区别是 FP/SIMD 与 Integer,它们进入不同的调度程序,尽管两者都有 DirectPath 指令。
也可以看看David Kanter 的巴塞罗那 (AMD Fam10h) 微架构文章。他所绘制的 K10/K8/Core2 前端图非常相关:
有关此类内容的更多链接,请参阅SO 上的 x86 标签 wiki
摘自 Agner Fog 的微架构指南(http://agner.org/optimize/)、K8/K10章节:
17.3 预解码和指令长度解码
一条指令的长度可以是 1 到 15 个字节。指令边界在代码缓存中标记并复制到二级缓存中。因此,指令长度解码很少成为瓶颈,尽管指令长度解码器每个时钟周期只能处理一条指令。
这可能与生成其他预解码信息无关,因为 Agner 说指令长度信息也存储在 L2 缓存中,但是从 L2 提取到 L1I 时必须重新生成其他预解码信息。
一级代码缓存包含大量的预解码信息。这包括每条指令结束的位置、操作码字节的位置,以及单路径、双路径和矢量路径指令之间的区别以及跳转和调用的识别。这些信息中的一部分被复制到二级缓存,但不是全部。来自二级缓存的指令带宽较低可能是由于添加了更多预解码信息的过程。
额外数据的存储格式的实际细节尚不清楚。据推测,L1I 缓存的每一行在数据数组中除了 64B 的内存内容外,还有一些额外的字节,采用某种自定义格式。这似乎需要大量额外空间来处理每条指令都是单字节的极端情况。
这些单独的流程并不是全部那有三个解码器,它们可以解码最多 3 个 DirectPath 指令(产生最多 3 个宏操作),或者可以解码一个 VectorPath 指令。
阿格纳·福格说道:
矢量路径指令的效率低于单指令或双指令,因为它们需要独占访问解码器和管道,并且并非总是以最佳方式重新排序。例如:
; Example 17.1. AMD instruction breakdown xchg eax, ebx ; Vector path, 3 ops nop ; Direct path, 1 op xchg ecx, edx ; Vector path, 3 ops nop ; Direct path, 1 op
该序列需要 4 个时钟周期来解码,因为向量路径指令必须单独解码。
(该示例针对的是 K8。K10xchg r,r
作为 2 m-op 指令运行。Agner 表示只有 K8 具有 DirectPath Double 指令(而 K10 只有单个与矢量指令),但这与 David Kanter 的图表所示的不一致。它显示了一个吞吐量为每时钟 3 m-ops(又名 uops)的包缓冲区,但输入到其中的解码器每个周期可以产生 1 或 2 个 uops。
Bulldozer 系列也有双指令,其解码器每时钟最多可产生 4 个 m-ops。因此它可以解码单个 Vectorpath 指令,或 1-1-1-1(四个 Directpath 单指令),或 2-1-1。这意味着只有第一个解码器可以处理 Double 指令。Piledriver 及更高版本还可以解码 2-2 模式(两个连续的 DirectPath Double 指令)。
Ryzen 有一个用于解码指令的 uop 缓存。它可以每时钟向其无序核心发出最多 5 条 DirectPath Single 指令。但如果任何指令是 Double 指令,它每时钟可以运行 6 条 uop。(因此,即使 AVX / AVX2 将 256b 指令作为两条 uop 运行,它在 Ryzen 上也是值得的。)
英特尔的策略截然不同:
它们会预先解码长度,但不会将其长期存储在任何地方。解码器会尝试解码,如果一条指令在简单解码器中不起作用,则它就是一条多 uop 指令,必须等待下一个时钟周期才能让复杂解码器处理它。
复杂解码器可以直接处理最多 4 个 uops 的指令,否则 uops 必须来自微码。