Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何使用SSE/AVX指令有效地将64位整数的2 x 2矩阵相乘?_Assembly_X86 64_Matrix Multiplication - Fatal编程技术网

Assembly 如何使用SSE/AVX指令有效地将64位整数的2 x 2矩阵相乘?

Assembly 如何使用SSE/AVX指令有效地将64位整数的2 x 2矩阵相乘?,assembly,x86-64,matrix-multiplication,Assembly,X86 64,Matrix Multiplication,有没有办法用SSE或AVX将无符号64位整数的2 x 2矩阵相乘 这比不使用SSE/AVX指令更有效?如果只需要结果的底部64位,事情就更容易了。假设ymm0包含矩阵A的四个值,ymm1包含矩阵B的四个值,则可以按如下方式计算乘积: vpermq ymm2,ymm0,0x8D vpermq ymm3,ymm1,0x4E vpermq ymm0,ymm0,0xD8 vpclmullqlqdq xmm4,xmm0,xmm1 vpclmulhqlqdq xmm

有没有办法用SSE或AVX将无符号64位整数的2 x 2矩阵相乘


这比不使用SSE/AVX指令更有效?

如果只需要结果的底部64位,事情就更容易了。假设ymm0包含矩阵A的四个值,ymm1包含矩阵B的四个值,则可以按如下方式计算乘积:

vpermq        ymm2,ymm0,0x8D
vpermq        ymm3,ymm1,0x4E
vpermq        ymm0,ymm0,0xD8
vpclmullqlqdq xmm4,xmm0,xmm1
vpclmulhqlqdq xmm5,xmm0,xmm1
vpclmullqhqdq xmm6,xmm0,xmm1
vpclmulhqhqdq xmm7,xmm0,xmm1
vpclmullqlqdq xmm8,xmm2,xmm3
vpclmulhqlqdq xmm9,xmm2,xmm3
vpclmullqhqdq xmm10,xmm2,xmm3
vpclmulhqhqdq xmm11,xmm2,xmm3
vpunpcklqdq   xmm0,xmm4,xmm6
vpunpcklqdq   xmm1,xmm5,xmm7
vpunpcklqdq   xmm2,xmm8,xmm10
vpunpcklqdq   xmm3,xmm9,xmm11
vinserti128   ymm0,ymm0,xmm1,1
vinserti128   ymm2,ymm2,xmm3,1
vpaddq        ymm0,ymm0,ymm2

因此,ymm0包含矩阵乘积的四个底部64位整数。

如果您想要完整的128位结果,事情会稍微复杂一些(同样,输入时ymm0=矩阵a,ymm1=矩阵B):


然后你可以得到四个128位的矩阵乘积系数,用ymm0和ymm1表示。

矩阵是如何用RAM表示的?试着用C编写,让C编译器来解决这个问题。它能够为我生成相当好的代码。答案可能取决于您是否考虑64b x 64b->128b,或者您是否只需要结果的底部64位。这可能还取决于您是否可以将多个独立的2x2矩阵乘法流水线化。@fuz GCC在生成64位整数矩阵乘法的SIMD指令之前,似乎至少需要AVX2。使用多个32x32=>64位SIMD
pmuludq
很难击败标量64位。用于SIMD 64位乘法的AVX512DQ使其更加合理。这看起来很酷,但就我所知,这个问题不是关于无卡利乘法的,使用进位跟随,仍然是编码;)
vpclmullqdq
是无进位乘法:异或而不是加法。但是结果中混合了
vpaddq
vpxor
。如果使用
vpmuludq
执行此操作,则不需要如此多的洗牌,但这不太可能比4x
mul
快(在现代Intel中,端口1和端口6各有4个UOP,完全管道化)。如果您想在YMM regs中获得结果,可以存储/重新加载或
vmovq
+随机播放。
vpcmpeqq      ymm12,ymm12,ymm12
vpermq        ymm2,ymm0,0x8D
vpermq        ymm3,ymm1,0x4E
vpermq        ymm0,ymm0,0xD8
vpsllq        ymm12,ymm12,63
vpclmullqlqdq xmm4,xmm0,xmm1
vpclmulhqlqdq xmm5,xmm0,xmm1
vpclmullqhqdq xmm6,xmm0,xmm1
vpclmulhqhqdq xmm7,xmm0,xmm1
vpclmullqlqdq xmm8,xmm2,xmm3
vpclmulhqlqdq xmm9,xmm2,xmm3
vpclmullqhqdq xmm10,xmm2,xmm3
vpclmulhqhqdq xmm11,xmm2,xmm3
vpunpcklqdq   xmm0,xmm4,xmm5
vpunpckhqdq   xmm1,xmm4,xmm5
vpunpcklqdq   xmm2,xmm6,xmm7
vpunpckhqdq   xmm3,xmm6,xmm7
vpunpcklqdq   xmm4,xmm8,xmm9
vpunpckhqdq   xmm5,xmm8,xmm9
vpunpcklqdq   xmm6,xmm10,xmm11
vpunpckhqdq   xmm7,xmm10,xmm11
vinserti128   ymm0,ymm0,xmm2,1
vinserti128   ymm1,ymm1,xmm3,1
vinserti128   ymm2,ymm4,xmm6,1
vinserti128   ymm3,ymm5,xmm7,1
vpaddq        ymm2,ymm2,ymm0
vpaddq        ymm3,ymm3,ymm1
vpxor         ymm4,ymm12,ymm0
vpxor         ymm5,ymm12,ymm2
vpcmpgtq      ymm6,ymm4,ymm5
vpsubq        ymm3,ymm3,ymm6
vpunpcklqdq   ymm0,ymm2,ymm3
vpunpckhqdq   ymm1,ymm2,ymm3