AVX512 掩码寄存器会减少执行时间吗?

Do AVX512 mask register reduce the execution time?

当使用掩码寄存器执行 AVX512 操作(使用内部函数)时,掩码的内容是否会对计算性能(延迟、吞吐量、端口占用等)产生任何影响?

例如:如果我执行 _mm512_mask_fmadd_round_ps 并且我的掩码寄存器只设置了 1 位,这与将所有位都设置为 1 有什么不同吗?

假设我只对其中一个通道使用计算结果,我是否应该始终在可能的情况下进行屏蔽或是否保证(通过规范或对实际 CPU 的测量,但可能会发生变化。 ..) 没有任何可见的效果?也许在降低为 asm 之前对内部函数进行了优化,编译器可以看到某种形式的 ILP?

不,即使对于像 vsqrtps 这样执行单元不是全宽的罕见指令,它也会进行完整计算而不考虑掩码,并在最后合并。 see performance numbers on https://uops.info/ (and https://agner.org/optimize/ 了解有关了解 uops、端口和延迟的更多信息。

虽然我认为合并目标甚至需要在 uop 可以分派之前就绪,尽管理论上它只需要在 ALU 延迟之后就绪。零掩码(maskz 而不是 mask)没有这个问题,因为目标是只写的,没有合并到。

不,掩码不会使任何事情变得更快,它只会花费您额外的指令来设置掩码寄存器。它可能甚至不节省电力(这可能通过允许更高的涡轮增压时间更长来间接帮助性能。

CPUs 已经 运行 大多数 512、256 和 128 位版本具有固定延迟的 SIMD 指令,使用宽执行单元,因此跳过一些工作只意味着一些元素执行单元闲置;短向量 CPU-style SIMD 的全部意义在于将更多的工作塞进更少的指令中,因为找到指令(或 uops)之间的依赖关系并将它们乱序调度到执行端口是复杂且耗电的扩大规模。

将它们分解并寻找 SIMD 执行单元的空闲元素以尝试将其他工作发送到执行单元的那些部分将达不到目的,需要单独调度每个元素。

(GPU 风格的 SIMD 对每个执行单元都有一个简单的流水线,所以它基本上就是这样工作的。CPUs 关心延迟,而不仅仅是吞吐量,所以他们有一个广泛的乱序每个核心执行管道,而不是大量管道。)


如果已知您唯一关心的元素位于低 128 位或 256 位,则可以使用 _mm_fmadd_ps_mm256_fmadd_ps 版本(尽管舍入覆盖版本仅可用对于 512 位矢量宽度,因此如果您需要 _round 覆盖版本,它必须是 512)。

Clang 有一个非常聪明的 shuffle 优化器,它有时可以看穿编译时常量的 shuffle 并注意到稍后只提取一个元素,并相应地进行优化。