Пример использования встроенных функций 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