英特尔内在函数汇编代码

时间:2016-03-25 10:30:35

标签: assembly simd intrinsics avx

我正在考虑简单的问题 - 加快计算两个双数组的分量乘积。我注意到使用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

即。以相反的顺序?但是这两行汇编代码如何对此做任何事情?

1 个答案:

答案 0 :(得分:0)

除了编译标志之外,如果没有更多的上下文,很难回答这个问题。根据操作的线程数和double数组的大小,可能是您的问题是内存限制,即性能受内存访问限制。

非常大的数据 您想查看Stream基准。使用AVX内在函数将有助于软件和硬件预取以及数据对齐,这可能解释了+ 20%。无论如何,你将受到内存限制(将数据从系统内存加载到L1缓存),并且与AVX操作相比,执行sequantialy操作将无关紧要,并且可能由并行发生的数据加载隐藏(由于预取的魔力)。 / p>

L2 CACHE中的数据 根据并发线程的数量,可以以更高的速度馈送数据。但是,对数据执行mul对数据的计算不够复杂,无法承担内存编组的成本。

L1 CACHE中的数据 对于这种情况,您可能会看到性能方面的一些改进,但可能还有其他一些因素,例如L1 Cache负载引起的执行依赖性和延迟。但是,在256位寄存器中加载对齐数据可能是性能最佳的。