我得到的 SSE 代码是为 x64 编写的,其中堆栈按 16 对齐。现在已为 32 位 x86(用于 MSVC/Windows 和 GCC/Linux)请求优化的代码路径。首先让这个在 MSVC 上工作。
__m128
现在,除了一些它拒绝编译的超过 3 个参数的内联(通过制作 const ref 并希望编译器对其进行优化来修复)之外,一切似乎都按原样工作。
//error C2719: 'd': formal parameter with __declspec(align('16')) won't be aligned
inline __m128i foo(__m128i a, __m128i b, __m128i c, __m128i d) {...}
但是我的印象是堆栈在 x86 Windows 上不是 16 字节对齐的。然而__declspec(align(16))
堆栈上的一些数组甚至没有收到警告,我确信它一定是在推送和弹出__m128
s (我记得在 x64 上需要 12 个寄存器,即使这样它也将一些移到堆栈中它没有'不需要一点,无论如何都做了自己的事情)。
我什至在数组内存地址上添加了一些断言(并关闭了 NDEBUG),它们似乎都通过了。
__declspec(align(16)) uint32_t blocks[64];
assert(((uintptr_t)blocks) % 16 == 0);
__m128i a = ...;
__m128i b = ...;
__m128i c = ...;
__m128i d = ...;
__m128i e = ...;
__m128i f = ...;
__m128i g = ...;
//do other stuff, which surely means there is not enough registers on x86
我真的很幸运,还是这里有一些魔法来重新对齐堆栈?这是便携式的吗?我确信我记得当我使用 VS2008 做 D3D9 时,让一些 D3DX 东西在 x86 上对齐时遇到了问题。
然而,我确实收到一堆警告的一件事是__m128
->__m128&
转换是非标准的。某些支持 SSE 的编译器是否真的不支持这一点,以及如何避免它(例如内联 output__m128
或超过 3 个参数)?
快速浏览一下表明 MS 自己以某种方式违反了这些规则(例如 XMMatrixTransformation http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.matrix.xmmatrixtransformation%28v=vs.85%29。 aspx需要 6 个 SSE 对象,我能看到的唯一区别是包裹在结构中)
XMMATRIX XMMatrixTransformation(
[in] XMVECTOR ScalingOrigin,
[in] XMVECTOR ScalingOrientationQuaternion,
[in] XMVECTOR Scaling,
[in] XMVECTOR RotationOrigin,
[in] XMVECTOR RotationQuaternion,
[in] XMVECTOR Translation
);