【问题标题】:Differences between AVX and AVX2AVX 和 AVX2 的区别
【发布时间】:2021-09-21 04:53:55
【问题描述】:

下面是 AVX2 中矩阵乘法的实现。我使用的机器只支持 AVX,所以我尝试用 AVX 实现相同的配置。

但是,我无法真正理解其中的差异以及需要更改的内容!此实现中的哪些特定于 AVX2,无法与只能处理 AVX 的机器一起使用?

这是 AVX 和 AVX2 的所有命令的链接 https://software.intel.com/sites/landingpage/IntrinsicsGuide/#techs=AVX

非常感谢您的任何见解!

 for (uint64_t i = 0; i < M; i++)
     {
         for (uint64_t j = 0; j < N; j++)
         {
             __m256 X = _mm256_setzero_ps();
             for (uint64_t k = 0; k < L; k+= 8) {
                 const __m256 AV = _mm256_load_ps(A+i*L+k);
                 const __m256 BV = _mm256_load_ps(B+j*L+k);
                 X = _mm256_fmadd_ps(AV,BV,X);
             }
             C[i*N+j] = hsum_avx(X);
         }
     }

【问题讨论】:

    标签: x86 matrix-multiplication simd avx avx2


    【解决方案1】:

    您的代码使用 AVX1 + FMA 指令,而不是 AVX2。例如,它可以在 AMD Piledriver 上运行良好。 (假设 hsum 以合理的方式实现,提取高半部分,然后使用 128 位随机播放。)。

    如果您的 AVX-only CPU 也没有 FMA,您需要使用 _mm256_mul_ps_mm256_add_ps


    对于 Intel,AVX2 和 FMA 是在同一代 Haswell 中引入的,但它们不同的扩展。 FMA 在一些没有 AVX2 的 CPU 中可用。

    不幸的是even a VIA CPU with AVX2 but not FMA,否则 AVX2 意味着 FMA,除非您在 VM 中或 emulator that intentionally has a combination of extensions that real HW doesn't

    (在一些 AMD CPU 中有一个 FMA4 扩展,有 4 个操作数(3 个输入和一个单独的输出),Bulldozer 到 Zen1,在 Intel 对 AMD 进行切换后为时已晚,他们无法更改 Bulldozer 设计以支持 FMA3。这就是为什么只有 AMD 的 FMA4,以及为什么直到 Piledriver 才支持与 Intel 兼容的 FMA 扩展。但这现在是历史尘埃的一部分,所以通常我们只说 FMA 来引用技术上的扩展称为 FMA3。请参阅 Agner Fog 的 2009 年博客 Stop the instruction set warHow do I know if I can compile with FMA instruction sets?)


    • AVX1:仅 256 位 FP(除 vptest 外没有整数指令,尽管在这种情况下 FP 确实包括像 vxorps ymm 这样的按位指令)。随机播放仅在通道内(例如 vshufps ymm 或新的 vpermilps)或具有 128 位粒度(vperm2f128vinsertf128 / vextractf128)。 AVX1 还提供所有 SSE1..4 指令的 VEX 编码,包括整数,具有 3 操作数无损。例如vpsubb xmm0, xmm1, [rdi]
    • AVX2:整数 SSE 指令的 256 位版本,以及新的车道交叉洗牌,如 vpermps / vpermdvpermq / pd,以及带有寄存器源的 vbroadcastss/sd ymm, xmm(AVX1 只有 vbroadcastss ymm, [mem])。也是一个高效的vpblendd 立即整数混合指令,如vblendps
    • FMA3:vfmadd213ps x/ymm, x/ymm, x/ymm/mem 等等。 (以及 pd 和标量 ss/sd 版本)。还有 fmsub..(减去第三个操作数)、fnmadd..(取反),甚至 fmaddsub...ps。 _mm256_fmadd_ps 将编译为某种形式的 vfmadd...ps,具体取决于编译器想要覆盖哪个输入操作数,以及它想要将哪个操作数用作内存操作数。

    这个介绍顺序解释了内在命名的错误选择,例如_mm256_permute_ps(立即)和_mm256_permutevar_ps(矢量控制)是 AVX1 vpermilps 车道内置换,而 AVX2 被 _mm256_permutexvar_ps 背负。令人困惑的是,内在函数有一个x 用于车道交叉,而 asm 助记符很简单。

    【讨论】:

    • 感谢您的洞察!为了澄清,你是说我需要结合使用 add_ps 和 mult_ps 来替换 FMA 指令 fmadd 对吗?
    • 是的,彼得就是这么说的。
    • @guts716:是的,当然。 FMA 只是 matmul 中行 x 列点积的那些操作的优化(精度和性能)。如果 FMA 不可用,则必须以老式方式进行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-08
    • 2017-08-31
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多