Open EgorBo opened 1 year ago
Tagging subscribers to this area: @mangod9 See info in area-owners.md if you want to be subscribed.
Author: | EgorBo |
---|---|
Assignees: | - |
Labels: | `area-System.Threading` |
Milestone: | - |
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch See info in area-owners.md if you want to be subscribed.
Author: | EgorBo |
---|---|
Assignees: | - |
Labels: | `area-CodeGen-coreclr` |
Milestone: | - |
Prototype: https://github.com/EgorBo/runtime-1/commit/5b1fcb8713ae5b3b985845c85f58ffd5a337782c
[Benchmark]
public bool ThreadId1() => Thread.CurrentThread.ManagedThreadId == 42;
[Benchmark]
public bool ThreadId2() => Environment.CurrentManagedThreadId == 42;
Windows-x64, Ryzen 7950X:
| Method | Toolchain | Mean |
|---------- |---------------------------- |----------:|
| ThreadId1 | \Core_Root_base\corerun.exe | 0.7658 ns |
| ThreadId2 | \Core_Root_base\corerun.exe | 0.7457 ns |
| | | |
| ThreadId1 | \Core_Root_PR\corerun.exe | 0.3993 ns |
| ThreadId2 | \Core_Root_PR\corerun.exe | 0.3928 ns |
NativeAOT will likely regress so I didn't clean it for NAOT here and kept the current behavior.
Currently, both
Environment.CurrentManagedThreadId
andThread.CurrentThread.ManagedThreadId
(special cased in JIT) both emit a single helper call to get thread Id. These APIs seem to be perf-sensitive and since we now have TLS expansion we can easily optimize these by doing: 1) Disable JIT opt forThread.CurrentThread.ManagedThreadId
(where it recognizes two calls and folds them to a helper call) 2) MakeEnvironment.CurrentManagedThreadId
to simply returnThread.CurrentThread.ManagedThreadId
like it used to. 2) SurfaceThread.m_InternalThread
to managed land so then it will be a single mov operation.My quick experiments show 2x-3x perf improvements
Example:
Current codegen:
Expected codegen:
Concerns: Mono and NativeAOT.