如何使用SSE指令集来完成2个双精度浮点数或4个浮点数? (至SSE4) [英] How to absolute 2 double or 4 floats using SSE instruction set? (Up to SSE4)

查看:1007
本文介绍了如何使用SSE指令集来完成2个双精度浮点数或4个浮点数? (至SSE4)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我尝试使用SSE加速的示例C代码,这两个数组长度为3072个元素,并且双精度浮点数,如果我不需要精度双精度浮点数,可以将其降低到浮点数。
$ b

  double sum = 0.0; (k = 0; k <3072; k ++){
sum + = fabs(sima [k] - simb [k])的

;
}

double fp =(1.0 - (sum /(255.0 * 1024.0 * 3.0)));

无论如何,我目前的问题是如何在SSE寄存器中执行fabs步骤,以便双打或浮动我可以将整个计算保留在SSE寄存器中,以便它保持快速,并且可以通过部分展开此循环来并行化所有步骤。



这里是我的一些资源找到 fabs()asm 或可能翻转标志 - SO 但是第二个弱点需要一个有条件的检查。

解决方案

可能最简单的方法如下:

  __ m128d vsum = _mm_set1_pd(0.0); (k = 0; k <3072; k + = 2)
{
__m128d va = _mm_load_pd(& sima [k]); // init部分和
; //从sima载入2个双打,simb
__m128d vb = _mm_load_pd(& simb [k]);
__m128d vdiff = _mm_sub_pd(va,vb); // calc diff = sima - simb
__m128d vnegdiff = mm_sub_pd(_mm_set1_pd(0.0),vdiff); // calc neg diff = 0.0 - diff
__m128d vabsdiff = _mm_max_pd(vdiff,vnegdiff); // calc abs diff = max(diff, - diff)
vsum = _mm_add_pd(vsum,vabsdiff); //累积两个部分和

$ $ $
$ b $ p注意这可能不比标量快现代x86 CPU上的代码,无论如何它们通常都有两个FPU。但是,如果你可以下降到单精度,那么你可能会得到2倍的吞吐量改进。



还要注意,你需要将<$ c中的两个部分和$ c> vsum 转换为循环后的标量值,但这样做相当微不足道,并且不是性能关键。


Here's the sample C code that I am trying to accelerate using SSE, the two arrays are 3072 element long with doubles, may drop it down to float if i don't need the precision of doubles.

double sum = 0.0;

for(k = 0; k < 3072; k++) {
    sum += fabs(sima[k] - simb[k]);
}

double fp = (1.0 - (sum / (255.0 * 1024.0 * 3.0)));

Anyway my current problem is how to do the fabs step in a SSE register for doubles or float so that I can keep the whole calculation in the SSE registers so that it remains fast and I can parallelize all of the steps by partly unrolling this loop.

Here's some resources I've found fabs() asm or possibly this flipping the sign - SO however the weakness of the second one would need a conditional check.

解决方案

Probably the easiest way is as follows:

__m128d vsum = _mm_set1_pd(0.0);        // init partial sums
for (k = 0; k < 3072; k += 2)
{
    __m128d va = _mm_load_pd(&sima[k]); // load 2 doubles from sima, simb
    __m128d vb = _mm_load_pd(&simb[k]);
    __m128d vdiff = _mm_sub_pd(va, vb); // calc diff = sima - simb
    __m128d vnegdiff = mm_sub_pd(_mm_set1_pd(0.0), vdiff); // calc neg diff = 0.0 - diff
    __m128d vabsdiff = _mm_max_pd(vdiff, vnegdiff);        // calc abs diff = max(diff, - diff)
    vsum = _mm_add_pd(vsum, vabsdiff);  // accumulate two partial sums
}

Note that this may not be any faster than scalar code on modern x86 CPUs, which typically have two FPUs anyway. However if you can drop down to single precision then you may well get a 2x throughput improvement.

Note also that you will need to combine the two partial sums in vsum into a scalar value after the loop, but this is fairly trivial to do and is not performance-critical.

这篇关于如何使用SSE指令集来完成2个双精度浮点数或4个浮点数? (至SSE4)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