<p>I won't be discussing the usefulness of workgroups here as you can find it pretty much anywhere. However I am going to touch up on GPU architecture to understand why do we have workgroups in the first place. Most GPUs are designed in such a way that the concept of workgroup is useful. I won't go into details but give a brief overview as to how the mainstream GPUs are designed (AMD/NVIDIA).</p>

<p>So basically both AMD and NVIDIA have hundreds of thousands of cores inside them. AMD groups these cores into what is called compute unit (CU) While NVIDIA groups them to call them a streaming multiprocessor (SM). Here is a picture from AMD architecture as I am more used to it.</p>

<p><a href="https://i.sstatic.net/g3HeG.png" rel="noreferrer"><img src="https://i.sstatic.net/g3HeG.png" alt="enter image description here"></a> </p>

<p>As you can see GPU device consists of CU or SM in NVIDIA's case. These then further contain the actual processing elements. AMD has 64 of them for the GCN architecture.
Now you are gonna say "so what?" Why do we still have workgroups why don't we use these individual "processing elements" or "cores" by themselves and ditch the concept of workgroup.</p>

<p>Well the thing is, as Matias told above, the compute unit doesn't consist of only these cores, it has much more. The processing elements are just ALUs and they can't do anything on their own. The actual logic that tells them what to do such as the "Branch Unit" the "Instruction Decoding Logic", "Cache" etc are present inside the Compute Unit. Here is another picture for the Compute Unit of GCN Architecture.</p>

<p><a href="https://i.sstatic.net/AHVfr.png" rel="noreferrer"><img src="https://i.sstatic.net/AHVfr.png" alt="enter image description here"></a></p>

<p>So as you see this looks more like a miniature CPU processor with the instruction register and other stuff built in. Here comes the concept of workgroup. In programmer's terms a Workgroup equals or you can say gets assigned to a Compute Unit or thread block equals a Streaming Multiprocessor (in NVIDIA's terms). There are subtle differences such as hardware and software threads which leads to wavefronts and warps but I am not going to touch them here.</p>

<p>So this is somewhat the general architecture how work gets assigned to a GPU. Hence workgroups are necessary. The idea of shared memory and everything Matias said above stems from the underlying GPU architecture.</p>

<p>So when working with images we usually divide it into smaller 2D blocks called workgroups and hand these blocks to get processed by the underlying Compute Units/SMs.</p>

CC BY-SA 4.0
2018-10-21T07:20:53.663Z
2018-10-21T07:20:53.663Z
gallickgunner
<p>Work groups share resources. The most notable resources they share are barriers and LDS (Local Data Storage aka shared memory in GL lingo, aka Thread Group Shared Memory).</p>
<p>See <a href="https://archive.org/details/efficient-compute-shader-programming" rel="nofollow noreferrer">Efficient Compute Shader Programming</a> (<a href="https://dietchan.org/uploads/1596112564001.pdf" rel="nofollow noreferrer">PDF</a>) for an example where LDS/TGSM is used to accelerate a simple gaussian blur.</p>
<p>It is an interesting thought exercise of how a simple algorithm (weight average N values and output the result) can be rewritten to better leverage the hardware. Basically with a kernel radius of 5, Pixel A will load pixels [A; E] to average them, pixel B loads pixels [A; F] to average, pixel C loads pixels [A; G], and so on until we hit pixel F which will load pixels [B; J] to average them. So the paper asks the question: why do we load pixels A through F from main RAM so many times? (note: GPUs DO have caches, but if multiple threads are requesting all the same regions is likely many of these loads will miss the cache or have bank conflicts) and instead tries to load A through F ONCE (each thread loads only one pixel) and store it into TGSM memory which is much faster (and can also be accessed directly by the HW). It's basically very similar to manual cache management.</p>
<p>Also if the workgroup happens to be &lt;= than the GPU's native workgroup size, barriers are much cheaper.</p>
<p>Note not all GPUs are created equal. For example current Mali's GPU do not have LDS, and shared memory is &quot;emulated&quot; via RAM fetches, thus trying to use LDS like a cache is only going to hurt performance.</p>

CC BY-SA 4.0
2018-10-21T06:14:08.330Z
2024-04-25T18:54:35.963Z
2024-04-25T18:54:35.963Z
Matias N Goldberg
<p><a href="https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDispatchCompute.xhtml" rel="noreferrer">glDispatchCompute</a> has the number of work groups as arguments.</p>

