In the previous post we discussed how we can improve JIT compilation of .net code by using ProfileOptimization for multicore machines in a .net framework 4.5 application. In this post we are going to discuss another CLR area improved in .net framework 4.5. In the next post, we going to discuss the new tools available in Visual Studio 2012 to further improve this. This discussion is about Native Images of assembly, why we need them and how to write better native assemblies.
What are Native Assemblies?
In the last post we discussed that IL code is compiled into Native code by JIT compiler when the process is being run by CLR. So a natural thought could be what if we could do this compilation before hand and generate the native images. We can use this native image when we actually need them in a process. It would be even better if this image could be shared by various application domains. As a matter of fact, native assemblies in .net fulfills this wish list. Not only they support the native image of a specified assembly, they also support creation of native images of other dependent assemblies.
As we know that JIT compiled image of methods is kept in the memory space of the running process, so creating native images upfront would reduce the memory footprint of the process. This compiled image would also be shared by all the processes requesting the same assembly, hence no process need to JIT compile it separately [as they are Windows PE files] and the proceses could share this, improving the overall system performance. Additionally this would improve the startup time of the process. In addition of time saved for JIT compilation, they also don't require any type safety verification.
Native Images Storage
NGEN [Native Image Generator] creates native image of a managed assembly and installs them to Native Image Cache. This is a reserved area in GAC [Global Assembly Cache]. So this might also be treated as a Time Vs Space trade-off where we sacrifice the hard disk space for the gains in the time saved during the process execution.
You should be able to find them in %WinDir%\assembly\NativeImages_RUNTIMEVERSION.
It must be remembered that these directories not visible in Folder explorer. We can check the contents of the folder in command window though.
Life Time of Native Images
Now let us discuss if these native images last forever on the machines and if and when they can be removed form the machine. This is called reclaiming the images. Before .net framework 4.5 and Windows 8, these images can be claimed manually using NGEN Unistall command. The command can be part of application uninstaller package.
The new framework also supports this for the images installed manually on Windows 8 operating system. For the images created automatically can be claimed automatically by the operating system if they haven't been used for a long time creating more free space for the more frequently used stuff on the machine. These are claimed by Native Image Task during the idle time.
User Level Native Images & Application Container level Native Images
For Windows 8 and later versions of the operating system, .net framework 4.5 supports creation of user and application container based native images. So if a machine is shared between different users, the native images can be made to not share between different user profiles.
Deciding IL Vs Native Images
From the above description it seems that NGENing assemblies would always be beneficial as we are bypassing the JIT compilation when the application is running. Is it really so? NGEN.exe is only for assemblies which run in a full trust scenario. If they are referenced in an application running in partial trust then their non-native version is loaded which goes through JIT compilation.
CLR puts the validation of strong named assemby under extra test which are not in GAC. so if our native image is for a strong assembly [not in GAC], we might not get any benefit as the CLR would still touch every page of the assembly which would nullify any gain caused by NGENing the assemblies.
Native Image Generator [NGEN.exe]
.net framework provides NGEN [Native image GENerator] for assembly's native image generation based on the processor architecture based instruction set. Once we have the native image of an assembly, it doesn't need to be JIT compiled when the application is running, improving the performance of the application. Native Image Generator can be launched using Developer Command Prompt in available with Visual Studio 2012 or Windows SDK Command Shell. For Visual Studio 2012, it appears in the start menu as follows:
The tool supports both installing and uninstalling native images from the native image store. The help about NGEN commands can be obtained by using /? switch with the executable as follows:
Deferring Native Image Generation
Native Image generation work can also be deferred up to when machine has some idle time. This is actually done by queuing up the NGENing of an assembly. This is then taken care of by Native Image Service. This is also used to update the native images because of other related dependencies updates including any updates in .net framework. This service can stand multiple machine reboots as it stores its state. Installation scripts can use NGEN.exe to queue up items for Native Image Service for low priority NGENing running with administrator privilege (which is a general requirement for running NGEN.exe for creating native images). The installer first copies the assembly to the application folder and then uses NGEN to queue up item for deferred NGEN using Native Image Service or Native Image Task based on the operating system you are doing the installation.
For Windows 8 onwards, the responsibilty of NGENing the queued up assemblies is taken over by Native Image Task. This task also support the automatic native image generation and reclaim for an assembly. [http://msdn.microsoft.com/en-us/library/hh691779.aspx]. The automatic NGEN is only for assemblies targeting .net framework 4.5 or later, plus it must have been installed in GAC or Windows Store App package. The automatic native image generation is achieved by the .net framework by tracking down the JITing of an assembly. They are queued for NGENing when the machine is idle.
Assembly Probing and native images
We have discussed in the past how we can determnine the assemblies loaded by an application using Fusion Log Viewer, Process Explorer, List DLls and Visual Studio Modules window [http://www.shujaat.net/2012/04/fusion-log-viewer-fuslogvw-for-assembly.html]. We know that these assemblies can be loaded from different locations which are searched in a predefined fashion. An application can go through a list of steps to locate the requested assembly. This is called Assembly Probing. You can find the details of the process here [How the Runtime Locates Assemblies]. We must remember that they require the application to be running in [Full Trust] for .net framework 4.0 onwards. But after .net framework 2.0, these assemblies can be shared across application domains, plus we don't need to individually NGEN assemblies, while doing this, we can also NGEN their dependencies if they are available in assembly manifest.
Native Image Generation Log
.net framework also supports generation of logs for native images generation of assemblies. These logs can be used for troubleshooting any possible issue when needed. The logs are created in the .net framework folder in %WinDir% folder as follows:
It seems that the log for NGEN service is maintained separately. You can see the NGEN service log as well in the above snapshot. The contents of the log are as follows:
The verbosity of the logs can be controlled using HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\NGenLogVerbosity registry entry. The supported values are 1, 2 and 3. The default value is 2 which is also used in the absence of this registry entry.
.net framework 4.5 also caps the size of this log for computer wide [1MB], user [500KB - Win8 only] and app container [100KB - Win8 only] specific native image generation. The details can be found here: [http://msdn.microsoft.com/en-us/library/hh708846.aspx]
MSCORSVW.EXE
MSCORSVW.exe is used to compile the .net assemblies to native images in the background. You might have seen some threads specially discussing and asking question specially about this executable. Actually you can find the executable in the following folder:
The remedy to get rid of this process is to finish all the queued up items waiting for getting compiled as discussed here:[http://blogs.msdn.com/b/davidnotario/archive/2005/04/27/412838.aspx]. Although this is an old post but it should still be valid.
Native Images and Windows App Store Packages
As we discussed before, Windows 8 supports automatic creation of native images for public assemblies. This is actually one of the App certification requirement for a Windows Store App. This is part of performance test, you can find it here: [http://msdn.microsoft.com/en-us/library/windows/apps/jj657973.aspx#performance_test]. We can also opt-out for this automatic native image generation by including nongen.txt file in our App package.
Linking Native Images with IL Assembly Image
[Erez Metula] has an amazing description of how native images are linked by IL assembly images by .net framework [Chapter 8]. The book is available on amazon and rightly deserves the rating. The book was released in November, 2011, so it discusses the features with .net 3.5 SP1 context [.net v4.0 - released: 3,2011]. But most of the stuff is still valid.
Here IL contains the details of the assemblies which have their native images already created in the cache. NI has further details about the native images identified by [MVID].
Showing posts with label JIT. Show all posts
Showing posts with label JIT. Show all posts
Thursday, January 31, 2013
Native Images of Assemblies - .net framework 4.5
Friday, January 25, 2013
Profile Optimization for .net framework 4.5 Applications
In this post we are going to discuss the performance improvement in .net framework 4.5 in the area of Just In Time [JIT] compilation. As we know the .net applications are compiled into Intermediate Language [IL] code. This is irrespective of the programming language chosen to develop the application. Now when the application is run, the IL code is read by the CLR and JIT compiled into native code for the particular machine.
So the compilation from the IL Code to the native code happens when the application is actually running. So it shouldn't take a long time to understand that we can improve application performance if we could avoid this. One way to do this is to generate native code using Native Image Generator i.e. NGen.exe. In this case the assembly's native images is loaded from the Native Image Cache from GAC [Global Assembly Cache]. The other option is to still do it dynamically just in time but somehow improve the performance of this JIT compilation. This is exactly what is added to .net framework 4.5.
.net framework 4.5 supports this optimization using application profiles. Now we can enable the profile optimization for an application. Based on the historic profile, it keeps JIT compiling the methods in the background. So when the code is actually needed for execution, it is already in native format so the runtime doesn't have to wait for this.
Now let's see how we can enable an application for this optimization using profiles. In order to support this feature, a new type is added to System.Runtime namespace in mscorlib.dll assembly. As you could guess, this is named as ProfileOptimization class. In the following code, we are setting the directory where the profile would be stored. Next we are starting to profile the application.
The CLR creates the file for profile in the specified folder as follows:
Generally, while improving the performance of an application, we look forward to improve the different features provided by the application irrespective of the usage scenarios. Since this JIT compilation is based on past usage of the application, the application would be optimized differently based on these profile files. This is custom optimization of software based on temporal use of the feature. This is because if I have used a feature today, there is a high probability I would be using the application similarly as I am using it today. The runtime is just keeping the usage pattern in persistence and would use it for future use of the application. Since this is based on past profiles, there wouldn't be any advantage the first time the application is running.
It must be remembered that ProfileOptimization is just beneficial for applications running on multicore machines. It's usage is simply ignored if the application is running on a single core machine. There would be no profiling and hence no resulting optimization.
Please remember that Profile Optimization is different than Profile Guided Optimization, another features introduced in .net framework. Profile Guided optimization is about improving the layout of native libraries, not running on CLR, based on some test scenarios. Profile Optimization is about background [JIT]ing the application using mutlicore extra resources. On the other hand Profile Guided Optimization is a compiler optimization technique which improve the native image layout based on some test scenarios. It would definitely be better that compiler heuristic but it definitely wouldn't be based on the actual usage of the system which could be different than the selected test scenarios. Microsoft has included some extra tools in Visual Studio 2012 to make the guided optimization better including MPGO [Managed Profile Guided Optimization] tool.
[Note] This is enabled by default for ASP.net 4.5 and Silverlight 5 applications.
So the compilation from the IL Code to the native code happens when the application is actually running. So it shouldn't take a long time to understand that we can improve application performance if we could avoid this. One way to do this is to generate native code using Native Image Generator i.e. NGen.exe. In this case the assembly's native images is loaded from the Native Image Cache from GAC [Global Assembly Cache]. The other option is to still do it dynamically just in time but somehow improve the performance of this JIT compilation. This is exactly what is added to .net framework 4.5.
.net framework 4.5 supports this optimization using application profiles. Now we can enable the profile optimization for an application. Based on the historic profile, it keeps JIT compiling the methods in the background. So when the code is actually needed for execution, it is already in native format so the runtime doesn't have to wait for this.
Now let's see how we can enable an application for this optimization using profiles. In order to support this feature, a new type is added to System.Runtime namespace in mscorlib.dll assembly. As you could guess, this is named as ProfileOptimization class. In the following code, we are setting the directory where the profile would be stored. Next we are starting to profile the application.
The CLR creates the file for profile in the specified folder as follows:
Generally, while improving the performance of an application, we look forward to improve the different features provided by the application irrespective of the usage scenarios. Since this JIT compilation is based on past usage of the application, the application would be optimized differently based on these profile files. This is custom optimization of software based on temporal use of the feature. This is because if I have used a feature today, there is a high probability I would be using the application similarly as I am using it today. The runtime is just keeping the usage pattern in persistence and would use it for future use of the application. Since this is based on past profiles, there wouldn't be any advantage the first time the application is running.
It must be remembered that ProfileOptimization is just beneficial for applications running on multicore machines. It's usage is simply ignored if the application is running on a single core machine. There would be no profiling and hence no resulting optimization.
Please remember that Profile Optimization is different than Profile Guided Optimization, another features introduced in .net framework. Profile Guided optimization is about improving the layout of native libraries, not running on CLR, based on some test scenarios. Profile Optimization is about background [JIT]ing the application using mutlicore extra resources. On the other hand Profile Guided Optimization is a compiler optimization technique which improve the native image layout based on some test scenarios. It would definitely be better that compiler heuristic but it definitely wouldn't be based on the actual usage of the system which could be different than the selected test scenarios. Microsoft has included some extra tools in Visual Studio 2012 to make the guided optimization better including MPGO [Managed Profile Guided Optimization] tool.
[Note] This is enabled by default for ASP.net 4.5 and Silverlight 5 applications.
Subscribe to:
Posts (Atom)










