【发布时间】:2022-01-07 21:23:49
【问题描述】:
根据[1] sha256rnds2 指令有一个使用寄存器xmm0 的隐式第三个操作数。这是阻止我同时在多个缓冲区上有效计算sha256 的原因,因此无法充分利用 CPU 的执行管道和传送带。
其他多缓冲区实现(例如[2]、[3])使用两种不同的技术来克服这个问题:
- 按顺序计算轮次
- 尽可能部分利用并行化
我的问题 - 为什么这条指令是这样设计的 - 有一个隐含的障碍,阻止我们利用多个执行管道或由于互惠吞吐量而有效地使用两条顺序指令。
我看到三个可能的原因:
- 最初,SHA-NI 被认为是低性能 CPU 的扩展。而且没有人认为它会在高性能 CPU 中流行 - 因此不支持多管道。
- 指令编码/解码方面存在限制 - 没有足够的位来编码第 3 个寄存器,这就是硬编码的原因。
-
shar256rnds2具有巨大的能源消耗,这就是为什么它不可能有多个执行管道。
链接:
【问题讨论】:
-
通过寄存器重命名,固定的隐式操作数不应该真正干扰同时执行。换句话说,如果你写
sha256rnd xmm1, xmm2 ; movdqa xmm0, xmm3 ; sha256rnd xmm4, xmm5,那么没有什么可以阻止两个sha256rnds 在不同的管道中同时执行,因为它们没有依赖关系。对于不同的指令,架构xmm0将被重命名为不同的内部寄存器。 -
所以根本原因可能是#2,但它的影响并没有你想象的那么大。当然,由于 #1 和 #3,任何给定的 CPU 实际上可能有也可能没有多个可以执行该指令的管道 - 但如果有,没有理由不能全部使用它们。
-
@NateEldredge:看起来他们想避免 VEX 编码,因此他们可以在没有 AVX/BMI 指令的低功耗 Silvermont 系列 CPU 上提供 SHA 扩展。 (它最有用的地方。)所以(1)导致(2),但不是因为它没有流水线。根据uops.info 和agner.org/optimize 的说法,Ice Lake 在端口 5 上有一个用于
SHA256RNDS2的执行单元,具有 6 个周期的延迟,但以 3c 的吞吐量流水线化。所以 2 可以同时飞行。没有接近前端瓶颈,多了一个movdqa。 -
它在 Goldmont 中同样流水线化,SHA256RNDS2 为 3 uop,8c 延迟,4c 吞吐量。虽然 SHA1 更好地流水线化(1 uop,5c lat,2c tput)。 Zen2 也有一个流水线执行单元; Zen3 有两个单元,4c 延迟 2c SHA256 吞吐量。
-
在
movdqa旁边交换 xmm0 需要从内存中存储/加载 - 每个缓冲区使用 7 个 xmm 寄存器:两个用于状态,五个用于 msgtmps。对于两个缓冲区,我需要 14 个寄存器 + 1 xmm0。最后一个寄存器可能用于 SHUF_MASK 或用作 xmm0 的暂存器。在任何一种情况下,都会出现寄存器溢出。
标签: assembly x86-64 cpu cpu-architecture sha256