Browse Source

Increase .NET minWorkerThreads to improve CPU utilization

MinWorkerThreads controls how many threads the .NET thread pool creates
when a new burst of requests come in. Increase this to properly size the
thread pool early on and improve CPU utilization, increasing throughput.

I saw gains of 5-10% at least.
Malcolm Evershed 12 years ago
parent
commit
938a92b68a
2 changed files with 28 additions and 0 deletions
  1. 23 0
      aspnet/src/Application.cs
  2. 5 0
      aspnet/src/Web.config

+ 23 - 0
aspnet/src/Application.cs

@@ -1,3 +1,6 @@
+using System;
+using System.Configuration;
+using System.Threading;
 using System.Web;
 using System.Web;
 using System.Web.Mvc;
 using System.Web.Mvc;
 using System.Web.Routing;
 using System.Web.Routing;
@@ -25,6 +28,7 @@ namespace Benchmarks.AspNet
         {
         {
             Routes();
             Routes();
             Views();
             Views();
+            Threads();
         }
         }
 
 
         private void Routes()
         private void Routes()
@@ -57,6 +61,25 @@ namespace Benchmarks.AspNet
             ViewEngines.Engines.Add(new RazorViewEngine { ViewLocationFormats = new[] { "~/Views/{0}.cshtml" } });
             ViewEngines.Engines.Add(new RazorViewEngine { ViewLocationFormats = new[] { "~/Views/{0}.cshtml" } });
         }
         }
 
 
+        private void Threads()
+        {
+            // To improve CPU utilization, increase the number of threads that the .NET thread pool expands by when
+            // a burst of requests come in. We could do this by editing machine.config/system.web/processModel/minWorkerThreads,
+            // but that seems too global a change, so we do it in code for just our AppPool. More info:
+            //
+            // http://support.microsoft.com/kb/821268
+            // http://blogs.msdn.com/b/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx
+            // http://blogs.msdn.com/b/perfworld/archive/2010/01/13/how-can-i-improve-the-performance-of-asp-net-by-adjusting-the-clr-thread-throttling-properties.aspx
+
+            int newMinWorkerThreads = Convert.ToInt32(ConfigurationManager.AppSettings["minWorkerThreadsPerLogicalProcessor"]);
+            if (newMinWorkerThreads > 0)
+            {
+                int minWorkerThreads, minCompletionPortThreads;
+                ThreadPool.GetMinThreads(out minWorkerThreads, out minCompletionPortThreads);
+                ThreadPool.SetMinThreads(Environment.ProcessorCount * newMinWorkerThreads, minCompletionPortThreads);
+            }
+        }
+
         public void Dispose()
         public void Dispose()
         {
         {
         }
         }

+ 5 - 0
aspnet/src/Web.config

@@ -29,6 +29,11 @@
     <!-- Disable support for directly accessing *.cshtml/*.vbhtml files because that is a perf killer
     <!-- Disable support for directly accessing *.cshtml/*.vbhtml files because that is a perf killer
          and because we don't use such functionality. -->
          and because we don't use such functionality. -->
     <add key="webpages:Enabled" value="false" />
     <add key="webpages:Enabled" value="false" />
+    <!-- To fully saturate the CPUs, we need to allow the .NET thread pool to create many threads
+         when a large burst of requests come in. We do this by boosting the minWorkerThreads value
+         from the default of 1 per logical processor to 8 per logical processor. This seems to be
+         pretty conservative as http://support.microsoft.com/kb/821268 recommends 50.-->
+    <add key="minWorkerThreadsPerLogicalProcessor" value="8" />
   </appSettings>
   </appSettings>
   <system.web>
   <system.web>
     <!-- Show errors -->
     <!-- Show errors -->