【发布时间】:2016-07-13 02:35:40
【问题描述】:
我正在考虑一个简单的问题——加快计算两个双精度数组的分量乘积。我注意到,与循环中的顺序乘法相比,使用 AVX 命令我只能获得大约 20% 的加速。
我决定检查这两种情况的延迟,并对加载操作的汇编代码感到困惑:
### __m256d pd;
### pd = _mm256_load_pd(a);
movq -112(%rbp), %rax //Pushing the pointer to the stack
vmovapd (%rax), %ymm0 //Pushing 32 bytes from memory to ymm
vmovapd %ymm0, -80(%rbp) //What is
vmovapd -80(%rbp), %ymm0 //happening here?
vmovapd %ymm0, -48(%rbp) //Quite slow down, since vmovapd cost ~ vmulpd
以上是以下 C 代码的程序集的一部分:
inline int test(double * a) {
__m256d pd;
pd = _mm256_load_pd(a);
return 1;
}
在__m256_load_pd的描述中说是这样完成的:
dst[255:0] := MEM[mem_addr+255:mem_addr]
dst[MAX:256] := 0
即以相反的顺序?但是这两行汇编代码有什么关系呢?
【问题讨论】:
-
你在编译时禁用了优化,所以 gcc 使代码变得很慢。通过优化,
test()编译为仅return 1,因为从未使用过pd。如果 20% 的加速是使用-O0,然后尝试使用-O3。如果您希望代码快速运行,则必须启用优化。 -
AT&T 语法在寄存器名称上使用
op src2,src1,dest和%装饰器,而 Intel 语法使用op dest, src1, src2。 Intel手册的伪代码根本不是asm,只是描述了操作。 -
20% 的加速是使用 icpc 的 -O3 标志的结果。
-
英特尔的 C++ 编译器是否已经自动矢量化了您的标量代码?理解/解释微基准测试结果的唯一有用方法是查看优化的 asm。最好来自
-march=native,因此自动矢量化器不限于 SSE2 作为基线。 -
我也指定了 -no-vec 标志。感谢您指出
-march=native。
标签: assembly simd intrinsics avx