<p>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.</p>
<p>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).</p>
<p>e.g.</p>
<pre><code>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...
</code></pre>
<p>To use glFinish()...</p>
<pre><code>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(...)
</code></pre>
<p>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).</p>
<p>It's important to note the difference between <a href="https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/glFlush.xml" rel="nofollow noreferrer">glFlush</a> and <a href="https://registry.khronos.org/OpenGL-Refpages/gl4/html/glFinish.xhtml" rel="nofollow noreferrer">glFinish</a>.</p>
<p>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).</p>
<p>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.</p>
<p>As mentioned above, for compute shaders this is especially important if the input of shader2 relies on the output of shader1.</p>

CC BY-SA 4.0
2023-05-04T09:49:22.443Z
Very nice explanation! Many thanks!
Thomas
CC BY-SA 4.0
2023-05-12T15:04:58.573Z
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.
Christian Rau
CC BY-SA 4.0
2023-05-04T09:39:36.837Z
2023-05-04T09:46:01.037Z
2023-05-04T09:46:01.037Z
lfgtm
<p>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?</p>

CC BY-SA 4.0
2023-05-12T15:08:52.990Z
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.
Christian Rau
<compute-shader>
Partial Workgroup release of compute shaders?
Thomas
# Partial Workgroup release of compute shaders?

(Asked by: username_0 on 2023-04-29)

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?

**Tags:** compute-shader

> **Comments:**
> **username_1**: 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.  

---

## 1 answers

### Answer by username_2 on 2023-05-04. Score: 0 | Accepted answer

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](https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/glFlush.xml) and [glFinish](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glFinish.xhtml).

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.

> **Comments:**
> **username_0**: Very nice explanation! Many thanks!  
> **username_1**: 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.  

---

