1
$\begingroup$

When using compute shaders, some workgroups can be faster than others, for example when all invocations within one group go into the 'if' case, where on another workgroup the invocations go into the 'if' and the 'else' case. My question: are the workgroups be released which have finished their work while others are still working? And can these warps be used at that time for other shaders? Or are they blocked till all workgroups within that dispatch compute call are finished? Is that hardware specific or driver specific?

$\endgroup$
1
  • $\begingroup$ It's not a bad question, but think about it for a moment. If a workgroup would block resources for the entirety of the dispatch, you could only ever have as many workgroups/threads as your hardware has dedicated processing units (or at least scheduling space for managing workgroups), which, while quite a lot in modern hardware, are usually a multitude less than common workloads. $\endgroup$ May 12, 2023 at 15:08

1 Answer 1

0
$\begingroup$

Yes resources will be availiable for the next command from the command queue, be it compute or other type of shader, even when the previous dispatch operations have not finished.

For this reason, if subsequent shaders rely on output of a previous shader, these need to have barriers in place or wait until the command queue is empty and and the operations are finished (glFinish).

e.g.

glUseProgram(computeShader1);      
glDispatchCompute(...)

glUseProgram(computeShader2);      
glDispatchCompute(...)

// Even at this point, shader1 could still have workgroups being processed... shader2 will either be in the command queue or currently being have workgroups being processed...

To use glFinish()...

glUseProgram(computeShader1);      
glDispatchCompute(...)

glFinish();     // Program will wait here until all GL operations in command queue are finished (queue will be empty)...

// At this point, all of shader1's workgroups have finished...

glUseProgram(computeShader2);     
glDispatchCompute(...)

You could use glFlush if you wish to process the commands without stalling the program, however this will not guarantee that subsequent commands are not being processed prematurely to what you think (since program is not stalled, it only empties the command queue telling GL to process what was in the queue and empty the queue).

It's important to note the difference between glFlush and glFinish.

glFlush tells GL to process all the commands that have been queued up to that point and clears the queue upto that point. Main program thread is not halted, and can carry on filling up (a now empty) command queue (while GL processes the 'flushed' operations).

glFinish tells GL to process all the commands that have been queued (like flush), but stalls the calling thread until GL is finished processing (which, in the example code, will prevent the second dispatch call until GL is finished processing its queue of commands, i.e no overlapping operations). When program continues, the queue will be empty and operations will have been processed.

As mentioned above, for compute shaders this is especially important if the input of shader2 relies on the output of shader1.

$\endgroup$
2
  • 1
    $\begingroup$ Very nice explanation! Many thanks! $\endgroup$
    – Thomas
    May 4, 2023 at 9:49
  • 1
    $\begingroup$ Please, please don't use glFinish for synchronization (even glFlush is hardly ever necessary for anything). While the explanations are correct, this is really bad advice as it entirely defeats the purpose of CPU and GPU working asynchronously. There are various other means for fine-grained synchronization, you even mentioned barriers yourself. And even then, first check if that is even necessary as many operations in the GL have implicit synchronization anyway. Unfortnately, this advice really taints the entire answer. $\endgroup$ May 12, 2023 at 15:04

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.