AVX和AVX2的区别

3
以下是使用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);
         }
     }

1个回答

8
你的代码使用了AVX1 + FMA指令,而不是AVX2。例如,在AMD Piledriver上运行应该没有问题(假设hsum以合理的方式实现,提取高半部分然后使用128位洗牌)。
如果你的AVX-only CPU也没有FMA,那么你需要使用 `_mm256_mul_ps`和`_mm256_add_ps`。
对于英特尔,AVX2和FMA在同一代处理器Haswell中推出,但它们是不同的扩展程序。某些CPU可用FMA而没有AVX2。
不幸的是,甚至有一种VIA CPU具有AVX2但没有FMA,否则AVX2将意味着具有FMA,除非你在VM或模拟器中故意具有真实HW不支持的一组扩展。
在一些AMD CPU中有FMA4扩展,具有4个操作数(3个输入和一个单独的输出),从Bulldozer到Zen1,之后Intel在太晚之前针对AMD进行了切换,无法更改他们的Bulldozer设计来支持FMA3。这就是为什么有一个仅适用于AMD的FMA4,以及为什么直到Piledriver,AMD才支持与Intel兼容的FMA扩展。但这已经成为历史的灰尘堆的一部分,所以通常我们只说FMA来引用技术上称为FMA3的扩展。请参见Agner Fog在2009年的博客“停止指令集战争”,以及“How do I know if I can compile with FMA instruction sets?”。
  • AVX1: 仅有256位的浮点指令(除了vptest整数指令,虽然此处的FP包括像vxorps ymm这样的按位操作指令)。洗牌只能在同一lane内进行(例如vshufps ymm或新的vpermilps),或者以128位为粒度进行(vperm2f128vinsertf128 / vextractf128)。 AVX1还提供了所有SSE1..4指令的VEX编码,包括整数指令,使用3个非破坏性操作数。例如:vpsubb xmm0, xmm1, [rdi]
  • AVX2: 整数SSE指令的256位版本和新的lane-crossing shuffles,例如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表示通道交叉,而汇编助记符则是普通的。

谢谢你的见解!为了澄清一下,你是说我需要同时使用add_ps和mult_ps来替代FMA指令fmadd,对吗? - MouseWarrior
2
是的,这就是Peter所说的。 - robthebloke
2
@guts716:当然可以。FMA只是对矩阵乘法中行列点积操作的精度和性能进行了优化。如果没有FMA可用,你就得按照传统的方式来做。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接