Mã bytecode .NET không phải là định dạng có thể thực thi trực tiếp bởi máy tính, mà nó cần phải được xử lý bằng một số dạng trình tạo code. Điều này có thể đạt được bằng cách biên dịch sẵn(AOT), biên dịch, phiên dịch hoặc biên dịch ngay lúc chạy (JIT). Trên thực tế, hiện nay tất cả cách cách này đều được sử dụng trong các tình huống khác nhau.
.NET được biết đến nhiều nhất với trình biên dịch JIT. Các JIT biên dịch các phương thức (và các thành phần khác) thành native code trong khi ứng dụng đang chạy và chỉ khi chúng cần thiết, do đó có tên “just in time” (đúng lúc). Ví dụ: một chương trình có thể chỉ gọi một trong số các phương thức trên một kiểu khi chạy. Một JIT cũng có thể tận dụng thông tin chỉ có sẵn trong thời gian chạy, như giá trị của các biến tĩnh chỉ đọc đã được khởi tạo hoặc mô hình CPU chính xác mà chương trình đang chạy và có thể biên dịch cùng một phương thức nhiều lần để tối ưu hóa mỗi lần cho các mục đích khác nhau với khả năng tối ưu code dựa trên các bài học từ các lần biên dịch trước đó.
JIT tạo mã cho một hệ điều hành và kiến trúc chip nhất định. .NET có các JIT implementation cho phép hỗ trợ, chẳng hạn như tập lệnh Arm64 và x64 cũng như các hệ điều hành Linux, macOS và Windows. Là một nhà phát triển .NET, bạn không phải lo lắng về sự khác biệt giữa các tập lệnh CPU và cách gọi các phương thức của hệ điều hành. JIT đảm nhiệm việc tạo code mà CPU muốn. Nó cũng biết cách tạo code tối ưu cho từng CPU và các nhà cung cấp hệ điều hành và CPU thường giúp chúng tôi thực hiện chính xác công việc đó.
AOT cũng tương tự ngoại trừ mã được tạo trước khi chạy chương trình. Các nhà phát triển chọn tùy chọn này vì nó có thể cải thiện đáng kể thời gian khởi động bằng cách loại bỏ công việc do JIT thực hiện. Các ứng dụng do AOT xây dựng vốn đã dành riêng cho hệ điều hành và kiến trúc, điều đó có nghĩa là cần có các bước bổ sung để giúp ứng dụng chạy trong nhiều môi trường. Ví dụ: nếu bạn muốn hỗ trợ Linux và Windows cũng như Arm64 và x64, thì bạn cần xây dựng bốn biến thể (để cho phép tất cả các kết hợp: Arm64-Linux, Arm64-Windows, x64-Linux, x64-Windows). Mã AOT cũng có thể cung cấp các tối ưu hóa có giá trị, nhưng nói chung không nhiều như JIT.
Chúng tôi sẽ đề cập đến việc diễn giải và dịch code trong một bài đăng sau, tuy nhiên, chúng cũng đóng vai trò quan trọng trong hệ sinh thái của chúng ta.
Một trong những tối ưu hóa trình tạo mã là intrinsic. Hardware intrinsics là một ví dụ trong đó .NET APIs được dịch trực tiếp thành các lệnh CPU. Điều này đã được sử dụng phổ biến khắp các thư viện .NET cho các lệnh SIMD.