Monday, October 7, 2019

.NET Core: Tiered Compilation

A couple of days back during the .NET Conf, there were some major announcements along with the release of .NET Core 3.0. In this post, I am going to write about something which has been there for almost a year, wasn't available by default, but with .NET Core 3.0, it will be enabled by default. This feature is called Tiered Compilation.

Before moving into Tiered Compilation, let's have a quick recap of how .NET Compilation works. First, the code we have written using high-level languages (C#, F#, etc.) will be compiled into an exe or dll which contains CIL (Common Intermediate Language). And during the run-time, the methods are compiled into Native/Machine code. This is being carried out by JIT (Just-In-Time Compiler) and the process is known as jitting. Basically, whenever some method is being called, that method gets jitted and being stored. When this method is called next time, the method won't get jitted again, instead, it will be loaded from the memory. So all the methods in our code were compiled ONLY ONCE.

Let's just go by an example. Imagine you have this MethodA(), which will get called when you are starting your application. And it will get called throughout the life cycle of your application. JIT can do a very good optimization for your MethodA() based on a variety of algorithms. But that would make your application start slowly. On the other hand, JIT can use a simple algorithm and jit the method fast, so your application would start faster, but the generated code might not be properly optimized and the MethodA() will perform slow.

Enter Tiered Compilation. With Tiered Compilation, based on the usage of a method, it can get jitted more than once and can be hot-swapped at runtime. So basically JIT can pick an approach to start the application fast, and then based on the usage of a method and if the method appears hot, it will compile the same method again to generate more efficient code and use it for future calls.

This is how the Tiered Compilation works. First Tiered Compilation breaks the code into 2 buckets.
  1. Code that is eligible for tiering
    1. Tier0
      • This is usually the less optimized code that is generated using minimal optimizations. That is when the method is first invoked, the Tier0 version generated.
    2. Tier1
      • This is whatever code the runtime thinks will run faster than Tier0. If any method appears hot, the runtime would jit the method again with a more optimized version and will replace Tier0.
  2. Code that is NOT eligible for tiering
    • Will be jitted as before Tiered Compilation was introduced
Tiered Compilation was added as an opt-in feature in .NET Core 2.1. But with .NET Core 3.0,  it is enabled by default.

To enable Quick JIT (Tier0 jitted code), update the .csproj as follows.
<PropertyGroup>
  <TieredCompilationQuickJit>true</TieredCompilationQuickJit>
</PropertyGroup>
To disable Tiered compilation,  update the .csproj as follows.
<TieredCompilation>false</TieredCompilation>

More information:
   Tiered Compilation
   Tiered Compilation Guide

Happy Coding.

Regards,
Jaliya

No comments:

Post a Comment