为啥不存在更广泛版本的 VDPPD / VDPPS,例如 512 位?

Posted

技术标签:

【中文标题】为啥不存在更广泛版本的 VDPPD / VDPPS,例如 512 位?【英文标题】:Why don't wider versions of VDPPD / VDPPS exist, like 512-bit bit?为什么不存在更广泛版本的 VDPPD / VDPPS,例如 512 位? 【发布时间】:2021-02-23 15:36:26 【问题描述】:

我只能找到 128 位版本的向量点积 AVX/SIMD 指令

    是否有 512 位版本? 如果不是(我找不到它们),有什么想法吗?至少在我看来,对于各种应用程序来说,这似乎是一个相当重要的指令系列,其中最重要的是对 zmm 的元素求和?向量。

【问题讨论】:

在单个指令中计算点积并不适合 SIMD。如果您想要一种在 SIMD 中计算点积的合理方法,您可以将两个向量加载到 SIMD 寄存器中,将寄存器相乘,然后累加到 SIMD 寄存器中。这可以更好地扩展,尤其是对于大型向量,因为您可以并行执行多个乘法(或更好:乘法累加),并且您只需要在算法的最后在 SIMD 向量内进行混洗。 这是有道理的。累积后是我现在正在使用的,效果很好,我可以看到它如何可以更好地扩展。谢谢! 【参考方案1】:

dpps 通常只有在您使用 SIMD“错误”(效率低下)时才有用,用于向量内的水平操作,而不是跨多个向量的垂直操作。 (如果您可以在不重新设计许多现有代码使用的某些数据结构的情况下获得一些加速,或者如果数据的其他用例更重要,那么您有时还是会这样做。)

Slides + text: SIMD at Insomniac Games (GDC 2015) 有一些关于将数据结构设计为 SIMD 友好的好东西(SoA 与 AoS),以及与滥用 SIMD 向量来保存 x、y、z 几何向量相比,这如何能提供更好的加速。


我只能找到 128 位版本的向量点积 AVX/SIMD 指令

AVX1 includes vdpps ymm, ymm, ymm/m256, imm8。它在 YMM 的两个通道中执行两个独立的 128 位 DPPS 操作,就像在 AVX 尤其是 AVX2 中以不太有用的方式扩展的大多数其他水平/随机播放指令一样。也许这就是你的意思?

这似乎是一个相当重要的指令族

一点也不。它对 2 到 4 个元素的点积有用,并且无论如何都解码为多个微指令。如果它完全符合您的需要,则值得在 Intel 上使用,但 AMD 只是对其进行微编码。 https://uops.info//https://agner.org/optimize/。或者至少在 Ice Lake 之前的 Intel 也大多“放弃”它,解码为 6 uop(14c 延迟),高于 vdpps xmm 在 Skylake 中的 4(13c 延迟)。仍然不如 Zen 的 8 微指令(15c 延迟)。

4 元素 SIMD 向量中的 3 个元素的几何向量得到(ab)使用了一些;这就是 dpps 的用途。 (有时可能是 3x3 或 4x4 矩阵,甚至可能是 2x2。)vdpps ymm 的两个单独的通道内 DPPS 操作对于获得结构数组 (AoS) 数据格式的 SIMD 优势可能比单个操作更有用8 宽操作。

dpps 不适用于较大数组的点积。 对于数组,FMA 到多个累加器中,您只能在最后水平组合, 就像在Improving performance of floating-point dot-product of an array with SIMD 中一样。另请参阅 this Q&A 了解一些性能调整实验。


车道交叉vdpps 不值得在执行单元中构建更多专用硬件,而不是让软件处理包含 5 个或更多元素的数组或对其进行微编码。 AVX-512 掩码使immediate control operand of dpps 的价值降低。 (立即数可以让您忽略一些输入元素,零与广播结果到您选择的元素,带有两个 4 位位掩码。)

这提出了另一点:vdpps 已经使用了立即数中的所有位。(YMM 版本对两半使用相同的立即数控制)。因此,在不改变立即数的工作方式的情况下,将没有空间将其扩展到 8-wide 操作。 (例如,可能总是广播,丢弃输出 0 掩码,因此您需要为 YMM 中的 8 个浮点数中的每一个设置一个输入控制掩码位?但这将需要自定义硬件与 xmm 版本所需的硬件分开)。

请注意,无需任何特殊指令/微指令,您可以使用vmulps 和水平总和来执行与vdpps 相同的操作(忽略立即数的功能)。 (vshufps / vaddps / vshufps / vaddps 将结果广播到每个元素。)英特尔的硬件支持将 Skylake 3p01(FP数学执行单元)加上 1 个 p5(随机播放单元)。

(不幸的是 haddps 无法利用任何水平 FP 硬件:/)

Ice Lake 肯定已经放弃了一些专用硬件,因为它很少使用;那里有 6 个 uops。 (额外的 2 个微指令用于 p0/p6 和 p1/p5,所以可能是洗牌,也可能是某些东西将立即数变成掩码?端口 6 甚至在冰湖,AFAIK 中也没有任何向量 ALU 执行单元。)

将 dpps 使用的专用硬件复制到 AVX-512 的更宽矢量宽度可能不值得晶体管成本。 512 位对于 CPU 来说非常宽; FMA 单元已经占据了很大的面积,并且 AVX-512 引入了一系列新指令,包括更多的车道交叉洗牌,这些指令比大多数代码中平均更广泛的vdpps zmm 更有用。

通常dpps 仅在您使用 SIMD错误时才有用。

【讨论】:

哇,彼得——这对我来说是一次很棒的教育。我一直在遵循这个方法(我的错误函数使用点积),虽然我理解它是如何工作的,但我不明白为什么......现在我明白了!非常感谢您提供的信息 - 我现在有几篇文章要阅读! 英特尔编译器在长点积方面做得非常好——累积多个 SIMD 累加器寄存器(需要 8 个寄存器来隐藏两个 4 周期 FP 流水线的延迟),使用组合这些 SIMD 累加器一棵二叉树,并且只在最后执行跨车道求和。

以上是关于为啥不存在更广泛版本的 VDPPD / VDPPS,例如 512 位?的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio 2013 Reference Hell - 它一直在寻找任何不存在的旧版本的 DLL - 为啥?

postgresql表不存在是为啥

为啥 Git 不使用更现代的 SHA?

为啥 RDD 不适合流式任务?

为啥项目中不包含必要的头文件?

为啥 iPhone 6 及更高版本的 wkwebview 不接受底部的点击?