Пример использования
встроенных функций SSE в программе на Си:
// скалярное произведение векторов
#include<stdio.h>
#include<xmmintrin.h>
#include"mark2.c"
#define N 10000000
// <обычная> функция
float inner1(float *x,float *y,int n)
{ float s;
int i;
s=0;
for(i=0;i<n;i++) s+=x[i]*y[i];
return s;
}
// функция с
использованием SSE intrinsics
float inner2(float *x,float *y,int n)
{ float sum;
int i;
__m128
*xx,*yy;
__m128 p,s;
xx=(__m128
*)x;
yy=(__m128
*)y;
s=_mm_set_ps1(0);
for (i=0;i<n/4;i++)
{ // предвыборка данных в кэш (на
несколько итераций вперед)
_mm_prefetch((char
*)&xx[i+4],_MM_HINT_NTA);
_mm_prefetch((char *)&yy[i+4],_MM_HINT_NTA);
p=_mm_mul_ps(xx[i], yy[i]); // векторное умножение четырех
чисел
s=_mm_add_ps(s,p);
// векторное сложение четырех чисел
}
p=_mm_movehl_ps(p,s);
// перемещение двух старших значений s в младшие p
s=_mm_add_ps(s,p);
// векторное сложение
p=_mm_shuffle_ps(s,s,1);
//перемещение второго значения в s в младшую позицию в p
s=_mm_add_ss(s,p);
// скалярное сложение
_mm_store_ss(&sum,s);
// запись младшего значения в память
return sum;
}
int main()
{ float *x,*y,s;
long t;
int i;
// выделение памяти с выравниванием
x=(float *)_mm_malloc(N*sizeof(float),16);
y=(float
*)_mm_malloc(N*sizeof(float),16);
for
(i=0;i<N;i++) { x[i]=10*i/N; y[i]=10*(N-i-1)/N; }
// Using x87
time_start();
s=inner1(x,y,N);
t=time_stop();
printf("Result: %f\n",s);
printf("Time: %ld\n",t);
// Using SSE
time_start();
s=inner2(x,y,N);
t=time_stop();
printf("Result: %f\n",s);
printf("Time: %ld\n",t);
_mm_free(x);
_mm_free(y);
return 0;
}
Пример команды компиляции:
gcc -march=pentium4 -O3 prog.c