为什么AVX-256 VMOVAPS指令只复制四个单精度浮点而不是8?

时间:2016-04-22 16:06:46

标签: c assembly intel avx avx2

我正在努力熟悉一些较新的英特尔处理器上提供的256位AVX指令。我已经验证我的i7-4720HQ支持256位AVX指令。我遇到的问题是VMOVAPS指令应该复制8个单精度浮点值,只复制4个。

dot PROC
    VMOVAPS YMM1, ymmword ptr [RCX]                
    VDPPS   YMM2, YMM1, ymmword ptr [RDX], 255      
    VMOVAPS ymmword ptr [RCX], YMM2                 
    MOVSS   XMM0, DWORD PTR [RCX]                  
    RET
dot ENDP

如果您不熟悉调用约定,Visual C ++ 2015期望在返回时返回此函数(因为它是一个浮点数)在XMM0中。

除此之外,标准是第一个参数在RCX中传递,第二个参数在RDX中传递。

以下是调用此函数的C代码。

_declspec(align(32)) float d1[] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
_declspec(align(32)) float d2[] = { 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f };
printf("Dot Product Test: %f\n", dot(d1, d2));

点函数的返回值始终为8.0。除此之外,我调试了函数,发现在第一个汇编指令之后,只有四个值被复制到YMM1中。 YMM1的其余部分仍为零。

我在这里做错了吗?我查看了英特尔文档和一些第三方文档。据我所知,我做的一切都是正确的。我使用了错误的指令吗?顺便说一句,如果你在这里告诉我使用英特尔编译器内在函数,请不要打扰。

2 个答案:

答案 0 :(得分:2)

您忘了阅读VDPPS的指令集参考页面。它提到结果分两部分产生:

VDPPS (VEX.256 encoded version)
DEST[127:0] ← DP_Primitive(SRC1[127:0], SRC2[127:0]);
DEST[255:128] ← DP_Primitive(SRC1[255:128], SRC2[255:128]);

这不是VMOVAPS的错误。

答案 1 :(得分:1)

我刚刚更新到visual studio 2015更新二,现在它正常工作。我不知道为什么。我最好的猜测是MASM将我的AVX256代码转换为AVX128代码是没有充分理由的。无论哪种方式,问题都解决了。