non-preemptive block scheduling

Hi all!

I know the problem of inter-block synchronization has been discussed many times
and NVIDIA does not encourage people doing this, but let me give it another try ;)

Suppose, if one wants to pass some data from one block to another.
The data consistency can be ensured with threadfence() and subsequent syncthreads(), no problem here,
but the question is how to signal other blocks that the data has actually arrived.

If I understand it correctly, a block actively waiting on mutex can cause a deadlock
because the scheduling mechanism is non-preemptive.

That is, if two thread blocks appear to be mapped to a single SM, then
one of them might never get the chance to execute, and hence the mutex can never be unlocked.

So, my question is: is there any way to enforce the scheduler to choose another block to execute ?
for instance, by issuing a ``dummy’’ global memory read from the first block:
that is, instead of:

if(thid == 0) {
while(*mutex != GoalVal) { ; }
}

we do the following:

while(1) {

if(thid == 0) {
if(*mutex == GoalVal)
// singal other blocks that data arrived…
}

a = g_in[thid]; // read whatever data from global memory

}

Though, I am not sure if this really works, any help greatly appreciated !

Hi all!

I know the problem of inter-block synchronization has been discussed many times
and NVIDIA does not encourage people doing this, but let me give it another try ;)

Suppose, if one wants to pass some data from one block to another.
The data consistency can be ensured with threadfence() and subsequent syncthreads(), no problem here,
but the question is how to signal other blocks that the data has actually arrived.

If I understand it correctly, a block actively waiting on mutex can cause a deadlock
because the scheduling mechanism is non-preemptive.

That is, if two thread blocks appear to be mapped to a single SM, then
one of them might never get the chance to execute, and hence the mutex can never be unlocked.

So, my question is: is there any way to enforce the scheduler to choose another block to execute ?
for instance, by issuing a ``dummy’’ global memory read from the first block:
that is, instead of:

if(thid == 0) {
while(*mutex != GoalVal) { ; }
}

we do the following:

while(1) {

if(thid == 0) {
if(*mutex == GoalVal)
// singal other blocks that data arrived…
}

a = g_in[thid]; // read whatever data from global memory

}

Though, I am not sure if this really works, any help greatly appreciated !

No, but you can make the same block execute a different task. Since the only difference between blocks is [font=“Courier New”]blockIdx[/font], just use you own variable for that and allocate work for blocks yourself (atomic operations come handy for that).

No, but you can make the same block execute a different task. Since the only difference between blocks is [font=“Courier New”]blockIdx[/font], just use you own variable for that and allocate work for blocks yourself (atomic operations come handy for that).