The maximum allowed number of threads per compute shader group is 1024 for Shader Model 5.0. Is it advisable with regard to performance to stay close to this maximum number?

In order to resolve SSAA and MSAA (down-scaling with appropriate tone mapping), I wrote some compute shaders.

One general compute shader works in all cases and performs one task without synchronization for each output texel and uses [numthreads(16, 16, 1)] (= 256 threads/group which is a multiple of NVidia's warp size of 32 and AMD's wavefront size of 64). Algorithmically, this does not result in the best performance, since for MSAA $T$x, each task performs $T$ texture loads from the radiance, normal and depth textures, and for SSAA $T$x, each task performs $T \times T$ texture loads from the radiance, normal and depth textures.

So instead of dispatching jobs in terms of output texels, I have some specialized compute shaders performing tasks with synchronization for each input texel (for SSAA) or for each subsample of an input texel (for MSAA). Here, each task performs $1$ texture load from the radiance, normal and depth textures and stores the results in group shared memory. Next, a GroupMemoryBarrierWithGroupSync takes place and only one job per output texel continues to finish the work. This is not ideal in case of many SSAA and MSAA samples, but for few samples such as MSAA 2x, one expects to see some gains. In practice, however, the general compute shader outperforms all the specialized compute shaders for both small and large numbers of samples/ouput texel?

SSAA 2x [numthreads(4, 16, 16)] = 1024 (multiple of 64): ~655 FPS vs ~577 FPS

SSAA 3x [numthreads(9, 8, 8)] = 576 (multiple of 64): ~265 FPS vs ~200 FPS

SSAA 4x [numthreads(16, 8, 8)] = 1024 (multiple of 64): ~127 FPS vs ~75 FPS

Can this be solely due to dispatching more threads/group? Can this be due to the synchronization of all threads per group (close to the maximum allowed number of threads)? Or is there some performance one needs to sacrifice in case of using a 3D instead of 2D block of threads per group?

• FYI it's generally considered more useful to report timings in milliseconds rather than in FPS, especially when comparing deltas between different techniques. – Nathan Reed Nov 18 '17 at 0:06

• With regard to the idleness of threads: for MSAA $T$x, $T \times w \times h$ threads are used for retrieving data of which $w \times h$ threads perform the averaging and store the final results; for SSAA $T$x, $T \times T \times w \times h$ threads are used for retrieving data of which $w \times h$ threads perform the averaging and store the final results. Here, $w$ and $h$ represent the number of ouput texels for the width and height. – Matthias Nov 17 '17 at 17:14
• Agree with this answer. Using a thread per texture read isn't likely to get your data out of memory any faster than issuing $T$ texture reads per thread—in either case you're almost certainly going to be memory-bandwidth-bound. So by using all those extra threads you're just reducing your occupancy and taking longer to get through all the threads in the dispatch. – Nathan Reed Nov 18 '17 at 0:05