So, the first idea was to implement shared memory into the smooth shader, and I did so. That brought down the average run time of the pressure solve shader from 15.4 ms to 13.87ms. Only 1.5 ms improvement.. why? Well, there was a halo of cells that had to be still fetched from global memory. So I thought to load those too to shared memory, but that introduced a ton of branching, which brought the average runtime to 29.7 ms… immediatelly reverted the change. At this point, unhappy with only 1.5 ms of change I didn’t stop here: fixing barrier bits brought down 13.87ms to 13.74ms, and changing the pressure and residual images from r32f to r16f (as that much precision is anyways not needed) brought it further down to 13.62ms. The biggest improvement was batching the gauss seidel calls: that allowed the GPU to better use the cached values and avoid CPU overhead. This brought the execution down to 8.93ms! This initial optimization sped up the pressure solve shader of a whooping 42%! And there is still the compute residual, prolong pressure, restrict residual and restrict solid shaders which too affect the pressure solve runtime!
TLDR:
- Initial runtime (avg) - 15.4ms
- Shared memory - 13.87ms (-1.53)
- Barrier bit fix - 13.742ms (-1.66)
- r32f to r16f - 13.62ms (-1.78)
- Batching smooth calls - 8.93ms (-6.47)