我如何使用SSE(和SSE2, SSE3等)扩展时,用Visual c++构建

How can I use SSE (and SSE2, SSE3, etc.) extensions when building with Visual C++?

本文关键字:扩展 构建 c++ Visual SSE3 何使用 SSE SSE2      更新时间:2023-10-16

我现在正在使用visual studio中的SSE指令对基本点积函数进行小优化。

下面是我的代码:(函数调用约定是cdecl):
float SSEDP4(const vect & vec1, const vect & vec2)
{
    __asm
    {
        // get addresses
        mov ecx, dword ptr[vec1]
        mov edx, dword ptr[vec2]
        // get the first vector
        movups xmm1, xmmword ptr[ecx]
        // get the second vector (must use movups, because data is not assured to be aligned to 16 bytes => TODO align data)
        movups xmm1, xmmword ptr[edx]
        // OP by OP multiply with second vector (by address)
        mulps xmm1, xmm2
        // add everything with horizontal add func (SSE3)
        haddps xmm1, xmm1
        // is one addition enough ?
        // try to extract, we'll see
        pextrd eax, xmm1, 03h
    }
}

vect是一个简单的结构体,包含4个单精度浮点数,不对齐到16字节(这就是为什么我使用movups而不是movaps)

vec1(1.0, 1.2, 1.4, 1.0)初始化,vec2(2.0, 1.8, 1.6, 1.0)初始化

一切都编译得很好,但是在执行时,我在两个XMM寄存器中都得到了0,结果就是这样在调试时,visual studio向我展示了2个寄存器(MMX1和MMX2,或有时MMX2和MMX3),它们是64位寄存器,但没有XMM,并且一切都为0。

有人知道发生了什么吗?

提前感谢:)

有几种方法可以在msvc++上获取SSE指令:

  1. 编译器特性-> http://msdn.microsoft.com/en-us/library/t467de55.aspx
  2. 外部MASM文件。

内联汇编(如您的示例代码)不再是一个合理的选择,因为它将无法编译非32位x86系统。(例如,构建64位二进制文件将失败)

此外,汇编块抑制了大多数优化。这对您很不利,因为即使像内联这样简单的事情也不会发生在您的函数中。

已正确编译并运行,因此至少可以使用SSE。

为了在register窗口中查看SSE寄存器,右键单击register窗口并选择SSE。这会让您看到XMM寄存器。

您还可以在监视窗口中使用@xmm<register><component>(例如,@xmm00来查看xmm0[0])来查看XMM寄存器的各个组件。

现在,至于您的实际问题,您正在用[edx]覆盖xmm1,而不是将其填充到xmm2中。

同样,在st(0)的x87堆栈上返回标量浮点值。而不是试图记住如何做到这一点,我只是将结果存储在堆栈变量中,并让编译器为我做:

float SSEDP4(const vect & vec1, const vect & vec2)
{
    float result;
    __asm
    {
        // get addresses
        mov ecx, dword ptr[vec1]
        mov edx, dword ptr[vec2]
        // get the first vector
        movups xmm1, xmmword ptr[ecx]
        // get the second vector (must use movups, because data is not assured to be aligned to 16 bytes => TODO align data)
        movups xmm2, xmmword ptr[edx] // xmm2, not xmm1
        // OP by OP multiply with second vector (by address)
        mulps xmm1, xmm2
        // add everything with horizontal add func (SSE3)
        haddps xmm1, xmm1
        // is one addition enough ?
        // try to extract, we'll see
        pextrd [result], xmm1, 03h
    }
    return result;
}