<p>The best place to put a look up table for a GPU compute shader depends on the size of the lookup table, and the frequency/coherency of access. In your case (you mentioned 4kb), shared local memory would likely be best (assuming you do not need this memory for other purposes in the same kernel). This memory has different names in different APIs, but is the same architectural thing and follows the same performance guidelines:</p>

<ul>
<li>CUDA: threadgroup shared memory</li>
<li>DirectCompute: groupshared memory</li>
<li>OpenCL: local memory</li>
<li>Metal: threadgroup memory</li>
<li>OpenGL: shared memory</li>
</ul>

<p>Storing the lookup table in global memory as a read-only buffer may perform just as well, depending on the cache size(s) of the particular GPU you're running on.</p>

<p>Note that I'm presuming this is a read-only lookup table. A read-write lookup table is a completely different beast, and you don't have any good options there.</p>

CC BY-SA 3.0
2016-05-20T06:17:13.907Z
There are also cases where a read-only buffer will do better than storing 4kb of read-only data in shared local memory. For example, storing it in local memory may mean that there is a unique copy of your data for every thread group. If the buffer fits in cache, it's quite possible that the cache performs better than local memory for read-only access patterns.
John Calsbeek
CC BY-SA 3.0
2016-05-30T08:01:59.140Z
Thanks for the feedback guys. I've finished the project I was using this for now, and wound up just using a r8ui readonly buffer texture, which worked pretty nicely :)
russ
CC BY-SA 3.0
2016-05-19T22:40:47.670Z
2016-05-19T22:40:47.670Z
GroverManheim
<p>I'm exploring isosurface algorithms on GPU for a bachelor's project (specifically concentrating on just binary in/out voxel data rather than real-valued fields). So I have a CPU implementation of good old marching cubes up and running in OpenFrameworks, and now at the stage of trying to port it to GLSL compute shaders, and considering the pitfalls before I dive in. I've only written vert and frag shaders before so it's all new to me.</p>

<p>My first issue is how to efficiently use a lookup table across dozens or hundreds of threads in a workgroup? I understand a GPU has different kinds of memory for different tasks but not fully sure on how each operates or which type to use.</p>

<p>Paul Bourke's classic copypasta table is a 256*16 array so if using a scalar byte type this can presumably be packed into a 4kb texture or SSBO.</p>

<p>The question is, how to stop the different threads from tripping each other up? Many cubes in each work group can potentially have the same configuration therefore trying to access the same location in the buffer at the same time. Is there a workaround or optimization to deal with this?</p>

CC BY-SA 3.0
2015-10-27T17:33:49.673Z
If it's a read-only lookup table, you can just use a buffer/texture. You could either pack it into one of the normal texture formats, or you can use some of the newer features of DX11 / OpenGL to have a custom format. UAV in DX11 land, or a texture / shader_image_load_store in OpenGL land.
RichieSams
CC BY-SA 3.0
2015-10-27T17:41:58.977Z
In addition, give this presentation a look: https://www.cvg.ethz.ch/teaching/2011spring/gpgpu/cuda_memory.pdf It's for CUDA, but it should give you a better idea of what is happening on the underlying hardware
RichieSams
CC BY-SA 3.0
2016-02-28T04:51:46.943Z
Not a full answer but the smaller amount of memory you use the better, as it will be more likely to fit in caches and have fewer cache misses.  If you have interpolatable values, like you are baking out points on a curve into textures, you might check this out as a way to get higher quality curve lookup tables with less memory: http://blog.demofox.org/2016/02/22/gpu-texture-sampler-bezier-curve-evaluation/
Alan Wolfe
<opengl><algorithm><gpgpu><mesh>
Optimal memory access when using lookup tables on GPU?
russ
# Optimal memory access when using lookup tables on GPU?

(Asked by: username_0 on 2015-10-27)

I'm exploring isosurface algorithms on GPU for a bachelor's project (specifically concentrating on just binary in/out voxel data rather than real-valued fields). So I have a CPU implementation of good old marching cubes up and running in OpenFrameworks, and now at the stage of trying to port it to GLSL compute shaders, and considering the pitfalls before I dive in. I've only written vert and frag shaders before so it's all new to me.

My first issue is how to efficiently use a lookup table across dozens or hundreds of threads in a workgroup? I understand a GPU has different kinds of memory for different tasks but not fully sure on how each operates or which type to use.

Paul Bourke's classic copypasta table is a 256\*16 array so if using a scalar byte type this can presumably be packed into a 4kb texture or SSBO.

The question is, how to stop the different threads from tripping each other up? Many cubes in each work group can potentially have the same configuration therefore trying to access the same location in the buffer at the same time. Is there a workaround or optimization to deal with this?

**Tags:** opengl, algorithm, gpgpu, mesh

> **Comments:**
> **username_1**: If it's a read-only lookup table, you can just use a buffer/texture. You could either pack it into one of the normal texture formats, or you can use some of the newer features of DX11 / OpenGL to have a custom format. UAV in DX11 land, or a texture / shader_image_load_store in OpenGL land.  
> **username_1**: In addition, give this presentation a look: https://www.cvg.ethz.ch/teaching/2011spring/gpgpu/cuda_memory.pdf It's for CUDA, but it should give you a better idea of what is happening on the underlying hardware  
> **username_2**: Not a full answer but the smaller amount of memory you use the better, as it will be more likely to fit in caches and have fewer cache misses.  If you have interpolatable values, like you are baking out points on a curve into textures, you might check this out as a way to get higher quality curve lookup tables with less memory: http://blog.demofox.org/2016/02/22/gpu-texture-sampler-bezier-curve-evaluation/  

---

## 1 answers

### Answer by username_3 on 2016-05-19. Score: 6 | Accepted answer

The best place to put a look up table for a GPU compute shader depends on the size of the lookup table, and the frequency/coherency of access. In your case (you mentioned 4kb), shared local memory would likely be best (assuming you do not need this memory for other purposes in the same kernel). This memory has different names in different APIs, but is the same architectural thing and follows the same performance guidelines:

* CUDA: threadgroup shared memory
* DirectCompute: groupshared memory
* OpenCL: local memory
* Metal: threadgroup memory
* OpenGL: shared memory

Storing the lookup table in global memory as a read-only buffer may perform just as well, depending on the cache size(s) of the particular GPU you're running on.

Note that I'm presuming this is a read-only lookup table. A read-write lookup table is a completely different beast, and you don't have any good options there.

> **Comments:**
> **username_4**: There are also cases where a read-only buffer will do better than storing 4kb of read-only data in shared local memory. For example, storing it in local memory may mean that there is a unique copy of your data for every thread group. If the buffer fits in cache, it's quite possible that the cache performs better than local memory for read-only access patterns.  
> **username_0**: Thanks for the feedback guys. I've finished the project I was using this for now, and wound up just using a r8ui readonly buffer texture, which worked pretty nicely :)  

---

