Advertisement
Guest User

Untitled

a guest
Jan 20th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.92 KB | None | 0 0
  1. // odwracanie kolejności elementów w tablicy jednowymiarowej
  2.  
  3. #include "cuda_runtime.h"
  4. #include "device_launch_parameters.h"
  5.  
  6. #include <stdio.h>
  7. #include <windows.h>
  8. #include <cmath>
  9. #include <limits>
  10. #include <float.h>
  11. #include <cstdlib>
  12. #include <ctime>
  13.  
  14. // liczba wątków
  15. const int N_THR = 512;
  16.  
  17. // rozmiar tablicy
  18. const int N = (1 << 23);
  19.  
  20. //////////////////////////////////////////////////////////////////
  21. // kod jądra - odwraca kolejność elementów w tablicy
  22. __global__ void reverseArray(int *d_in)
  23. {
  24. // fragmenty tablicy w pamięci współdzielonej
  25. __shared__ int s_data1[N_THR];
  26. __shared__ int s_data2[N_THR];
  27.  
  28. // indeksy elementów tablicy
  29. int in1 = blockDim.x * blockIdx.x + threadIdx.x;
  30. int in2 = N - blockDim.x * (blockIdx.x + 1) + threadIdx.x;
  31.  
  32. // indeks w tablicy w pamięci współdzielonej
  33. int out = blockDim.x - 1 - threadIdx.x;
  34.  
  35. // zapisanie elementów tablicy w pamięci współdzielonej
  36. s_data1[out] = d_in[in1];
  37. s_data2[out] = d_in[in2];
  38.  
  39. // synchronizacja wątków w bloku
  40. __syncthreads();
  41.  
  42. // zamiana elementów - przepisanie z pamięci współdzielonej
  43. // do pamięci globalnej
  44. d_in[in1] = s_data2[threadIdx.x];
  45. d_in[in2] = s_data1[threadIdx.x];
  46. }
  47.  
  48. /////////////////////////////////////////////////////////////////////
  49. // szuka najblizszego punktu
  50. __global__ int GetClosest(int *x, int *y/*, int index, int n*/)
  51. {
  52. __shared__ int s_data1[N_THR];
  53.  
  54. int a = x[index];
  55. int b = y[index];
  56. double minDistance = DBL_MAX;
  57. double tmp;
  58. int minIndex;
  59.  
  60. for (int i = 0; i < n; i++) {
  61. if (i != index) {
  62. tmp = sqrt(pow(x[i] - a, 2) + pow(y[i] - b, 2));
  63. if (tmp < minDistance) {
  64. minDistance = tmp;
  65. minIndex = i;
  66. }
  67. }
  68. }
  69. return minIndex;
  70. }
  71.  
  72. //////////////////////////////////////////////////////////////////
  73. int main(int argc, char* argv[])
  74. {
  75. // wybór karty na której zostana wykonane obliczenia
  76. if (cudaSetDevice(0) != cudaSuccess)
  77. {
  78. printf("cudaSetDevice failed! Do you have a CUDA-capable GPU installed?");
  79.  
  80. return 0;
  81. }
  82.  
  83. // utworzenie tablicy
  84. int *a_cpu = (int*)malloc(N * sizeof(int));
  85. if (!a_cpu)
  86. {
  87. printf("malloc failed!\n");
  88.  
  89. return 0;
  90. }
  91. for (int i = 0; i < N; ++i)
  92. a_cpu[i] = i;
  93.  
  94. // przydzielenie pamięci na karcie
  95. int *a_gpu;
  96. if (cudaMalloc((void**)&a_gpu, N * sizeof(int)) != cudaSuccess)
  97. {
  98. printf("cudaMalloc failed!\n");
  99.  
  100. return 0;
  101. }
  102.  
  103. // przekopiowanie tablicy do pamięci karty
  104. if (cudaMemcpy(a_gpu, a_cpu, N * sizeof(int), cudaMemcpyHostToDevice) != cudaSuccess)
  105. {
  106. printf("cudaMemcpy failed!\n");
  107.  
  108. return 0;
  109. }
  110.  
  111.  
  112. //**********************************
  113.  
  114. int *X = (int*)malloc(N * sizeof(int));
  115. int *Y = (int*)malloc(N * sizeof(int));
  116.  
  117. for (int i = 0; i < N; i++) {
  118. X[i] = rand() % 100;
  119. Y[i] = rand() % 100;
  120. }
  121.  
  122. // przydzielenie pamięci na karcie
  123. int *X_gpu;
  124. int *Y_gpu;
  125. if (cudaMalloc((void**)&X_gpu, N * sizeof(int)) != cudaSuccess)
  126. {
  127. printf("cudaMalloc failed!\n");
  128.  
  129. return 0;
  130. }
  131. if (cudaMalloc((void**)&Y_gpu, N * sizeof(int)) != cudaSuccess)
  132. {
  133. printf("cudaMalloc failed!\n");
  134.  
  135. return 0;
  136. }
  137.  
  138. // przekopiowanie tablicy do pamięci karty
  139. if (cudaMemcpy(X_gpu, X, N * sizeof(int), cudaMemcpyHostToDevice) != cudaSuccess)
  140. {
  141. printf("cudaMemcpy failed!\n");
  142.  
  143. return 0;
  144. }
  145. if (cudaMemcpy(Y_gpu, Y, N * sizeof(int), cudaMemcpyHostToDevice) != cudaSuccess)
  146. {
  147. printf("cudaMemcpy failed!\n");
  148.  
  149. return 0;
  150. }
  151.  
  152. //**********************************************
  153.  
  154. // rozmiar bloku i siatki bloków
  155. dim3 dimBlock(N_THR);
  156. dim3 dimGrid((N / 2) / N_THR);
  157.  
  158. printf("N: %d, dimBlock: %d, dimGrid: %d\n\n", N, dimBlock.x, dimGrid.x);
  159.  
  160. // utworzenie zdarzeń do pomiaru czasu obliczeń
  161. cudaEvent_t start, stop;
  162. if (cudaEventCreate(&start) != cudaSuccess)
  163. {
  164. printf("cudaEventCreate failed!\n");
  165.  
  166. return 0;
  167. }
  168. if (cudaEventCreate(&stop) != cudaSuccess)
  169. {
  170. printf("cudaEventCreate failed!\n");
  171.  
  172. return 0;
  173. }
  174.  
  175. // zarejestrowanie zdarzenia - początek obliczeń
  176. if (cudaEventRecord(start, 0) != cudaSuccess)
  177. {
  178. printf("cudaEventRecord failed!\n");
  179.  
  180. return 0;
  181. }
  182.  
  183. // wywołanie kodu jądra
  184. GetClosest <<< dimGrid, dimBlock >> >(X_gpu,Y_gpu,N);
  185.  
  186. // sprawdzenie czy udało się wywołać kod jądra
  187. if (cudaGetLastError() != cudaSuccess)
  188. {
  189. printf("kernel invocation failed!\n");
  190.  
  191. return 0;
  192. }
  193.  
  194. // zarejestrowanie zdarzenia - koniec obliczeń
  195. if (cudaEventRecord(stop, 0) != cudaSuccess)
  196. {
  197. printf("cudaEventRecord failed!\n");
  198.  
  199. return 0;
  200. }
  201.  
  202. // synchronizacja (oczekiwanie na zakończenie zdarzenia stop)
  203. if (cudaEventSynchronize(stop) != cudaSuccess)
  204. {
  205. printf("cudaEventSynchronize failed!\n");
  206.  
  207. return 0;
  208. }
  209.  
  210. // wyznaczenie czasu obliczeń
  211. float ms = 0;
  212. if (cudaEventElapsedTime(&ms, start, stop) != cudaSuccess)
  213. {
  214. printf("cudaEventElapsedTime failed!\n");
  215.  
  216. return 0;
  217. }
  218.  
  219. printf("running time on GPU: %20f [ms]\n", ms);
  220.  
  221. // przekopiowanie tablicy z pamięci karty
  222. if (cudaMemcpy(a_cpu, a_gpu, N * sizeof(int), cudaMemcpyDeviceToHost) != cudaSuccess)
  223. {
  224. printf("cudaMemcpy failed!\n");
  225.  
  226. return 0;
  227. }
  228.  
  229. // sprawdzenie poprawności zamiany
  230. for (int i = 0; i < N; i++)
  231. {
  232. if (a_cpu[i] != N - 1 - i)
  233. {
  234. printf("error!\n");
  235.  
  236. return 0;
  237. }
  238. }
  239.  
  240. int n2 = N / 2;
  241. int n1 = N - 1;
  242. int j;
  243.  
  244. DWORD dw1 = GetTickCount();
  245.  
  246. // zamiana elementów tablicy przez CPU
  247. for (int i = 0; i < n2; i++)
  248. {
  249. j = a_cpu[i];
  250. a_cpu[i] = a_cpu[n1 - i];
  251. a_cpu[n1 - i] = j;
  252. }
  253.  
  254. DWORD dw2 = GetTickCount();
  255.  
  256. printf("running time on CPU: %20u [ms]\n", dw2 - dw1);
  257.  
  258. // usunięcie zdarzeń
  259. if (cudaEventDestroy(start) != cudaSuccess)
  260. {
  261. printf("cudaEventDestroy failed!\n");
  262.  
  263. return 0;
  264. }
  265. if (cudaEventDestroy(stop) != cudaSuccess)
  266. {
  267. printf("cudaEventDestroy failed!\n");
  268.  
  269. return 0;
  270. }
  271.  
  272. // zwolnienie pamięci
  273. cudaFree(a_gpu);
  274. free(a_cpu);
  275.  
  276. // usunięcie kontekstu GPU
  277. cudaDeviceReset();
  278.  
  279. return 0;
  280. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement