原文:https://blog.csdn.net/nick_wong/article/details/7779381
先上代码:
-
/*g++ -msse2 main.cpp -lrt*/
-
#include <iostream>
-
#include <xmmintrin.h>//SSE指令集需包含词头文件
-
#include <time.h>
-
using namespace std;
-
#define N 120
-
int main() {
-
struct timespec tpstart,tpend;
-
clock_gettime(CLOCK_MONOTONIC, &tpstart);
-
/////////////////do something
-
{
-
__m128 *p1,*p2,*p3;//__m128是一个长128位的数据类型,存放在寄存器中
-
__attribute(aligned(128)) float f1[N],f2[N],f3[N];//新建一些浮点型数组
-
/*__attribute(aligned(128))强制使编译器在给f1等分配内存空间时对齐在128位(8字节)上*/
-
//cout<<f1<<"\t"<<(int)f1%128<<endl;
-
/*运行此条语句可以看出地址f1总是128的倍数,在内存上即是总存在一行上,使得总线取值时能够一次取完*/
-
for(int i=0; i<N; i++) {
-
f1[i]=i+0.12;
-
f2[i]=i+0.16;
-
}
-
for(int time=0; time<10000; time++) {
-
p1=(__m128*)f1;
-
p2=(__m128*)f2;
-
p3=(__m128*)f3;
-
for(int i=0; i<N; i+=4) {
-
*p3=_mm_mul_ps(*p1,*p2);//此函数封装了一些汇编原语,使得可以同时计算4个值的乘法
-
p3++;
-
p2++;
-
p1++;
-
}
-
/*注意N的取值,N取为4的整数倍,使得最后一次调用SSE指令时刚好能全部处理完。否则容易引发段错误。
-
所以,即使不能使用完,也一定要申请4的整数背空间*/
-
}
-
}
-
/////////////////done
-
clock_gettime(CLOCK_MONOTONIC, &tpend);
-
long timedif = (tpend.tv_sec-tpstart.tv_sec)*1000*1000+(tpend.tv_nsec-tpstart.tv_nsec)/1000;
-
cout<<"SSE:\t"<<timedif<<endl;
-
/////////////////////////不采用SSE指令/////////////////////////////////////
-
clock_gettime(CLOCK_MONOTONIC, &tpstart);
-
/////////////////do something
-
{
-
float f1[N],f2[N],f3[N];
-
for(int i=0; i<N; i++) {
-
f1[i]=i+0.12;
-
f2[i]=i+0.16;
-
}
-
for(int time=0; time<10000; time++) {
-
for(int i=0; i<N; i++) {
-
f3[i]=f1[i]*f2[i];
-
}
-
}
-
}
-
/////////////////done
-
clock_gettime(CLOCK_MONOTONIC, &tpend);
-
timedif = (tpend.tv_sec-tpstart.tv_sec)*1000*1000+(tpend.tv_nsec-tpstart.tv_nsec)/1000;
-
cout<<"noSSE:\t"<<timedif<<endl;
-
return 0;
-
}
注意计时函数需要包含的头文件和编译选项,clock_gettime函数能精确到纳秒。
运行结果为:
SSE: 4929
noSSE: 9980
以微秒为单位,平均提高约两倍。
下面是另一份代码,演示如何动态申请空间,注意内存对齐:
-
#include <xmmintrin.h>
-
#include <iostream>
-
using namespace std;
-
const int N=120;
-
int main()
-
{
-
__m128 *p1,*p2,*p3;
-
__attribute(aligned(128)) float *pf1,*pf2,*pf3;
-
pf1=(float *)_mm_malloc(sizeof(float)*N,128);
-
pf2=(float *)_mm_malloc(sizeof(float)*N,128);
-
pf3=(float *)_mm_malloc(sizeof(float)*N,128);
-
cout<<(int)pf1%128<<endl;
-
cout<<(int)pf2%128<<endl;
-
cout<<(int)pf3%128<<endl;
-
for(int i=0;i<N;i++){
-
pf1[i]=i+0.12;
-
pf2[i]=i+0.16;
-
};
-
p1=(__m128*)pf1;
-
p2=(__m128*)pf2;
-
p3=(__m128*)pf3;
-
for(int i=0;i<N;i+=4){
-
*p3=_mm_add_ps(*p1,*p2);
-
p3++;
-
p2++;
-
p1++;
-
}
-
_mm_free(pf1);
-
_mm_free(pf2);
-
_mm_free(pf3);
-
return 0;
-
}