微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

AVX 和 AVX2 之间的差异

如何解决AVX 和 AVX2 之间的差异

下面是 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);
         }
     }

解决方法

您的代码使用 AVX1 + FMA 指令,而不是 AVX2。例如,它可以在 AMD Piledriver 上正常运行。 (假设 hsum 以一种理智的方式实现,提取高半部分,然后使用 128 位 shuffle。)。

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


对于英特尔,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 AMD 才支持与 Intel 兼容的 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 这样的位指令)。 Shuffle 仅在车道内(例如 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 助记符很简单。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。