Advertisement
MargaritaOwl

ArhSSE

Jun 1st, 2016
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.93 KB | None | 0 0
  1. #include <iostream>
  2. #include <ctime>
  3. #include <xmmintrin.h>
  4. #include <cstdlib>
  5. using namespace std;
  6. #define p 8000
  7. float **matrA = (float **)_mm_malloc(p * sizeof(float), 16);
  8. float **matrB = (float **)_mm_malloc(p * sizeof(float), 16);
  9. float *vectX = (float *)_mm_malloc(p * sizeof(float), 16);
  10. float *vectY = (float *)_mm_malloc(p * sizeof(float), 16);
  11. void standart_function(float**matrA, float **matrB, float*vectX, float*vectY, float a, float b, int n);
  12. void sse_function(float**matrA, float **matrB, float*vectX, float*vectY, float a, float b, int n);
  13. float a, b;
  14. int main()
  15. {
  16.     //srand(time(0));
  17.     setlocale(LC_ALL, "rus");
  18.     clock_t time;
  19.     bool exitbool = true;
  20.     a = (rand() % 200 - 100) + ((rand() % 100) / 100.);
  21.     b = (rand() % 200 - 100) + ((rand() % 100) / 100.);
  22.     int step = 1000, highborder = 8000, tempnum;
  23.     for (int i = 0; i < p; i++)
  24.     {
  25.         matrA[i] = (float *)_mm_malloc(p * sizeof(float), 16);
  26.         matrB[i] = (float *)_mm_malloc(p * sizeof(float), 16);
  27.         vectX[i] = (rand() % 200 - 100) + ((rand() % 100) / 100.);
  28.         vectY[i] = (rand() % 200 - 100) + ((rand() % 100) / 100.);
  29.     }
  30.     for (int i = 0; i < p; i++)
  31.     {
  32.         for (int j = 0; j < p; j++)
  33.         {
  34.             matrA[i][j] = (rand() % 200 - 100) + ((rand() % 100) / 100.);
  35.             matrB[i][j] = (rand() % 200 - 100) + ((rand() % 100) / 100.);
  36.         }
  37.     }
  38.     if (highborder > 0 && highborder < p)
  39.     {
  40.         cout << "Введите размер массива: ";
  41.         cin >> highborder;
  42.     }
  43.     if (step > 0 && step < p&&step <= highborder)
  44.     {
  45.         cout << "Введите шаг(массив будет отсортирован от нуля с заданным шагом): ";
  46.         cin >> step;
  47.     }
  48.     while (exitbool)
  49.     {
  50.         cout << "Выберите способ выполнения операции alpha*matrix(A)*vector(x)+beta*matrix(B)*vector(b):\n1)выпонить стандартными операциями;\n2)выполнить с использованием расширений SSE;\nИначе, введите \"0\": ";
  51.         cin >> tempnum;
  52.         cout << endl;
  53.  
  54.         for (int j = 0; j <= highborder; j += step)
  55.         {
  56.             switch (tempnum)
  57.             {
  58.             case 1: {
  59.                 time = clock();
  60.                 standart_function(matrA, matrB, vectX, vectY, a, b, j);
  61.                 cout << "Стандартными операциями (" << j << "): " << ((double)(clock() - time)) / CLOCKS_PER_SEC << " секунд" << endl;
  62.                 break;
  63.             }
  64.             case 2: {
  65.                 time = clock();
  66.                 sse_function(matrA, matrB, vectX, vectY, a, b, j);
  67.                 cout << "SSE (" << j << "): " << ((double)(clock() - time)) / CLOCKS_PER_SEC << " секунд" << endl;
  68.                 break; }
  69.             case 0: {exitbool = false; }
  70.             }
  71.         }
  72.         cout << endl;
  73.     }
  74.         for (int i = 0; i < p; i++)
  75.         {
  76.             _mm_free(matrA[i]);
  77.             _mm_free(matrB[i]);
  78.         }
  79.         _mm_free(vectX);
  80.         _mm_free(vectY);
  81.         _mm_free(matrA);
  82.         _mm_free(matrB);
  83.    
  84.  
  85.     return 0;
  86. }
  87.  
  88. void standart_function(float**matrA, float **matrB, float*vectX, float*vectY, float a, float b, int n)
  89. {
  90.     float *rdvect1, *rdvect2;
  91.  
  92.     rdvect1 = (float *)_mm_malloc(n * sizeof(float), 16);//выделяем память
  93.     rdvect2 = (float *)_mm_malloc(n * sizeof(float), 16);
  94.     for (int i = 0; i < n; i++)
  95.     {
  96.         rdvect1[i] = 0;
  97.         for (int j = 0; j < n; j++)
  98.         {
  99.             rdvect1[i] += matrA[i][j] * vectX[j];
  100.             rdvect2[i] += matrB[i][j] * vectY[j];
  101.         }
  102.  
  103.         rdvect1[i] = a*rdvect1[i] + b*rdvect2[i];
  104.     }
  105. }
  106.  
  107. void sse_function(float**matrA, float **matrB, float*vectX, float*vectY, float a, float b, int n)
  108. {
  109.     __m128 *xx, *yy, ssrdvect1, sstemp1, ssrdvect2, sstemp2, aa, bb;
  110.     xx = (__m128 *)vectX;
  111.     yy = (__m128 *)vectY;
  112.  
  113.     aa = _mm_set_ps1(a);
  114.     bb = _mm_set_ps1(b);
  115.  
  116.     float *rdvect11 = (float *)_mm_malloc(n * sizeof(float), 16);//выделяем память
  117.     float *rdvect22 = (float *)_mm_malloc(n * sizeof(float), 16);
  118.     float *ready_vector = (float *)_mm_malloc(n * sizeof(float), 16);
  119.     for (int i = 0; i < n; i++)
  120.     {
  121.  
  122.         sstemp1 = _mm_set_ps1(a);//устанавливаем 4 значения, выведенных по адресу
  123.         sstemp2 = _mm_set_ps1(b);
  124.  
  125.         for (int j = 0; j<n / 4; j++)
  126.         {
  127.             ssrdvect1 = _mm_mul_ps(*((__m128 *)*(matrA + i) + j), *(xx + j));// векторное умножение четырех чисел
  128.             sstemp1 = _mm_add_ps(sstemp1, _mm_add_ps(ssrdvect1, _mm_movehl_ps(ssrdvect1, ssrdvect1)));
  129.  
  130.             ssrdvect2 = _mm_mul_ps(*((__m128 *)*(matrB + i) + j), *(yy + j));
  131.             ssrdvect2 = _mm_add_ps(sstemp2, _mm_add_ps(ssrdvect2, _mm_movehl_ps(ssrdvect2, ssrdvect2)));
  132.         }
  133.         _mm_store_ss((rdvect11 + i), _mm_add_ps(sstemp1, _mm_shuffle_ps(sstemp1, sstemp1, 1)));//запись младшего значения в память
  134.         _mm_store_ss((rdvect22 + i), _mm_add_ps(sstemp2, _mm_shuffle_ps(sstemp2, sstemp2, 1)));
  135.     }
  136.  
  137.     xx = (__m128 *)rdvect11;
  138.     yy = (__m128 *)rdvect22;
  139.     for (int i = 0; i < n / 4; i++, xx++, yy++)
  140.         _mm_store_ps((ready_vector + i * 4), _mm_add_ps(_mm_mul_ps(aa, *xx), _mm_mul_ps(bb, *yy)));
  141.  
  142.     _mm_free(rdvect11);//освобождаем память
  143.     _mm_free(rdvect22);
  144.     _mm_free(ready_vector);
  145.  
  146. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement