Consider emitting more performant codegen for looped switch statement, such as that found in a simple interpreter
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- csharp
- Domain
- compilers, performance
Research direction
Start by comparing label_array_interpreter.c and standard_interpreter.c in the linked ExampleInterpreterJumpTablesDifference repository, including its benchmark procedure. Then locate the .NET runtime JIT switch and loop code-generation paths; done means demonstrating the proposed optimized control flow without regressing other switch cases or size-focused modes.
Written by the indexing model from the issue text.
Description
Basically the request is that when having code like
while (true)
{
switch (instruction)
{
... handle cases - some end with break (majority), others with goto, others with return, etc.
}
}
instead of emitting assembly like (in generic format):
a:
branch <jump table>[value]
case 0:
...
goto a;
case 1:
...
goto a;
...
we would emit assembly like
a:
branch <jump table>[value]
case 0:
...
branch <jump table>[value] + (&a - &here);
case 1:
...
branch <jump table>[value] + (&a - &here);
...
GCC supports emitting assembly like this via labels as values, but that feature is far more generic than is needed to achieve the benefits of the above for 99% of cases, and runs into some issues I believe plus would be very difficult to add to IL anyway I suspect.
Here is an example of me implementing an interpreter in C with the exact same logic & code (outside of the goto & switch handling), but using the 2 different approaches. On my machines I measure about a 33% performance improvement on macOS x64 (~0.92s vs ~1.37s) and a 45% performance improvement on macOS arm64 (~0.85s vs ~1.55s). I tested with for i in $(seq 1 10) ; do time sudo standard_interpreter/label_array_interpreter 50000000 ; sleep 1 ; done (note: you have to run in the directory with instructions.txt).
Source code: https://github.com/hamarb123/ExampleInterpreterJumpTablesDifference (the difference is in https://github.com/hamarb123/ExampleInterpreterJumpTablesDifference/blob/main/label_array_interpreter.c vs https://github.com/hamarb123/ExampleInterpreterJumpTablesDifference/blob/main/standard_interpreter.c).
Due to such large potential performance benefits for some domains that rely heavily on this kind of thing (especially stuff like interpreters), I think it would be well worth implementing this in .NET. If additional code size is a concern, it could be saved for only optimised code & disabled on NAOT in optimise for size mode.
I would greatly appreciate this being considered as I plan to write an interpreter at some point (in C# ideally) with a structure along these lines, and it seems I could end up missing up to something like a third to a half of the potential performance I could have.
/cc @jakobbotsch who I was discussing this on the c# discord with.
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from dotnet/runtime
-
agentic-workflows untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
area-System.Reflection blocking-clean-ci-optional Known Build Error os-mac-os-x untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
area-CodeGen-coreclr untriaged
Difficulty 1/5 Under an hour Newbie friendliness 92/100
-
agentic-workflows untriaged
Difficulty 1/5 Under an hour Newbie friendliness 78/100
-
area-VM-meta-mono untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
:watch: Not Triaged 11.0 fundamentals/subsvc
Difficulty 2/5 1-3 hours Newbie friendliness 92/100
dotnet/AspNetCore.Docs#37699 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SubtitleEdit/subtitleedit#15108 · 1 comment ·
-
area/docs-content Bug pulumi/docs
Difficulty 1/5 1-3 hours Newbie friendliness 94/100
-
Create parent directories only after the containment check in InstallHelper.TryExtractToDirectory Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
PowerShell/PSResourceGet#2056 ·