What follows is the part of my kernel that does not behave properly, then an explanation of what I've found while debugging.
__global__ void Mangler(float *matrix, int *map)
{
__shared__ signed int localMap[N];
if(0 == threadIdx.x)
{
for(int i=0; i<N; i++)
localMap[i] = -1;
}
__syncthreads();
int fn = ...; // a lot of code goes into this number, skipped for clarity
int rnumber = threadIdx.x;
int X = atomicCAS(&localMap[fn], -1, rnumber); // Spot of bother 1
if(X == -1) // Spot of bother 2
{
// some code
}
else
{
// other code
}
}
I've found in the documentation that atomicCAS(*address, compare, value) basically returns (and saves to the given address) the result of (old == compare ? value : old), where old is the value at the address before executing the function.
Going with this, I believe that executing int X = atomicCAS(&localMap[fn], -1, rnumber); should have two possible outcomes (according to NVidia Cuda C Programming Guide):
- if
localMap[fn] == -1thenXshould have a value ofrnumberandlocalMap[fn]should have a value ofrnumber. This does not happen. - if
localMap[fn] != -1thenXshould be set to the value oflocalMap[fn]and said value should be left intact.
What happens instead, as debugging with NSight has shown me, is that X is being assigned -1, while localMap[fn] is being assigned the value of rnumber. I do not understand that, but as you can see in my code, I've changed the if to catch this situation.
Which brings me to spot of bother number 2: though NSight shows the value of X as -1, the if {} is being completely skipped (no breakpoints within hit whatsoever) and execution jumps straight to else.
My questions:
Do I misunderstandyes, I didatomicCAScompletely?- What could cause and
ifwhich should evaluate as true to jump straight intoelsein device code?
I'm using NVidia CUDA 5.5, Visual Studio 2012 x64 on Windows 8, NVidia Nsight Monitor Visual Studio Edition 3.1. The GPU for the machine is NVidia GeForce GTX 550 Ti.
I've tried changing the syntax to if(X!=-1); the true branch of the if is still not being executed.
else), and it results in a memory access violation, which is consistent with a -1 slipping in there. - Pawel J. Walprintfstatements in yourifandelsepaths. Are you compiling this code with the-Gswitch? Also, ifXevaluates differently for different threads within a warp, things may be confusing depending on which thread you have in focus, or which version of X you are inspecting. - Robert Crovellaifconditional, theelsepart is executed first. - Roger Dahl