<p>What is the point of having work groups? How are they useful, compared to just having NxM independent pixel calculations with a known (x,y) input parameter in the shader?</p>

<opengl><compute-shader>
What's the point of "work groups" for OpenGL compute shaders?
spraff
# What's the point of "work groups" for OpenGL compute shaders?

(Asked by: username_0 on 2018-10-20)

[glDispatchCompute](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDispatchCompute.xhtml) has the number of work groups as arguments.

What is the point of having work groups? How are they useful, compared to just having NxM independent pixel calculations with a known (x,y) input parameter in the shader?

**Tags:** opengl, compute-shader


---

## 2 answers

### Answer by username_1 on 2018-10-21. Score: 8

I won't be discussing the usefulness of workgroups here as you can find it pretty much anywhere. However I am going to touch up on GPU architecture to understand why do we have workgroups in the first place. Most GPUs are designed in such a way that the concept of workgroup is useful. I won't go into details but give a brief overview as to how the mainstream GPUs are designed (AMD/NVIDIA).

So basically both AMD and NVIDIA have hundreds of thousands of cores inside them. AMD groups these cores into what is called compute unit (CU) While NVIDIA groups them to call them a streaming multiprocessor (SM). Here is a picture from AMD architecture as I am more used to it.

[![enter image description here](https://i.sstatic.net/g3HeG.png)](https://i.sstatic.net/g3HeG.png)

As you can see GPU device consists of CU or SM in NVIDIA's case. These then further contain the actual processing elements. AMD has 64 of them for the GCN architecture.
Now you are gonna say "so what?" Why do we still have workgroups why don't we use these individual "processing elements" or "cores" by themselves and ditch the concept of workgroup.

Well the thing is, as username_2 told above, the compute unit doesn't consist of only these cores, it has much more. The processing elements are just ALUs and they can't do anything on their own. The actual logic that tells them what to do such as the "Branch Unit" the "Instruction Decoding Logic", "Cache" etc are present inside the Compute Unit. Here is another picture for the Compute Unit of GCN Architecture.

[![enter image description here](https://i.sstatic.net/AHVfr.png)](https://i.sstatic.net/AHVfr.png)

So as you see this looks more like a miniature CPU processor with the instruction register and other stuff built in. Here comes the concept of workgroup. In programmer's terms a Workgroup equals or you can say gets assigned to a Compute Unit or thread block equals a Streaming Multiprocessor (in NVIDIA's terms). There are subtle differences such as hardware and software threads which leads to wavefronts and warps but I am not going to touch them here.

So this is somewhat the general architecture how work gets assigned to a GPU. Hence workgroups are necessary. The idea of shared memory and everything username_2 said above stems from the underlying GPU architecture.

So when working with images we usually divide it into smaller 2D blocks called workgroups and hand these blocks to get processed by the underlying Compute Units/SMs.


---

### Answer by username_2 on 2018-10-21. Score: 5

Work groups share resources. The most notable resources they share are barriers and LDS (Local Data Storage aka shared memory in GL lingo, aka Thread Group Shared Memory).

See [Efficient Compute Shader Programming](https://archive.org/details/efficient-compute-shader-programming) ([PDF](https://dietchan.org/uploads/1596112564001.pdf)) for an example where LDS/TGSM is used to accelerate a simple gaussian blur.

It is an interesting thought exercise of how a simple algorithm (weight average N values and output the result) can be rewritten to better leverage the hardware. Basically with a kernel radius of 5, Pixel A will load pixels [A; E] to average them, pixel B loads pixels [A; F] to average, pixel C loads pixels [A; G], and so on until we hit pixel F which will load pixels [B; J] to average them. So the paper asks the question: why do we load pixels A through F from main RAM so many times? (note: GPUs DO have caches, but if multiple threads are requesting all the same regions is likely many of these loads will miss the cache or have bank conflicts) and instead tries to load A through F ONCE (each thread loads only one pixel) and store it into TGSM memory which is much faster (and can also be accessed directly by the HW). It's basically very similar to manual cache management.

Also if the workgroup happens to be <= than the GPU's native workgroup size, barriers are much cheaper.

Note not all GPUs are created equal. For example current Mali's GPU do not have LDS, and shared memory is "emulated" via RAM fetches, thus trying to use LDS like a cache is only going to hurt performance.


---

