1

我正在考虑在纯汇编中实现 SHA3。SHA3​​ 具有 17 个 64 位无符号整数的内部状态,但由于它使用的转换,如果我在寄存器中有 44 个这样的整数可用,则可以实现最佳情况。可能加上一个临时寄存器。在这种情况下,我将能够在寄存器中进行整个转换。

但这是不现实的,甚至可以一直优化到几个寄存器。尽管如此,更多可能更好,这取决于这个问题的答案。

我正在考虑至少使用 MMX 寄存器进行快速存储,即使我需要换成其他寄存器进行计算。但我担心那是古代建筑。

MMX 寄存器和 RAX 之间的数据传输是否会比在堆栈上索引 u64 并从可能是 L1 缓存的地方访问它们更快?或者即使是这样,除了我应该注意的速度考虑之外,是否还有隐藏的陷阱?我对一般情况感兴趣,所以即使在我的计算机上一个比另一个快,它可能仍然没有定论。

4

1 回答 1

6

使用 ymm 寄存器作为“类似内存”的存储位置- 这不是性能的胜利。MMX 也不会。该用例是为了完全避免可能干扰微基准的内存访问。

高效的存储转发和快速的 L1d 缓存命中使得使用常规 RAM 非常好。x86 允许内存操作数,例如add eax, [rdi],并且现代 CPU 可以将其解码为单个 uop。

使用 MMX,您需要 2 个微指令,例如movd edx, mm0/ add eax, edx。所以这是更多的微指令和更多的延迟。 movd在典型的现代 CPU 上,进出 MMX或movqXMM 寄存器的延迟比 3 到 5 个周期的存储转发延迟更差。


但是如果你不需要经常来回移动数据,你也许可以有用地将你的一些数据保存在 MMX / XMM 寄存器中并使用pxor mm0, mm1等等。

如果您可以安排您的算法,以便使用movd/movq(int<->XMM 或 int<->MMX) 和movq2dq/ movdq2q(MMX->XMM / XMM->MMX) 指令而不是存储和内存操作数或加载,那么它可能是一个胜利。

但是在 Haswell 之前的 Intel 上,只有 3 个 ALU 执行端口,因此如果让存储/加载端口空闲,4 宽的超标量管道可能会遇到比前端吞吐量更窄的瓶颈(ALU 吞吐量)。

(请参阅https://agner.org/optimize/和x86 标签 wiki中的其他性能链接。)

于 2018-12-08T15:30:10.113 回答