sha256rnds2 隐式寄存器 xmm0

sha256rnds2 implicit register xmm0

根据 [1] sha256rnds2 指令有一个隐含的第三个操作数,它使用寄存器 xmm0。这就是阻止我同时在多个缓冲区上有效计算 sha256 并因此希望充分利用 CPU 的执行管道和传送带的原因。

其他多缓冲区实现(例如 [2], [3])使用两种不同的技术来克服这个问题:

  1. 按顺序计算回合
  2. 尽可能部分利用并行化

我的问题 - 为什么以这种方式设计这条指令 - 有一个隐含的障碍,阻止我们利用多个执行管道或由于相互吞吐量而有效地使用两个顺序指令。

我看到三个可能的原因:

  1. 最初 SHA-NI 被认为是低性能 CPUs 的扩展。并且没有人认为它会在高性能 CPU 中流行 - 因此不支持多管道。
  2. 指令 encoding/decoding 方面存在限制 - 没有足够的位来编码第三个寄存器,这就是它被硬编码的原因。
  3. shar256rnds2 有巨大的能源消耗,这就是为什么它不可能有多个执行管道。

链接:

  1. https://www.felixcloutier.com/x86/sha256rnds2
  2. https://github.com/intel/intel-ipsec-mb/blob/main/lib/sse/sha256_ni_x2_sse.asm
  3. https://github.com/intel/isa-l_crypto/blob/master/sha256_mb/sha256_ni_x2.asm

寄存器重命名使得这对后端来说不是问题。 (有关寄存器重命名如何隐藏先写后写和先读后写危险的信息,请参阅 。)

在最坏的情况下,这会在部分或全部 sha256rnds2 指令之前花费额外的 movdqa xmm0, whatevervmovdqa 指令,从而消耗少量的前端吞吐量。或者我想如果你没有寄存器,那么可能是一个额外的负载,甚至是 store/reload.

看起来他们想避免 VEX 编码,因此他们可以在没有 AVX/BMI 指令的低功耗 Silvermont 系列 CPU 上提供 SHA 扩展。 (这是最有用的地方,因为 CPU 相对于它所发送的数据量而言速度较慢。)所以是的,。 x86 执行带有 VEX 前缀的三寄存器指令,这为另一个 4 位寄存器编号提供了一个新字段。 (vblendvb 有 4 个显式操作数,第 4 个寄存器编号为立即数,但这很疯狂,需要特殊的解码器支持。)

所以 (1) 导致 (2),但不是因为缺少流水线。

根据 https://uops.info/ and https://agner.org/optimize/SHA256RNDS2 和指令在所有支持它的 CPU 上至少部分流水线化。 Ice Lake 在端口 5 上有一个用于 SHA256RNDS2 的执行单元,具有 6 个周期的延迟,但以 3c 的吞吐量进行流水线处理。所以 2 可以同时飞行。不接近前端瓶颈额外 movdqa.