我如何使用SSE(和SSE2, SSE3等)扩展时,用Visual c++构建
How can I use SSE (and SSE2, SSE3, etc.) extensions when building with Visual C++?
我现在正在使用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指令:
- 编译器特性-> http://msdn.microsoft.com/en-us/library/t467de55.aspx
- 外部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;
}
相关文章:
- 如何构建一个 setup.py 来编译C++使用 Python、pybind11 和 Mingw-w64 的扩展?
- 通过 cmake 从C++扩展构建 Python 子模块
- 在 c++ 中构建封装但可扩展的动画库
- xgboost 构建错误:参数包未扩展为"..":
- 在Windows元组上构建64位Python扩展:未声明的标识符
- 编译 PythonService.cpp来自 win32 Python 扩展构建
- 复制C DLL以构建任何C#项目的输出,以扩展为参考
- 如何导入或安装预构建的Python扩展模块(C )(即未通过Setuptools编译的库)
- 构建 Python C++扩展
- 在Windows NTS模式下构建PHP扩展
- 构建php扩展时未定义的引用
- 使用boost构建Python扩展
- 通过增强构建构建Python扩展
- Android NDK构建共享库-中止-停止.local_module_filename不能包含文件扩展名
- 在 Windows 8.1 应用中使用 Visual C++ 2012 构建的 Windows 8.0 扩展 SDK 组
- 使用 Rice 在 C++ 中构建 Ruby 扩展:如何将 Ruby 方法(回调)的指针传输到C++函数
- 在重载函数上构建Python C++扩展失败
- 在Eclipse上构建PHP扩展
- 如何在QT中构建新的扩展坞
- 使用CMake错误构建Thor SFML扩展