This question is about the best strategy to choose a local_size in OpenGL's compute shader. The application is a Lattice Boltzmann Method (LBM) with a number of cells ranging from 100,000 to 1 million. This LBM will be run by end-users with a variety of different graphics cards and they will set the number of cells depending on the capability of their machine.
Although this LBM is 2d, the work to dispatch to the compute shader is, as far as I understand, one-dimensional since each cell can be processed independently.
As it is right now, I've set up the work in the following way.
In the compute shader:
#define LOCAL_GROUP_SIZE 64
layout (local_size_x = LOCAL_GROUP_SIZE, local_size_y = 1, local_size_z = 1) in;
And in the calling function
int nGroups = int(nCells/LOCAL_GROUP_SIZE);
nGroups++; // nGroups x LOCAL_GROUP_SIZE must be greater than the number of cells, otherwise the back ones won't be processed
// [...]
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_ssboCells.bufferId());
glDispatchCompute(nGroups, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
glFinish();
The questions I have in mind:
- How to choose the LOCAL_GROUP_SIZE to get good performance on average over a variety of GPUs? As far as I understand this size is required to be hard-coded in the CS and cannot be set at run time depending on the user's GPU.
- Is there any reason to use a 2 or 3 dimensional work group in this case?
- Not sure if the glMemoryBarrier is of any use given that each cell is processed independently.
Thanks in advance for any insight.