Advertisement
Guest User

Untitled

a guest
Jan 20th, 2018
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.72 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.  
  9. // liczba wątków
  10. const int N_THR = 512;
  11.  
  12. // rozmiar tablicy
  13. const int N = (1 << 23);
  14.  
  15. //////////////////////////////////////////////////////////////////
  16. // kod jądra - odwraca kolejność elementów w tablicy
  17. __global__ void reverseArray(int *d_in)
  18. {
  19. // fragmenty tablicy w pamięci współdzielonej
  20. __shared__ int s_data1[N_THR];
  21. __shared__ int s_data2[N_THR];
  22.  
  23. // indeksy elementów tablicy
  24. int in1 = blockDim.x * blockIdx.x + threadIdx.x;
  25. int in2 = N - blockDim.x * (blockIdx.x + 1) + threadIdx.x;
  26.  
  27. // indeks w tablicy w pamięci współdzielonej
  28. int out = blockDim.x - 1 - threadIdx.x;
  29.  
  30. // zapisanie elementów tablicy w pamięci współdzielonej
  31. s_data1[out] = d_in[in1];
  32. s_data2[out] = d_in[in2];
  33.  
  34. // synchronizacja wątków w bloku
  35. __syncthreads();
  36.  
  37. // zamiana elementów - przepisanie z pamięci współdzielonej
  38. // do pamięci globalnej
  39. d_in[in1] = s_data2[threadIdx.x];
  40. d_in[in2] = s_data1[threadIdx.x];
  41. }
  42.  
  43. //////////////////////////////////////////////////////////////////
  44. int main(int argc, char* argv[])
  45. {
  46. // wybór karty na której zostana wykonane obliczenia
  47. if (cudaSetDevice(0) != cudaSuccess)
  48. {
  49. printf("cudaSetDevice failed! Do you have a CUDA-capable GPU installed?");
  50.  
  51. return 0;
  52. }
  53.  
  54. // utworzenie tablicy
  55. int *a_cpu = (int*)malloc(N * sizeof(int));
  56. if (!a_cpu)
  57. {
  58. printf("malloc failed!\n");
  59.  
  60. return 0;
  61. }
  62. for (int i = 0; i < N; ++i)
  63. a_cpu[i] = i;
  64.  
  65. // przydzielenie pamięci na karcie
  66. int *a_gpu;
  67. if (cudaMalloc((void**)&a_gpu, N * sizeof(int)) != cudaSuccess)
  68. {
  69. printf("cudaMalloc failed!\n");
  70.  
  71. return 0;
  72. }
  73.  
  74. // przekopiowanie tablicy do pamięci karty
  75. if (cudaMemcpy(a_gpu, a_cpu, N * sizeof(int), cudaMemcpyHostToDevice) != cudaSuccess)
  76. {
  77. printf("cudaMemcpy failed!\n");
  78.  
  79. return 0;
  80. }
  81.  
  82. // rozmiar bloku i siatki bloków
  83. dim3 dimBlock(N_THR);
  84. dim3 dimGrid((N / 2) / N_THR);
  85.  
  86. printf("N: %d, dimBlock: %d, dimGrid: %d\n\n", N, dimBlock.x, dimGrid.x);
  87.  
  88. // utworzenie zdarzeń do pomiaru czasu obliczeń
  89. cudaEvent_t start, stop;
  90. if (cudaEventCreate(&start) != cudaSuccess)
  91. {
  92. printf("cudaEventCreate failed!\n");
  93.  
  94. return 0;
  95. }
  96. if (cudaEventCreate(&stop) != cudaSuccess)
  97. {
  98. printf("cudaEventCreate failed!\n");
  99.  
  100. return 0;
  101. }
  102.  
  103. // zarejestrowanie zdarzenia - początek obliczeń
  104. if (cudaEventRecord(start, 0) != cudaSuccess)
  105. {
  106. printf("cudaEventRecord failed!\n");
  107.  
  108. return 0;
  109. }
  110.  
  111. // wywołanie kodu jądra
  112. reverseArray<<< dimGrid, dimBlock >>>(a_gpu);
  113.  
  114. // sprawdzenie czy udało się wywołać kod jądra
  115. if (cudaGetLastError() != cudaSuccess)
  116. {
  117. printf("kernel invocation failed!\n");
  118.  
  119. return 0;
  120. }
  121.  
  122. // zarejestrowanie zdarzenia - koniec obliczeń
  123. if (cudaEventRecord(stop, 0) != cudaSuccess)
  124. {
  125. printf("cudaEventRecord failed!\n");
  126.  
  127. return 0;
  128. }
  129.  
  130. // synchronizacja (oczekiwanie na zakończenie zdarzenia stop)
  131. if (cudaEventSynchronize(stop) != cudaSuccess)
  132. {
  133. printf("cudaEventSynchronize failed!\n");
  134.  
  135. return 0;
  136. }
  137.  
  138. // wyznaczenie czasu obliczeń
  139. float ms = 0;
  140. if (cudaEventElapsedTime(&ms, start, stop) != cudaSuccess)
  141. {
  142. printf("cudaEventElapsedTime failed!\n");
  143.  
  144. return 0;
  145. }
  146.  
  147. printf("running time on GPU: %20f [ms]\n", ms);
  148.  
  149. // przekopiowanie tablicy z pamięci karty
  150. if (cudaMemcpy(a_cpu, a_gpu, N * sizeof(int), cudaMemcpyDeviceToHost) != cudaSuccess)
  151. {
  152. printf("cudaMemcpy failed!\n");
  153.  
  154. return 0;
  155. }
  156.  
  157. // sprawdzenie poprawności zamiany
  158. for (int i = 0; i < N; i++)
  159. {
  160. if (a_cpu[i] != N - 1 - i)
  161. {
  162. printf("error!\n");
  163.  
  164. return 0;
  165. }
  166. }
  167.  
  168. int n2 = N / 2;
  169. int n1 = N - 1;
  170. int j;
  171.  
  172. DWORD dw1 = GetTickCount();
  173.  
  174. // zamiana elementów tablicy przez CPU
  175. for (int i = 0; i < n2; i++)
  176. {
  177. j = a_cpu[i];
  178. a_cpu[i] = a_cpu[n1 - i];
  179. a_cpu[n1 - i] = j;
  180. }
  181.  
  182. DWORD dw2 = GetTickCount();
  183.  
  184. printf("running time on CPU: %20u [ms]\n", dw2-dw1);
  185.  
  186. // usunięcie zdarzeń
  187. if (cudaEventDestroy(start) != cudaSuccess)
  188. {
  189. printf("cudaEventDestroy failed!\n");
  190.  
  191. return 0;
  192. }
  193. if (cudaEventDestroy(stop) != cudaSuccess)
  194. {
  195. printf("cudaEventDestroy failed!\n");
  196.  
  197. return 0;
  198. }
  199.  
  200. // zwolnienie pamięci
  201. cudaFree(a_gpu);
  202. free(a_cpu);
  203.  
  204. // usunięcie kontekstu GPU
  205. cudaDeviceReset();
  206.  
  207. return 0;
  208. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement