c - 寻址非整数地址和 sse

标签 c pointers x86 sse memory-alignment

我正在尝试使用 SSE 加速我的代码,并且以下代码运行良好。 基本上是一个 __m128变量应连续指向 4 个 float ,以便一次执行 4 个操作。

这段代码相当于计算c[i]=a[i]+b[i]i来自 03 .

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来自 03 , 它在执行时崩溃。

__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 倍或更高的命中率。

关于c - 寻址非整数地址和 sse,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19376042/

相关文章:

c - 在 C 中访问函数外部的结构变量

C++ 链表结构引用为双指针,需要访问下一个节点

assembly - execve shellcode 写段错误

c++ - 在 C/C++ 中的特定地址边界上对齐内存是否仍能提高 x86 性能?

构造时调用的 C 静态测试

c - 使用Arduino生成黄金码调制的正弦波

C++ 使用指向模板对象的指针

c++ - 如何在C++中获取整数数组的元素数量?

python - 是否有用 C 编写的 python 模块的 fini 例程?

assembly - 进入保护模式后尝试跳转时出错 - 程序集引导加载程序