现代硬件算法[3.4]: 指令表
指令表
执行阶段交错是数字电子学中的一个通用概念,它不仅应用于主CPU流水线,还应用于独立的指令和内存级别。大多数执行单元都有自己的小流水线,可以在前一个指令后的一到两个周期接收另一条指令。
在这种情况下,需要使用两种不同的“代价”来评估指令:
- 延迟(latency):需要多少个周期来获取指令的结果。
- 吞吐量(Throughput):平均每个周期可以执行多少指令
你可以从称为指令表的特殊文档中获得特定架构下指令的延迟和吞吐量。以下是我的Zen 2的一些示例值(对应32位操作数,可能存在差异):
Instruction | Latency | R-Throughput |
---|---|---|
jmp |
- | 2 |
mov r, r |
- | 1/4 |
mov r, m |
4 | 1/2 |
mov m, r |
3 | 1 |
add |
1 | 1/3 |
cmp |
1 | 1/4 |
popcnt |
1 | 1/4 |
mul |
3 | 1 |
div |
13-28 | 13-28 |
一些注释:
- 因为我们的已经习惯了“更多”意味着“更糟”的代价模型,所以人们大多使用吞吐量的倒数(reciprocals),而不是吞吐量。
- 如果某条指令执行地很频繁,则可以复制其执行单元以增加其吞吐量——甚至可以增加不止一个,但不高于解码宽度。
- 某些指令的延迟为0。意味着这些指令用于控制调度程序,而不会到达执行阶段。它们仍然具有非零的吞吐量倒数值,因为CPU前端仍然需要处理它们。
- 大多数指令都是流水线化的,如果它们的吞吐量倒数值为n,这通常意味着他们的执行单元可以在n个周期后接收一条新的指令(如果n小于1,则意味着有多个执行单元,所有执行单元都可以在下一个周期执行另一条指令)。整数除法是一个值得注意的例外:它要么是流水线化的很差,要么根本没有没有流水线化。
- 有些指令具有可变的延迟,这不仅取决于操作数的位宽,还取决于其值。对于涉及内存的操作(包括像
add
这样的融合操作),延迟通常指的是最佳情况(命中一级缓存)下的值。
这其中还有许多重要的小细节,但目前介绍到这里就足够了。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 旭穹の陋室!
评论