0

我对英特尔 SSE 内在函数的各种算术运算有疑问。做 _mm_add_ps 与做 _mm_add_ps 有什么区别?_mm_add_epi8/16/32?我想确保我的数据始终保持一致。

在我执行此操作时的示例代码中:

 __m128 u1 = _mm_load_ps(&V[(i-1)]);

我得到一个分段错误。但是当我这样做时:

 __m128 u1 = _mm_loadu_ps(&V[(i-1)]);

它工作正常。

因为我希望我的数据对齐,所以我声明了这样的数组:

 posix_memalign((void**)&V, 16, dx*sizeof(float));

有人可以帮忙解释一下吗。

4

1 回答 1

4

_mm_add_psfloats 加在一起,其中_mm_add_epi8/16/32添加不是浮点数的整数。

_mm_loadu_ps不需要您浮点数为 16 字节(128 位)对齐,而_mm_load_ps需要 16 字节对齐。

因此,如果您在第一个上遇到 seg 错误,则说明您的对齐方式是错误的。

posix_memalign页面上它说:

如果出现以下情况,posix_memalign() 函数将失败:

[EINVAL] 对齐参数的值不是 sizeof(void *) 的两个倍数的幂。

我不确定sizeof(float)== sizeof(void*)?? 根据这个,它在 C 中似乎是相同的(在 32 位系统上)。好的,这里有点小技巧,因为指针的大小通常是 CPU 寄存器宽度的大小,32 位或 64 位(8 字节)取决于使用的系统,而 afloat通常是 32 位(4 字节)

您的对齐分配应该看起来更像这样:

posix_memalign((void**)&V, 16, dx*sizeof(void*)); //since it will the correct size for your platform.  You can always cast to `float` later on.
于 2012-06-15T16:37:25.410 回答