{"id":994,"date":"2013-11-15T08:03:00","date_gmt":"2013-11-15T08:03:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/webdev\/2013\/11\/15\/asp-net-performance-prefetch-and-multi-core-jitting\/"},"modified":"2013-11-15T08:03:00","modified_gmt":"2013-11-15T08:03:00","slug":"asp-net-performance-prefetch-and-multi-core-jitting","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/asp-net-performance-prefetch-and-multi-core-jitting\/","title":{"rendered":"ASP.NET Performance: Prefetch and Multi-Core Jitting"},"content":{"rendered":"<p><em>Editor note: This blog is originally published by <a href=\"http:\/\/blogs.msdn.com\/272012\/ProfileUrlRedirect.ashx\">Jose Reyes &#8211; ASP.NET<\/a><\/em><em> on 02-29-2012 in <\/em><a href=\"http:\/\/blogs.msdn.com\/b\/web_performance_blog\/\"><em>Web Performance Blog<\/em><\/a><em>, which will be obsolete soon.&nbsp; Future ASP.NET related performance blogs will be posted here.<\/em><\/p>\n<div class=\"WordSection1\">\n<h2><span style=\"font-variant: normal !important\">Introduction.<\/span><\/h2>\n<p class=\"MsoNormal\">A couple of new features are introduced in ASP.NET 4.5 to improve startup time of web apps. Both features use a flag on the web.config to enable them. The features don&rsquo;t do any magic by themself. They just enable features available on the operating system underneath or in the CLR APIs.<\/p>\n<h2><span style=\"font-variant: normal !important\">Prefetch feature<\/span><\/h2>\n<p class=\"MsoNormal\">The prefetch feature only works on Windows 8 Server or newer OS. It requires the Os to be configured and the enablePrefetchOptimization flag on the &lt;system.web\/compilation&gt; section of web.config to be set. The flag only has effect at the app level. No subdirectory config or location tag makes sense here. The setting is set to false by default, so users must explicitly set it to true in order for it to work.<\/p>\n<p class=\"MsoNormal\">To enable the feature, run the Enable-MMAgent power shell command:<\/p>\n<p class=\"MsoNormal\"><span style=\"color: #595959;font-family: consolas\">&nbsp;&nbsp;&nbsp; powershell Enable-MMAgent -OperationAPI<\/span><\/p>\n<p class=\"MsoNormal\">The SuperFetch service might need to be started. Verify is running:<\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">C:&gt;sc query sysmain<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">SERVICE_NAME: sysmain<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TYPE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 20&nbsp; WIN32_SHARE_PROCESS<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STATE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 4&nbsp; <span style=\"background: yellow\">RUNNING<\/span><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WIN32_EXIT_CODE&nbsp;&nbsp;&nbsp; : 0&nbsp; (0x0)<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SERVICE_EXIT_CODE&nbsp; : 0&nbsp; (0x0)<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CHECKPOINT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0x0<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WAIT_HINT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0x0<\/span><\/p>\n<h2><span style=\"font-variant: normal !important\">Prefetch Implementation.<\/span><\/h2>\n<p class=\"MsoNormal\">The features simple uses the operation recorder API. See <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/hh437562(v=vs.85).aspx\">OperationStart<\/a> and <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/hh437558(v=vs.85).aspx\">OperationEnd<\/a> APIs on msdn. This APIs require an integer used as an Id of the operation. We use a hash code of the app domain app id, which is a string.<\/p>\n<p class=\"MsoNormal\" style=\"text-align: left;line-height: normal;margin-bottom: 0pt\" align=\"left\"><span style=\"color: blue;font-family: consolas;font-size: 9.5pt\">string<\/span><span style=\"font-family: consolas;font-size: 9.5pt\"> domainId = <span style=\"color: #2b91af\">HttpRuntime<\/span>.AppDomainAppId;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"text-align: left;line-height: normal;margin-bottom: 0pt\" align=\"left\"><span style=\"color: blue;font-family: consolas;font-size: 9.5pt\">int<\/span><span style=\"font-family: consolas;font-size: 9.5pt\"> operationId = domainId.GetHashCode(); <\/span><\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p class=\"MsoNormal\">The OperationStart call is made the first time the app domain is created. The OperationEnd API is called at the end of the request in which we called OperationStart. A .pf file should be created on the prefetch directory:<\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">C:&gt;dir %windir%Prefetch<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\"> Volume in drive C has no label.<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\"> Volume Serial Number is CC5B-113C<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\"> Directory of C:WindowsPrefetch<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">02\/16\/2012&nbsp; 04:17 PM&nbsp;&nbsp;&nbsp; &lt;DIR&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">02\/16\/2012&nbsp; 04:17 PM&nbsp;&nbsp;&nbsp; &lt;DIR&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ..<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">02\/16\/2012&nbsp; 04:17 PM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 164,832 <span style=\"background: yellow\">Op-W3WP.EXE-90E54C33-765F360E.pf<\/span><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 File(s)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 164,832 bytes<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: 0pt\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 Dir(s)&nbsp; 30,203,154,432 bytes free<\/span><\/p>\n<h2><span style=\"font-variant: normal !important\">Multi-Core Jitting feature.<\/span><\/h2>\n<p class=\"MsoNormal\">The multi-core jitting feature is enabled by default, and work on all OS where ASP.NET 4.5 is available. You can disable it by setting the profileGuidedOptimizations enumerated value on the &lt;system.web\/compilation&gt; section on the web.config, to <em><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">None<\/span><\/em>.<\/p>\n<h2><span style=\"font-variant: normal !important\">Multi-Core Jitting Implementation.<\/span><\/h2>\n<p class=\"MsoNormal\">The feature uses the new class <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.runtime.profileoptimization(v=VS.110).aspx\">ProfileOptimization<\/a> class of the System.Runtime namespace. The class is called the first time the app domain is created. First, we set the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.runtime.profileoptimization.setprofileroot(v=vs.110).aspx\">profile<\/a> root to the codegen directory, which by default is something like:<\/p>\n<p class=\"MsoNormal\">&#8220;%windir%Microsoft.NETFramework64v4.0.30319Temporary ASP.NET Files<strong>myapp<\/strong>weirdhash1weirdhash2&#8243;<\/p>\n<p class=\"MsoNormal\">Remember that the temporary files folder value can be changed on tempDirectory attribute of the &lt;system.web\/compilation&gt; section of the web.config.<\/p>\n<p class=\"MsoNormal\">After setting the profile root, we call <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.runtime.profileoptimization.startprofile(v=vs.110).aspx\">StartProfile<\/a>() with the filename &#8220;profileoptimization.prof&#8221;. The CLR code underneath handles all the magic. If you examine the contents of the temporary ASP.NET file folder, you will see the file there:<\/p>\n<p class=\"MsoNormal\" style=\"text-align: left;margin-bottom: 0pt\" align=\"left\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">C:WindowsMicrosoft.NETFramework64v4.0.30319Temporary ASP.NET Filesdotnetnuke59a60e53a2ac2624&gt;dir *.prof<\/span><\/p>\n<p class=\"MsoNormal\" style=\"text-align: left;margin-bottom: 0pt\" align=\"left\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\"> Volume in drive C has no label.<\/span><\/p>\n<p class=\"MsoNormal\" style=\"text-align: left;margin-bottom: 0pt\" align=\"left\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\"> Volume Serial Number is CC5B-113C<\/span><\/p>\n<p class=\"MsoNormal\" style=\"text-align: left;margin-bottom: 0pt\" align=\"left\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"text-align: left;margin-bottom: 0pt\" align=\"left\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\"> Directory of C:WindowsMicrosoft.NETFramework64v4.0.30319Temporary ASP.NET Filesdotnetnuke59a60e53a2ac2624<\/span><\/p>\n<p class=\"MsoNormal\" style=\"text-align: left;margin-bottom: 0pt\" align=\"left\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"text-align: left;margin-bottom: 0pt\" align=\"left\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">02\/16\/2012&nbsp; 04:38 PM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9,828 <span style=\"background: yellow\">profileoptimization.prof<\/span><\/span><\/p>\n<p class=\"MsoNormal\" style=\"text-align: left;margin-bottom: 0pt\" align=\"left\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 File(s)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9,828 bytes<\/span><\/p>\n<p class=\"MsoNormal\" style=\"text-align: left;margin-bottom: 0pt\" align=\"left\"><span style=\"line-height: 115%;font-family: 'Courier New';font-size: 9pt\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 Dir(s)&nbsp; 30,203,035,648 bytes free&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/p>\n<h2><span style=\"font-variant: normal !important\">Conclusion.<\/span><\/h2>\n<p class=\"MsoNormal\">The ASP.NET Prefetch feature uses the operation recording APIs to improve startup time of web applications. The feature is enabled when a Windows Server 8 machine is configured for the operation API and enabledPrefetchOptimization flag is set on the web.config.<\/p>\n<p class=\"MsoNormal\">The multi-core jitting feature is available in more operating systems and is on by default. It uses a new CLR feature for profile base optimization.<\/p>\n<p class=\"MsoNormal\">Thanks for reading.<\/p>\n<\/div>\n<p>Originally posted at <a href=\"http:\/\/blogs.msdn.com\/b\/josere\/\">http:\/\/blogs.msdn.com\/b\/josere\/<\/a><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Editor note: This blog is originally published by Jose Reyes &#8211; ASP.NET on 02-29-2012 in Web Performance Blog, which will be obsolete soon.&nbsp; Future ASP.NET related performance blogs will be posted here. Introduction. A couple of new features are introduced in ASP.NET 4.5 to improve startup time of web apps. Both features use a flag [&hellip;]<\/p>\n","protected":false},"author":410,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[197],"tags":[31,108],"class_list":["post-994","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aspnet","tag-asp-net","tag-performance"],"acf":[],"blog_post_summary":"<p>Editor note: This blog is originally published by Jose Reyes &#8211; ASP.NET on 02-29-2012 in Web Performance Blog, which will be obsolete soon.&nbsp; Future ASP.NET related performance blogs will be posted here. Introduction. A couple of new features are introduced in ASP.NET 4.5 to improve startup time of web apps. Both features use a flag [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/994","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/410"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=994"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/994\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=994"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=994"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=994"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}