Advertisement
Guest User

Untitled

a guest
Dec 13th, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.32 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <Windows.h> // для замера времени выполнения программы
  5. #include <cmath>
  6.  
  7.  
  8. // Функция для обработки массивов данных без использования SSE
  9. void calcCPP(int nelems, float* mas1, float* mas2, float* mas3)
  10. {
  11. float sqr1;
  12. float sqr2;
  13.  
  14. // TODO: Модифицировать реализацию функции в соответствии с заданием.
  15. for (int i = 0; i < nelems; i++) {
  16. sqr1 = mas1[i] * mas1[i];
  17. sqr2 = mas2[i] * mas2[i];
  18.  
  19. mas3[i] = sqrt(0.3 * sqr1 + sqr2);
  20. }
  21. }
  22.  
  23.  
  24. // Функция для обработки массивов данных с использованием SSE
  25. void calcSSE(int nelems, float* mas1, float* mas2, float* mas3)
  26. {
  27. int niters = nelems / 4; // количество итераций цикла
  28. float v[4];
  29. for (int i = 0; i < 4; i++)
  30. {
  31. v[i] = 0.3f;
  32. }
  33. __asm
  34. {
  35. pushf
  36. push edi
  37. push esi
  38. push ebx
  39. push ecx
  40. push eax
  41.  
  42. movups xmm4, [v] // Инициализация констант
  43.  
  44. mov esi, mas1 // Инициализация указателей
  45. mov edi, mas2
  46. mov ebx, mas3
  47.  
  48. mov ecx, niters // Инициализация счетчика цикла
  49.  
  50. cycle :
  51.  
  52. movaps xmm1, [esi]
  53. add esi, 16
  54. mulps xmm1, xmm1
  55. mulps xmm1, xmm4 // 0.3f*sqr1[i]
  56.  
  57. movaps xmm2, [edi]
  58. add edi, 16
  59. mulps xmm2, xmm2 // sqr2[i]
  60.  
  61. addps xmm1, xmm2
  62.  
  63. sqrtps xmm5, xmm1
  64.  
  65. movntps[ebx], xmm5 // в память mas3
  66. add ebx, 16
  67.  
  68. dec ecx
  69. jnz cycle
  70.  
  71. pop eax
  72. pop ecx
  73. pop ebx
  74. pop esi
  75. pop edi
  76. popf
  77. }
  78. }
  79.  
  80.  
  81. // Функция инициализации содержания массива
  82. void init_mas(int nelems, float* mas, float val0)
  83. {
  84. float val;
  85. val = val0;
  86. for (int i = 0; i < nelems; i++)
  87. {
  88. mas[i] = val;
  89. val += 0.5f;
  90. }
  91. }
  92.  
  93.  
  94. // Функция сравнения содержания двух массивов
  95. bool compare_masses(int nelems, float* mas1, float* mas2)
  96. {
  97. bool res = true;
  98. float delta;
  99. float base;
  100.  
  101. for (int i = 0; i < nelems; i++)
  102. {
  103. delta = abs(mas2[i] - mas1[i]);
  104. base = max(abs(mas1[i]), abs(mas2[i]));
  105. if (base != 0)
  106. {
  107. // Контроль по относительной погрешности
  108. if (delta / base > 1e-4)
  109. res = false;
  110. }
  111. }
  112. return res;
  113. }
  114.  
  115.  
  116. // Функция расчета интервала времени (мс)
  117. float eval_time_interval(LARGE_INTEGER hrStart, LARGE_INTEGER hrEnd, int ncycles)
  118. {
  119. LARGE_INTEGER hrFrequency; // частота работы таймера высокого разрешения
  120. float interval, time_ms;
  121.  
  122. if (!QueryPerformanceFrequency(&hrFrequency))
  123. {
  124. // High resolution timer is not available!
  125. time_ms = -1.0;
  126. }
  127. else
  128. {
  129. interval = (hrEnd.LowPart - hrStart.LowPart) / (float)hrFrequency.LowPart;
  130. time_ms = 1000.0 * interval / (float)ncycles;
  131. }
  132. return time_ms;
  133. }
  134.  
  135.  
  136. // Точка входа в приложение
  137. int main()
  138. {
  139. char str[80];
  140. LARGE_INTEGER hrStartCPP, hrEndCPP; // замер времени без SSE
  141. LARGE_INTEGER hrStartSSE, hrEndSSE; // замер времени с SSE
  142. int ncycles = 1000; // количество циклов выполнения функции
  143. float timeCPP, timeSSE; // время обработки без SSE и c SSE
  144. bool isCorrect;
  145.  
  146. // Выделение памяти под массивы
  147. const int nelems = 1024 * 1024;
  148. float* mas1 = (float*)malloc(nelems * 4);
  149. float* mas2 = (float*)malloc(nelems * 4);
  150. float* resCPP = (float*)malloc(nelems * 4);
  151. float* resSSE = (float*)malloc(nelems * 4);
  152.  
  153. // Инициализируем начальные значения массивов
  154. init_mas(nelems, mas1, 1.0f);
  155. init_mas(nelems, mas2, 2.0f);
  156.  
  157. // Обработка массивов без SSE
  158. printf("Processing masses without SSE...\n");
  159. QueryPerformanceCounter(&hrStartCPP); // начало отсчета времени
  160. for (int i = 0; i < ncycles; i++)
  161. {
  162. calcCPP(nelems, mas1, mas2, resCPP);
  163. }
  164. QueryPerformanceCounter(&hrEndCPP); // конец отсчета времени
  165.  
  166. // Обработка массивов с SSE
  167. printf("Processing masses with SSE...\n");
  168. QueryPerformanceCounter(&hrStartSSE); // начало отсчета времени
  169. for (int i = 0; i < ncycles; i++)
  170. {
  171. calcSSE(nelems, mas1, mas2, resSSE);
  172. }
  173. QueryPerformanceCounter(&hrEndSSE); // конец отсчета времени
  174.  
  175. // Анализ результатов обработки
  176. isCorrect = compare_masses(nelems, resCPP, resSSE);
  177. timeCPP = eval_time_interval(hrStartCPP, hrEndCPP, ncycles);
  178. timeSSE = eval_time_interval(hrStartSSE, hrEndSSE, ncycles);
  179.  
  180. // Освобождение памяти
  181. free(mas1); mas1 = NULL;
  182. free(mas2); mas2 = NULL;
  183. free(resCPP); resCPP = NULL;
  184. free(resSSE); resSSE = NULL;
  185.  
  186. // Вывод результатов измерения времени
  187. if (isCorrect)
  188. printf("Result is correct!\n");
  189. else
  190. printf("Result is not correct!\n");
  191. printf("Processing time without SSE, ms: %13.5f\n", timeCPP);
  192. printf("Processing time with SSE, ms: %13.5f\n", timeSSE);
  193. printf("Press Enter to exit.\n");
  194. gets_s(str, sizeof(str));
  195. return 0;
  196. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement