another note

This commit is contained in:
profan 2026-06-07 19:05:20 +01:00
parent ceafacce76
commit 6b0d3b97ba
1 changed files with 2 additions and 1 deletions

View File

@ -23,7 +23,6 @@ void EvaluateLoop()
## RyuJIT Implementation Details ## RyuJIT Implementation Details
When the C# JIT observes a pattern like this: When the C# JIT observes a pattern like this:
```cs ```cs
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T Add<T>(T a, T b) public static T Add<T>(T a, T b)
where T : unmanaged where T : unmanaged
@ -45,6 +44,8 @@ public static T Add<T>(T a, T b)
... which to the normal C# eye would seem like you'd end up with a runtime branch every time this runs right? ... which to the normal C# eye would seem like you'd end up with a runtime branch every time this runs right?
However because C# JIT implementations (RyuJIT included) monomorphizes generics when T is a value type, we end up with different versions of this function, and whenever it compiles one of these functions where it branches over types and typeof(T) along with branching over types is a specific pattern the JIT recognises, we actually end up with a function without any branches after the JIT has compiled the function for us. Fun! However because C# JIT implementations (RyuJIT included) monomorphizes generics when T is a value type, we end up with different versions of this function, and whenever it compiles one of these functions where it branches over types and typeof(T) along with branching over types is a specific pattern the JIT recognises, we actually end up with a function without any branches after the JIT has compiled the function for us. Fun!
... Good for us, because I abused this pattern a lot in this program in order to make it easy to toggle on/off vectorization!
# The Program # The Program
![The Application, in its 1024x1024 window](sharpero.png) ![The Application, in its 1024x1024 window](sharpero.png)