Mou*_*ior 3 x86 simd avx matrix-multiplication 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);
}
}
Run Code Online (Sandbox Code Playgroud)
您的代码使用 AVX1 + FMA 指令,而不是 AVX2。例如,它可以在 AMD 打桩机上正常运行。(假设 hsum 以合理的方式实现,提取高半部分,然后使用 128 位混洗。)。
如果您的仅 AVX CPU 也没有 FMA,则您需要使用_mm256_mul_ps和_mm256_add_ps。
对于英特尔来说,AVX2 和 FMA 是在同一代 Haswell 中引入的,但它们是不同的扩展。FMA 在某些没有 AVX2 的 CPU 中可用。
不幸的是,甚至还有带有 AVX2 但没有 FMA 的 VIA CPU,否则 AVX2 意味着 FMA,除非您使用的虚拟机或模拟器故意具有真实硬件所没有的扩展组合。
(一些 AMD CPU 中有一个 FMA4 扩展,有 4 个操作数(3 个输入和一个单独的输出),Bulldozer 到 Zen1,之后英特尔在 AMD 上进行了切换,为时已晚,他们无法更改其 Bulldozer 设计以支持 FMA3。这就是为什么有仅限 AMD 的 FMA4,以及为什么直到 Piledriver 之前 AMD 才支持与 Intel 兼容的 FMA 扩展。但现在这已成为历史的一部分,所以通常我们只是说 FMA 来引用技术上称为 FMA3 的扩展。请参阅 Agner Fog 2009 年的博客 停止指令集战争,以及如何知道我是否可以使用 FMA 指令集进行编译?)
vptest,尽管本例中的 FP 确实包含像 之类的按位指令vxorps ymm)。随机播放仅在通道内(例如vshufps ymm或 new vpermilps)或具有 128 位粒度(vperm2f128或vinsertf128/ vextractf128)。AVX1 还提供所有 SSE1..4 指令(包括整数)的 VEX 编码,具有 3 操作数非破坏性。例如vpsubb xmm0, xmm1, [rdi]vpermps/vpermd和vpermq / pd,并vbroadcastss/sd ymm, xmm带有寄存器源(AVX1 仅具有vbroadcastss ymm, [mem])。也是一个高效的vpblendd立即整数混合指令,例如vblendpsvfmadd213ps 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(向量控制)是 AVX1vpermilps通道内排列,而 AVX2 则背负着_mm256_permutexvar_ps. 令人困惑的是,内在函数有一个xfor 车道交叉,而 asm 助记符却很简单。
| 归档时间: |
|
| 查看次数: |
8767 次 |
| 最近记录: |