我正在尝试使用 SSE 加速我的代码,并且以下代码运行良好。基本上是一个 __m128
变量应连续指向 4 个 float ,以便一次执行 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 位和 float
数据为 32 位。因此,128 位指针可能无法指向不能被 128 整除的地址。
无论如何,您知道问题出在哪里以及我该如何解决吗?
而不是像这样使用隐式对齐的加载/存储:
__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 倍或更高的命中率。
我是一名优秀的程序员,十分优秀!