Description
Update:
We've now completed the initial experiment into runtime-async. Overall, the experiment was very successful. For details, see https://github.com/dotnet/runtimelab/blob/feature/async2-experiment/docs/design/features/runtime-handled-tasks.md. We tested two possible implementations: a VM implementation and a JIT implementation. Of the two, we are more positive about the JIT implementation, both for performance and for maintenance.
Our primary conclusion is that runtime-async is at least as good as compiler-async in all the configurations that we measured. In addition, we believe that the new implementation can be fully compatible with the existing compiler-async, meaning that runtime-async can be a drop-in replacement.
We would like to graduate this experiment to a new runtime feature. However, this is a large feature which may take multiple releases to complete. In order to transparently replace the compiler-async implementation we will have to implement all the existing functionality in runtime-async.
For now we'll close out the experiment with the detailed results listed in the link above, and plan to publish more information on runtime-async planning as things become more concrete.
Intro
In .NET 8 we started an experiment in adding support for green threads to .NET. We learned a lot, but decided not to continue at the current time.
In .NET 9 we'd like to take what we learned and explore performance and usability improvements of the existing .NET async
/Task
threading model.
Background
From the C# and .NET libraries level, there are two supporting threading models: OS threads, and C# async
/Task
. Concurrent code can access each of these models using the System.Threading.Thread
type or C# async
/Task.Run
, respectively. For most modern C# code we recommend using async
and Task
if you need blocking-free waiting or concurrency.
The Experiment
The status and code for the in-progress experiment can be found here: https://github.com/dotnet/runtimelab/tree/feature/async2-experiment
An ongoing design doc is present in: https://github.com/dotnet/runtimelab/blob/feature/async2-experiment/docs/design/features/runtime-handled-tasks.md
While async
and Task
are the newest and most-preferred option at the C# and .NET libraries level, they are not a direct part of the .NET runtime threading model.
This experiment asks the question: what if they were? Rather than implement the async
structure entirely in C# as a state machine rewrite, we are interested in exploring direct runtime integration with async methods.
The characteristics we're interested in for this experiment are:
-
Throughput
-
Microbenchmarks -- how much does
await
cost? -
Lots of nested awaits?
-
Frequent suspension vs. rare suspension
-
-
Compatibility
-
Are the semantics similar/identical to C#?
-
Cost of switching
-
-
Code size
-
IL size
-
Crossgen/Native AOT code size
-
As we explore more we might find more questions. At the moment, we're not planning to investigate things which require a lot of additional implementation work.
Metadata
Metadata
Assignees
Type
Projects
Status