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].
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.
Wednesday, January 16, 2013
Connect Items Status for Portable Class Library Project References
A few months back we disucssed about an issue with assembly references with Portable Class Library Project. The issue was submitted here:
https://connect.microsoft.com/VisualStudio/feedback/details/768350/assembly-references-in-portable-library-projects
We have a complete post detailing the actual issue here:
http://www.shujaat.net/2012/10/issues-bugs-with-portable-class-library.html
Microsoft team was kind enough to pick up the issue for fixing. Actually the connect item has two reported items. It seems that the issue is partially fixed in the final release of Visual Studio 2012. The status is now set as "Active".
https://connect.microsoft.com/VisualStudio/feedback/details/768350/assembly-references-in-portable-library-projects
We have a complete post detailing the actual issue here:
http://www.shujaat.net/2012/10/issues-bugs-with-portable-class-library.html
Microsoft team was kind enough to pick up the issue for fixing. Actually the connect item has two reported items. It seems that the issue is partially fixed in the final release of Visual Studio 2012. The status is now set as "Active".
Sunday, January 13, 2013
.net framework 4.5 & Compression - ZipPackage and Open Package Specification API
In this post we are going to discuss how we can use the Open Package Specification API in .net framework for compression and decompression. Although we can not use the API to decompress the standard Zip files, but the compressed files using the API can be read and decompressed using the API. So if the feature under development needs decompression of self-compressed data files, the API can be used in a desktop application. It must be remembered that newer file formats including docx, pptx and nupkg are based on the Open Package Convention. Yes, it also includes Nuget packages. This is what msdn has to say about the System.IO.Packaging namespace.
"Provides classes that support storage of multiple data objects in a single container. ["msdn] The types for the API resides in System.IO.Packaging namespace in WindowsBase.dll assembly.
WindowsBase.dll is available as a default assembly in a WPF Application project, still we can add it manually for other project types.
The System.IO.Packaging namespace was added in .NET Framework 3.0. For dealing with compression and Decompression, we can use ZipPackage and ZipPackagePart types. ZipPackage inherits from the Package.
Similarly ZipPackagePart is the specialization of PackagePart type available in the same namespace.
Compression
Let's see how can we write a very simple code to compress packages using the packaging API. Below is a method that takes a folder name as input. It compresses the immediate files in a folder to the compressed file name provided as the second parameter to the method.
The above code gets the list of file names in a folder. It then creates a package and adds the files to the package as package parts. Please note that the sample code would just work for single level of files in a folder. We can use the similar code recursively to compress the folder hierarchy.
Here MimeMapping is from System.Web assembly and the same namespace. This is a new type introduced with .net framework 4.5. This type is not available by default with default Console application template and we need to add a separate reference of System.Web assembly in order to use this type. This type can be used to map document extensions to mime type.
Based on the Open package specification, the API creates a file [Content_Type].xml in the compressed file. The contents of the file is the details of extensions and their mime types. For my case, the contents were as follows:
This is the standard format for the file.
Decompression
Decompressing a compressed packages as also as easy. The caveat is that the standard zip files can not be directly decompressed using the API. This is because of the requirement of [Content_Type].xml file in the package to be decompressed. Actually Package.GetParts() wouldn't return anything if the file is absent.
The above code checks if the destination folder exists, it creates it if non-existent. It then reads the immediate contents of the package i.e. package parts and streams them individually to the specified folder.HttpUtility is also from System.Web. We have used UrlDcode from the type to remove any "%20" added to the file name. The method decodes them to spaces.
Download
"Provides classes that support storage of multiple data objects in a single container. ["msdn] The types for the API resides in System.IO.Packaging namespace in WindowsBase.dll assembly.
WindowsBase.dll is available as a default assembly in a WPF Application project, still we can add it manually for other project types.
The System.IO.Packaging namespace was added in .NET Framework 3.0. For dealing with compression and Decompression, we can use ZipPackage and ZipPackagePart types. ZipPackage inherits from the Package.
Similarly ZipPackagePart is the specialization of PackagePart type available in the same namespace.
Compression
Let's see how can we write a very simple code to compress packages using the packaging API. Below is a method that takes a folder name as input. It compresses the immediate files in a folder to the compressed file name provided as the second parameter to the method.
The above code gets the list of file names in a folder. It then creates a package and adds the files to the package as package parts. Please note that the sample code would just work for single level of files in a folder. We can use the similar code recursively to compress the folder hierarchy.
Here MimeMapping is from System.Web assembly and the same namespace. This is a new type introduced with .net framework 4.5. This type is not available by default with default Console application template and we need to add a separate reference of System.Web assembly in order to use this type. This type can be used to map document extensions to mime type.
Based on the Open package specification, the API creates a file [Content_Type].xml in the compressed file. The contents of the file is the details of extensions and their mime types. For my case, the contents were as follows:
This is the standard format for the file.
Decompression
Decompressing a compressed packages as also as easy. The caveat is that the standard zip files can not be directly decompressed using the API. This is because of the requirement of [Content_Type].xml file in the package to be decompressed. Actually Package.GetParts() wouldn't return anything if the file is absent.
The above code checks if the destination folder exists, it creates it if non-existent. It then reads the immediate contents of the package i.e. package parts and streams them individually to the specified folder.HttpUtility is also from System.Web. We have used UrlDcode from the type to remove any "%20" added to the file name. The method decodes them to spaces.
Download
Subscribe to:
Posts (Atom)