3

In a CUDA kernel, I have code similar to the following. I am trying to calculate one numerator per thread, and accumulate the numerators over the block to calculate a denominator, and then return the ratio. However, CUDA is setting the value of denom to whatever value is calculated for numer by the thread in the block with the largest threadIdx.x, rather than the sum of the numer value calculated across all the threads in the block. Does anyone know what is going on?

extern __shared__ float s_shared[];

float numer = //calculate numerator

s_shared[threadIdx.x] = numer;
s_shared[blockDim.x] += numer;
__syncthreads();

float denom = s_shared[blockDim.x];
float result = numer/denom;

result should always be between 0 and 1 and should sum to 1 across the block, but instead it is equal to 1.0 for every thread where threadIdx.x is the maximum, and some other value not confined to the range for the other threads in the block.

1 Answer 1

4

You're not synchronizing the summing properly to the blockDim.x location. None of the threads are waiting to see what others have written before adding their sum. Sort of like

  1. Everyone reads zero,
  2. goes home, calculates zero + numer.
  3. Everyone writes zero+numer to the memory location

The high threadId wins b/c it has a high likelihood of acting last, I suppose.

What you want to do instead, in order to do a quick sum, is to do a binary sum on s_shared[threadIdx.x]

  1. everyone writes their numer
  2. half the threads calculate sums of pairs and write those to a new location
  3. a quarter of the threads calculate the sums of pairs of pairs, and write those to a new location
  4. etc
  5. until you just have one thread and one sum

This takes O(n) work and O(log n) time.

Sign up to request clarification or add additional context in comments.

2 Comments

Just to make a note of this, the logic here is known as a reduction. There are a few samples of this in the cuda sdk. See: cuda-sdk/C/src/reduction/reduction_kernel.cu
The sample can be found here now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.