Shared memory spilling and better inlining policies - #1096
Open
Qubitol wants to merge 6 commits into
Open
Conversation
Inject the `enable_smem_spilling` PTX pragma at the start of the calculate_wavefunctions in the code generator. The kernel is then able to spill registers to shared memory rather than global memory.
Even when compiled with CUDA < 13, it would just silently ignore the pragma, while when compiling for HIP, it would fail to compile if not guarded.
Modify flags to force inlining/not-inlining of helicity amplitudes functions. Add two mutually exclusive flags to control this behaviour.
Member
|
LGTM, I just looked at the merge conflict, should be as easy as removing the ALWAYS_INLINE as the attribute can be put in one place no matter if its CPU or GPU compilation. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR implements two things:
HELINL=-1: prevent inliningHELINL=0(default): compiler defaultHELINL=1: forced inliningPerformance comparison
Regarding performance comparison before/after, I tested the 3 processes:
g g > t t~ gg g > t t~ g gg g > t t~ g g gin standalone mode, measuring
check_sathroughput, and register spilling, fixing 256 threads per block, and by varying number of blocks.I analysed all the possible combinations across inlining policy and shared memory spilling dimensions, testing both CUDA and AVX2 backends (for CPU backend of course shared memory spilling is not a thing).
Benchmark throughput across work size
Throughput change due to inlining (heatmap)
Throughput change due to shared memory spilling enabled (heatmap)
Register pressure and spill destination
Most kernels use the architectural maximum of 255 registers/thread.$+1g$ at 130 and no-inline $+2g$ at 242; no-inline $+3g$ remains at 255.
The exceptions are no-inline
When shared spilling is active, the compiler reserves 19,456 bytes/block.$+1g$ and $+2g$ , where there are no compiler-reported spill loads/stores to redirect.
It allocates nothing for no-inline
Conclusions
Compiler-default is best for `g g > t t~ g g g$, no-inline is strong for
The effect on end-to-end benchmark throughput is usually modest.
What's next?
If we decide to merge only one single feature, I would create a separate branch and PR, while closing this.