开发人员如何从SSE中受益

SSE(StreamingSIMDExtensions)是Intel公司推出的一种基于向量处理器的指令集,可以提高应用程序的性能。如何在开发中充分利用SSE,让程序减少计算时间、提高效率?笔者将从多个角度为大家详细解读。

理解SSE

SSE的概念与特点

SSE是Intel公司推出的一种SIMD(单指令多数据处理)指令集,用于高效地进行向量数据处理。SSE可以将多个数据同时加载到处理器中,进行同一种操作,从而提高了计算速度。SSE最早是在PentiumIII处理器中出现的,目前已经推广到了大多数的处理器中。

SSE的特点包括:

比较高的时钟频率单指令可以同时处理多个数据SIMD指令可以提高矩阵运算的速度支持单精度浮点运算可用于D游戏开发、数字信号处理、图像处理等领域

SSE的版本和区别

SSE一共发布了四个版本,分别是SSE、SSE2、SSE和SSE4。

其中,SSE版本最早推出,支持单精度浮点和整数指令。SSE2简化了循环和判断操作的指令,支持64位浮点数运算。SSE增加了16种新的指令,包括针对无符号比较、乘积运算、插值等操作。在SSE4版本中,增加了2种新的指令,主要用于XML解析器、字符串处理器、郑码转换器、标记解析器等。

SSE的应用场景

数字信号处理

数字信号处理是一种基于数字信号进行处理的技术,如分析、合成、增强等。在数字信号处理中,可以通过SSE指令简单高效地进行相关计算,例如:

voidresample(constfloat*src,intn_src,float*dst,intn_dst,constfloat*filter,intn_filter,floatcutoff){

constfloatfactor=(float)n_src/(float)n_dst;floatacc=0;for(inti_dst=0;i_dstn_dst;++i_dst){floatpos_src=i_dst*factor;inti_src=(int)pos_src;floatfrac=pos_src-i_src;floatweight_0=filter[0],weight_1=0.f,weight_diff=0;for(intj=1;jn_filteri_src-j=-1;++j){floatw=filter[j];floats=src[i_src-j];

weight_diff+=fabs(weight_1-w);

weight_1=weight_0;

weight_0=w;

acc+=(s*weight_1+s*weight_0)*0.5f;if(j16weight_diffcutoff){

i_src-=j-1;

gotopass;

}

}for(intj=0;j=i_src;++j){floatw=filter[i_src-j];floats=src[j];

acc+=s*w;

}

pass:

dst[i_dst]=acc;

acc=0;

}

}

图像处理

相比于数字信号处理,图像处理对CPU品质与计算速度要求更高。例如怎样快速高效完成图像的融合?

在这里,我们以OpenCV中的addWeighted函数为例,对代码进行分析。

voidaddWeighted(InputArraysrc1,doublealpha,InputArraysrc2,doublebeta,doublegamma,OutputArraydst,intdtype=-1);

其中,函数参数含义如下:

src1,src2:两幅输入图像,需保证尺寸和类型相同。alpha,beta:两个图像的权重系数。gamma:亮度调节系数。而使用SSE2指令集可加速公式计算。

使用SSE2指令集可加速公式计算。使用SSE指令集的代码如下:

if(use_sse)

{for(inti=0;i(len~7);i+=8)

{__mdXmm=_mm_loadu_pd((constdouble*)(alpha+i));__mdtemp_a=_mm_shuffle_pd(Xmm,Xmm,_MM_SHUFFLE2(0,0));__mdtemp_b=_mm_shuffle_pd(Xmm,Xmm,_MM_SHUFFLE2(1,1));

_mm_storel_pd((double*)(alpha1+i),temp_a);

_mm_storel_pd((double*)(beta1+i),temp_b);

_mm_storer_pd((double*)(alpha1+i+2),temp_a);

_mm_storer_pd((double*)(beta1+i+2),temp_b);

_mm_storeh_pd((double*)(alpha1+i+4),temp_a);

_mm_storeh_pd((double*)(beta1+i+4),temp_b);

}

}

三维动画

除了图片扫描和图形绘制,SSE还广泛用于D游戏、视频播放、数据处理等领域。下面,我们介绍在反向动力学中的应用场景。

在D动画中,动呈现关节为平级关节,易解(Alartetal.,)。然而,在华丽动感的更复杂的组合关节中,其动力学肌肉/软体方程则较难表示。

因此,在微小得高计算资源的智能设备中,可以将运动学预测与动推理的遭遇甚至提高效率。

如何编写SSE代码

内联汇编

内联汇编可以直接在C/C++代码中插入SSE指令,提高了程序的运行速度。下面是一段SSE运算的内联汇编代码例子:

voidsimd_multiply(float*dst,constfloat*src1,constfloat*src2,intcount){intsimd_count=count/4;

__ma,b,r;inti=0;for(;isimd_count;++i){

a=_mm_loadu_ps(src1+i*4);

b=_mm_loadu_ps(src2+i*4);

r=_mm_mul_ps(a,b);

_mm_storeu_ps(dst+i*4,r);

}for(;icount;++i){

dst[i]=src1[i]*src2[i];

}

}

SSE指令集

除了内联汇编外,还可以直接使用SSE指令集进行编写,下面列举一些常用的指令:

加载四元数据(loadX_x)存储四元数据(storeX_x)加法运算(add_x)乘法运算(mul_x)比较运算(cmp_x)线性插值运算(lerp_x)

总结

本文从多个角度介绍了SSE的概念、特点、应用场景和编写方式。相信读完本文,你会对SSE有一个更深入的认识,对于减少计算时间和提高程序效率也更有信心了。

(原创不易,如果喜欢请随手


转载请注明:http://www.aierlanlan.com/grrz/5016.html