我对英特尔SSE内在函数的各种算术运算有疑问。 做一个_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));
有人可以帮忙解释一下。
答案 0 :(得分:4)
_mm_add_ps
将float
添加到一起,其中_mm_add_epi8/16/32
添加整数,这些整数不是浮点数。
_mm_loadu_ps
不要求您的浮点数对齐16字节(128位),而_mm_load_ps
确实需要16字节对齐。
因此,如果第一个出现seg故障,那么你的对齐是错误的。
在posix_memalign
页面上显示:
如果出现以下情况,posix_memalign()函数将失败:
[EINVAL]对齐参数的值不是2的幂 sizeof(void *)的倍数。
我不确定sizeof(float)
== sizeof(void*)
??
每this,它在C(在32位系统上)似乎是相同的。好的,这里有点小技巧,因为指针的大小通常是CPU寄存器宽度的大小,32位或64位(8字节),具体取决于所使用的系统,而float
通常为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.