proffreda

Cuda Sum-Reduce in Shared Memory

Sep 19th, 2016
374
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.40 KB | None | 0 0
  1. #include "../common/book.h"
  2. #define N (1024*2048)
  3. #define NumSMPs 14 #Machine dependent
  4. #define ThreadsPerBlock 1024
  5. #define BlocksPerGrid N/ThreadsPerBlock
  6.  
  7.  
  8.  
  9. __global__ void add_reduce( float *a, float *b, float *c ) {
  10. // Shared memory for results of multiplication
  11.  
  12. __shared__ float cache[ThreadsPerBlock];
  13. int gindex = threadIdx.x + blockIdx.x * ThreadsPerBlock;
  14. int lindex = threadIdx.x;
  15. cache[lindex] = a[gindex]*b[gindex];
  16.  
  17. int offset = ThreadsPerBlock/2;
  18. while (offset != 0) {
  19. if (lindex < offset){
  20. cache[lindex] += cache[lindex + offset];}
  21. __syncthreads();
  22. offset /= 2; }
  23. if (lindex == 0)
  24. c[blockIdx.x] = cache[0];
  25. }
  26.  
  27.  
  28. int main( void ) {
  29. float *a, *b, *c;
  30. float *dev_a, *dev_b, *dev_c;
  31.  
  32. // allocate the memory on the CPU
  33. a = (float*)malloc( N * sizeof(float) );
  34. b = (float*)malloc( N * sizeof(float) );
  35. c = (float*)malloc(BlocksPerGrid * sizeof(float) );
  36.  
  37. // allocate the memory on the GPU
  38. HANDLE_ERROR( cudaMalloc( (void**)&dev_a, N * sizeof(float) ) );
  39. HANDLE_ERROR( cudaMalloc( (void**)&dev_b, N * sizeof(float) ) );
  40. HANDLE_ERROR( cudaMalloc( (void**)&dev_c, BlocksPerGrid * sizeof(float) ) );
  41.  
  42. // fill the arrays 'a' and 'b' on the CPU
  43. for (int i=0; i<N; i++) {
  44. a[i] = 1.0/(i+1);
  45. b[i] = 2.0/(i+1);
  46. }
  47.  
  48. // copy the arrays 'a' and 'b' to the GPU
  49. HANDLE_ERROR( cudaMemcpy( dev_a, a, N * sizeof(float),
  50. cudaMemcpyHostToDevice ) );
  51. HANDLE_ERROR( cudaMemcpy( dev_b, b, N * sizeof(float),
  52. cudaMemcpyHostToDevice ) );
  53.  
  54. add_reduce<<<BlocksPerGrid,ThreadsPerBlock>>>( dev_a, dev_b, dev_c );
  55.  
  56. // copy the array 'c' back from the GPU to the CPU
  57. HANDLE_ERROR( cudaMemcpy( c, dev_c, BlocksPerGrid * sizeof(float),
  58. cudaMemcpyDeviceToHost ) );
  59.  
  60. // verify that the GPU did the work we requested
  61.  
  62. printf("\nResults of GPU\n");
  63. float sum = 0.0;
  64. for (int i=0 ; i < BlocksPerGrid; ++i) {
  65. sum += c[i];}
  66. printf("Sum of %d Block results: %f\n", BlocksPerGrid, sum);
  67.  
  68.  
  69. // free the memory we allocated on the GPU
  70. HANDLE_ERROR( cudaFree( dev_a ) );
  71. HANDLE_ERROR( cudaFree( dev_b ) );
  72. HANDLE_ERROR( cudaFree( dev_c ) );
  73.  
  74. // free the memory we allocated on the CPU
  75. free( a );
  76. free( b );
  77. free( c );
  78.  
  79. return 0;
  80. }
Advertisement
Add Comment
Please, Sign In to add comment