Generating Native Code for Assemblies

When the CLR needs to execute code in an assembly, it passes the code through a just-in-time (JIT) compiler and turns the MSIL to native code that can be executed by the machine's CPU. The advantage to this JIT design is that you can ship MSIL code without having to worry about optimizing your code for the target processor. The .NET Framework will most likely be ported to a variety of CPU architectures found in a variety of devices from computers to handheld systems, and attempting to write optimal code for each of those processors would be a daunting task. This work is unnecessary, because each implementation of the .NET Framework ships with a JIT compiler that turns MSIL instructions into instructions optimal for the target CPU.

If performance is of the utmost concern in your application, you can turn your MSIL code into CPU-specific machine code through a process known as native image generation. During this process, MSIL instructions found in an assembly are translated into native CPU-specific instructions, which can then be written to disk. After this native image generation has completed, the CLR can make use of that code and can skip the JIT step normally employed for assemblies.

The .NET Framework ships with a tool called the Native Image Generator, which generates a native image for an assembly. This command-line tool is found in an executable called ngen.exe and takes an assembly name as input:

ngen assembly

The native image is placed in a cache of native images for assemblies.

Keep in mind that ngen must be run on the device that executes the generated code. You cannot, for example, build assemblies as part of your build process, run ngen on the assemblies, and ship the native images to your customers. Your build machine might very well have a different CPU than your customer's machines, and ngen generates code for the CPU on which ngen is executing. If it is important for your customers to have native images for your assemblies, you must run ngen on the customer's machines as a part of the installation process.

It is also important to note that the original .NET assemblies must be available at all times, even if native code is available in the native image cache. The native images are standard Win32 Portable Executable (PE) files and lack all of the metadata available in a .NET assembly. If code loads your native image assembly and executes code that forces the .NET Framework to examine metadata (using Reflection, for example, to obtain type information for the assembly), then the original .NET assembly must be available so that the CLR can query its metadata. The metadata will not be carried with the native image.

0 0

Post a comment