2

我得到的 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))堆栈上的一些数组甚至没有收到警告,我确信它一定是在推送和弹出__m128s (我记得在 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
);
4

1 回答 1

1

堆栈上的变量是对齐的。据我记得,Visual C++ 总是正确地过度对齐堆栈变量。

您看到的第四个参数的错误是您的 Visual C++ 无法将过度对齐的类型作为值参数传递为堆栈上的指针。前三个通过寄存器传递。

用于__vectorcall通过寄存器(六个)传递更多参数,并通过堆栈值传递其余参数(因此即使是第 7 个参数也可以避免错误)。

使用可以正常传递过度对齐类型的最新 Visual C++(从 Visual C++ 2017 开始)。(最近修复了一个错误,但它是关于传递非平凡可复制的过度对齐类型,xmm 类型是可平凡复制的,所以它们很好)。

更好地使用最新的 Visual C++ 和__vectorcall:-)

于 2021-11-10T11:07:59.820 回答