首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SSE工作在元素数不是4的倍数的数组上。

SSE工作在元素数不是4的倍数的数组上。
EN

Stack Overflow用户
提问于 2016-09-08 06:34:08
回答 1查看 841关注 0票数 0

所有人。

我的问题是是否有三个数组,如下所示

代码语言:javascript
复制
float a[7] = {1.0, 2.0, 3.0, 4.0, 
              5.0, 6.0, 7.0};
float b[7] = {2.0, 2.0, 2.0, 2.0,
              2.0, 2.0, 2.0};
float c[7] = {0.0, 0.0, 0.0, 0.0,
              0.0, 0.0, 0.0};

我想按以下方式执行元素级的乘法操作

代码语言:javascript
复制
c[i] = a[i] * b[i], i = 0, 1, ..., 6

对于前四个元素,我可以使用SSE本质,如下所示

代码语言:javascript
复制
__m128* sse_a = (__m128*) &a[0];
__m128* sse_b = (__m128*) &b[0];
__m128* sse_c = (__m128*) &c[0];

*sse_c = _mm_mul_ps(*sse_a, *sse_b);

C中的内容将是

代码语言:javascript
复制
c[0] = 2.0, c[1] = 4.0, c[2] = 6.0, c[3] = 8.0
c[4] = 0.0, c[5] = 0.0, c[6] = 0.0

在索引4、5和6中剩下的三个数字,我使用下面的代码来执行按元素进行的乘法操作。

代码语言:javascript
复制
sse_a = (__m128*) &a[4];
sse_b = (__m128*) &b[4];
sse_c = (__m128*) &c[4];

float mask[4] = {1.0, 1.0, 1.0, 0.0};
__m128* sse_mask = (__m128*) &mask[0];

*sse_c = _mm_add_ps( *sse_c, 
    _mm_mul_ps( _mm_mul_ps(*sse_a, *sse_b), *sse_mask ) );

c4-6中的内容将是

代码语言:javascript
复制
c[4] = 10.0, c[5] = 12.0, c[6] = 14.0, which is the expected result.

_mm_add_ps()并行地添加四个浮点,在数组a、b和c中分别在索引4、5和6中分配第一、第二和第三个浮点数。但是第四个浮点数没有分配给数组。为了避免无效的内存访问,我在sse_mask上乘以使第四个数字为零,然后再将结果添加回sse_c (数组c)。

但我想知道这是否安全?

非常感谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-08 07:01:02

您的数学操作似乎是正确的,但我不确定像您所做的那样使用强制转换是在__m128 vars中加载和存储数据的方法。

装载和储存

若要将数据从数组加载到__m128变量,应使用__m128 _mm_load_ps (float const* mem_addr)__m128 _mm_loadu_ps (float const* mem_addr)。很容易搞清楚这里是什么,但是有几个精确性:

  • 对于涉及访问或操作内存的操作,通常有两个函数执行相同的操作,例如loadloadu。第一个要求您的内存在一个16字节的边界上对齐,而u版本则没有这个要求。如果您不知道内存对齐,请使用u版本。
  • 您还拥有load_psload_pd。不同之处是:s代表单精度,而d代表双精度(好的旧float)。当然,您只能在每个__m128变量中放置两个双倍,但是可以放置4个浮点数。

所以从数组中加载数据非常容易,只需做:__m128* sse_a = _mm_loadu_ps(&a[0]);。对b做同样的操作,但是对于c,这确实取决于。如果你只想要乘法的结果,它是无用的初始化它在0,加载它,然后把乘法的结果到它,然后最后得到它回来。

您应该使用load的挂起操作来存储数据,即void _mm_storeu_ps (float* mem_addr, __m128 a)。因此,一旦复制完成并在sse_c中得到结果,只需执行_mm_storeu_ps(&c[0@, sse_c) ;

算法

使用掩码背后的想法是好的,但您有一些更简单的东西:从a[3]加载ans存储数据(b和c相同)。那样的话,它就会有4个元素,所以就没有必要使用任何掩码了?是的,有一个操作已经对第三个元素完成了,但这将是完全透明的:store操作将用新的值替换旧值。既然两者是平等的,那就不是问题了。

另一种方法是在数组中存储8个元素,即使只需要7个。这样,您就不必担心内存是否被分配了,不需要像上面这样的特殊逻辑来支付3个浮点数的成本,这在最近的所有计算机上都是没有的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39384037

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档