寻址非整数地址和sse

时间:2013-10-15 08:01:16

标签: c++ c pointers sse

我正在尝试使用sse加速我的代码,以下代码运行良好。 基本上__m128变量应该指向一行中的4个浮点数,以便一次执行4个操作。

此代码相当于从c[i]=a[i]+b[i]i计算0 3

float *data1,*data2,*data3
// ... code ... allocating data1-2-3 which are very long.
__m128* a = (__m128*) (data1);
__m128* b = (__m128*) (data2);
__m128* c = (__m128*) (data3);
*c = _mm_add_ps(*a, *b);

但是,当我想稍微改变我使用的数据时(见下文),为了从c[i]=a[i+1]+b[i]i计算0 3,它在执行时崩溃。

__m128* a = (__m128*) (data1+1); // <-- +1
__m128* b = (__m128*) (data2);
__m128* c = (__m128*) (data3);
*c = _mm_add_ps(*a, *b);

我的猜测是,它与__m128为128位且浮点数据为32位这一事实有关。因此,128位指针可能无法指向不能被128整除的地址。

无论如何,你知道问题是什么以及如何绕过它吗?

3 个答案:

答案 0 :(得分:5)

而不是像这样使用隐式对齐的加载/存储:

__m128* a = (__m128*) (data1+1); // <-- +1
__m128* b = (__m128*) (data2);
__m128* c = (__m128*) (data3);
*c = _mm_add_ps(*a, *b);

根据需要使用显式对齐/未对齐的加载/存储,例如:

__m128 va = _mm_loadu_ps(data1+1); // <-- +1 (NB: use unaligned load)
__m128 vb = _mm_load_ps(data2);
__m128 vc = _mm_add_ps(va, vb);
_mm_store_ps(data3, vc);

相同数量的代码(即相同数量的指令),但它不会崩溃,并且您可以明确控制哪些加载/存储已对齐且哪些未对齐。

请注意,最近的CPU对未对齐的负载的处罚相对较小,但在较旧的CPU上,可能会有2倍或更高的命中率。

答案 1 :(得分:1)

这里的问题是a最终指向的不是__m128;它指向包含__m128的最后96位和外部32位的东西,可以是任何东西。它可能是下一个__m128的前32位,但最终,当您到达同一内存块中的最后一个__m128时,它将是其他内容。也许你无法访问的保留内存,因此崩溃。

答案 2 :(得分:0)

我对sse不太熟悉,但我认为你可以制作一个本地(或另一个副本)数据,这些数据在128处正确分配,并包含4个来自data1 + 1位置的浮点数。

希望这有帮助, 勒兹。