无法在 x86 上以 SSE 类型访问内存,但在 x64 上工作正常
Posted
技术标签:
【中文标题】无法在 x86 上以 SSE 类型访问内存,但在 x64 上工作正常【英文标题】:Cannot access memory as SSE type on x86 but works fine on x64 【发布时间】:2012-05-07 15:42:17 【问题描述】:我有一些使用 MSVC SSE 内在函数编写的代码。
__m128 zero = _mm_setzero_ps();
__m128 center = _mm_load_ps(&sphere.origin.x);
__m128 boxmin = _mm_load_ps(&rhs.BottomLeftClosest.x);
__m128 boxmax = _mm_load_ps(&rhs.TopRightFurthest.x);
__m128 e = _mm_add_ps(_mm_max_ps(_mm_sub_ps(boxmin, center), zero), _mm_max_ps(_mm_sub_ps(center, boxmax), zero));
e = _mm_mul_ps(e, e);
__declspec(align(16)) float arr[4];
_mm_store_ps(arr, e);
float r = sphere.radius;
return (arr[0] + arr[1] + arr[2] <= r * r);
Math::Vector
类型(sphere.origin
、rhs.BottomLeftClosest
和 rhs.TopRightFurthest
的类型)实际上是一个包含 3 个浮点数的数组。我将它们对齐到 16 个字节,这段代码在 x64 上执行得很好。但是在 x86 上,我在读取空指针时遇到访问冲突。关于这来自哪里的任何建议?
【问题讨论】:
未对齐的 SSE 访问将显示为空指针访问。 是的,听起来像是未对齐的负载。尝试使用loadu
而不是load
,看看错误是否消失。或者直接进入调试器,检查地址
好的,反对票是怎么回事?
@jalf 诸如“为什么 __m128 center = _mm_load_ps(&sphere.origin.x);
_mm_load_ps() 要求传递的指针是 16 字节对齐的。没有证据表明您确保 sphere.origin.x 正确对齐。如果您无法提供该保证,则需要改用 _mm_loadu_ps()。
【讨论】:
这当然解决了问题。显然,将__declspec(align(16))
添加到origin
的声明实际上并不意味着它是16 字节对齐的。那好吧。谢谢你。
对,不行,你不能对齐结构或类成员。
如果编译器能提到这一点就好了。
嗯,这很困难,因为它无法猜测您需要绝对对齐而不是相对对齐。您可以将功能请求发布到 connect.microsoft.com
那么如何访问大量的浮点数呢?你可以保证第一个元素是 16 Byte 元素,其他的呢?以上是关于无法在 x86 上以 SSE 类型访问内存,但在 x64 上工作正常的主要内容,如果未能解决你的问题,请参考以下文章
不同的 mmx、sse 和 avx 版本是互补的还是彼此的超集?