下面是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);
}
}
发布于 2021-07-11 22:51:44
您的代码使用AVX1 + FMA指令,而不是AVX2。例如,它可以在AMD Piledriver上运行。(假设hsum以一种正常的方式实现,提取上半部分,然后使用128位的改组。)
如果您的AVX专用CPU也没有FMA,您将需要使用_mm256_mul_ps
和_mm256_add_ps
.
对于英特尔,AVX2和FMA是在同一代,哈斯韦尔,但这是不同的扩展。在一些没有AVX2的CPU中可以使用FMA。
不幸的是,存在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中有一个FMA4扩展,有4个操作数(3个输入和一个单独的输出),推土机通过Zen1,因为英特尔对AMD的切换太晚了,以至于他们无法改变推土机的设计以支持FMA3。这就是为什么有一个只有AMD的FMA4,为什么直到皮拉德里弗,AMD支持与英特尔兼容的FMA扩展。但这是历史上的一部分,所以我们通常只使用FMA来引用技术上被称为FMA3的扩展。参见Agner 2009年的博客 Stop the instruction set war和How do I know if I can compile with FMA instruction sets?)
vptest
外没有整数指令,尽管在本例中FP确实包括按位指令(如vxorps ymm
) )。洗牌只有在车道(例如vshufps ymm
或新vpermilps
)或128位粒度(vperm2f128
或vinsertf128
/ vextractf128
)。AVX1还提供了所有SSE1 1.4指令的VEX编码,包括整数,具有3-操作数非破坏性。例如,vpsubb xmm0, xmm1, [rdi]
vpermps
/ vpermd
和vpermq / pd
,以及有注册源的vbroadcastss/sd ymm, xmm
(AVX1只有vbroadcastss ymm, [mem]
)。也是一个高效的vblendps
vpblendd
vfmadd213ps x/ymm, x/ymm, x/ymm/mem
等等。(以及pd和标量ss/sd版本)。同时也是..。(减去第三个操作数),fnmadd。(否定产品),甚至是fmaddsub...ps。_mm256_fmadd_ps
将编译成某种形式的vfmadd...ps
,这取决于编译器想要覆盖的输入操作数,以及它要用作内存操作数的操作数.。
本文介绍的顺序解释了本征命名的错误选择,例如_mm256_permute_ps
(即时)和_mm256_permutevar_ps
(矢量控制)是AVX1 vpermilps
在车道上的变体,AVX2被_mm256_permutexvar_ps
缠住。因此,令人困惑的是,内部有一个x
的车道交叉,而asm助记符是简单的。
https://stackoverflow.com/questions/68340319
复制相似问题