<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Developer Division Performance Engineering blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/ddperf/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/ddperf/feed.xml</link>
    <description>News and commentary on developing scalable Windows applications with Visual Studio</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:00:27 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Help Make Visual Studio Faster</title>
      <link>https://docs.microsoft.com/archive/blogs/ddperf/help-make-visual-studio-faster</link>
      <pubDate>Thu, 05 May 2011 23:45:55 GMT</pubDate>
      <dc:creator><![CDATA[David Berg]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ddperf/2011/05/05/help-make-visual-studio-faster/</guid>
      <description><![CDATA[One of the most difficult things about our job is trying to decipher why Visual Studio is slow for a...]]></description>
      <content:encoded><![CDATA[<p>One of the most difficult things about our job is trying to decipher why Visual Studio is slow for a customer.&nbsp; Often it starts with a vague complaint (e.g. "Visual Studio is sluggish") which we then have to narrow down to a particular action that's slow, and try and get a profile.&nbsp; Then we have to look through a large profile and figure out which code is running slower than it should be and why.&nbsp; Sometimes the problem is CPU intensive, sometimes it's disk or network, sometimes it's a different program altogether that just happens to be slow.&nbsp; I know the process is just as frustrating for customers, who have to try and figure out just where it is slow and get us a profile.&nbsp; And of course, if VS is just a little bit slow, then it's often much easier to live with it than go through the hassle of trying to help us isolate it.</p>
<p>That's why I'm pleased to announce that we now have a better approach.&nbsp; <a href="https://blogs.msdn.com/b/visualstudio/archive/2011/05/02/perfwatson.aspx" title="VS Blog - Perf Watson">Visual Studio Perf Watson</a>&nbsp;is now available for download and use with VS2010 SP1.&nbsp; If you download and install Perf Watson it does everything for you (and us).&nbsp; Here's how it works:</p>
<ol>
<li>Perf Watson monitors VS to make sure it is responsive.</li>
<li>If VS goes unresponsive for more than 2 seconds, Perf Watson grabs a stack frame.</li>
<li>Perf Watson then times how long it takes for&nbsp;VS to become responsive again.</li>
<li>Perf Watson then takes the stack information along with the total time of the hang and sends it to Microsoft.</li>
<li>We take the data and load it into a database.</li>
<li>We analyze the data to see which call stacks are causing the longest hangs that impact the most customers, and then we log bugs on those.</li>
<li>Since we have call stacks, the bugs tend to be very actionable.</li>
<li>Since the data comes from real customers, with hit counts and severity information, we have no trouble prioritizing these performance hangs appropriately - we know exactly what they're costing you.</li>
</ol>
<p>We've been using Perf Watson internally for a while now, and we've been able to identify and fix a lot of problems just based on our internal product usage.&nbsp; We've also seen some nice correlation between issues raised by Perf Watson and issues found through other analysis.&nbsp; This correlation helps us know that we're on the right track and gives extra weight to getting these issues resolved.</p>
<p>But our usage patterns aren't the same as yours.&nbsp; Everyone uses VS a little bit differently.&nbsp; That's why we're excited to put Perf Watson in your hands so that we can get an accurate picture of the performance issues you're running into, with strong metrics and data to back up the work we need to do.</p>
<p>I hope you'll decide to download and install Perf Watson.&nbsp; </p>
<p>Regards,</p>
<p>David Berg<br />DDPE</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Performance Troubleshooting Article and VS2010 SP1 Change</title>
      <link>https://docs.microsoft.com/archive/blogs/ddperf/performance-troubleshooting-article-and-vs2010-sp1-change</link>
      <pubDate>Tue, 01 Mar 2011 16:48:00 GMT</pubDate>
      <dc:creator><![CDATA[David Berg]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ddperf/2011/03/01/performance-troubleshooting-article-and-vs2010-sp1-change/</guid>
      <description><![CDATA[Jason Zander just posted an article on Performance Troubleshooting Article and VS2010 SP1 Change,...]]></description>
      <content:encoded><![CDATA[<p>Jason Zander just posted an article on <a href="https://blogs.msdn.com/b/jasonz/archive/2011/03/03/performance-troubleshooting-article-and-vs2010-sp1-change.aspx">Performance Troubleshooting Article and VS2010 SP1 Change</a>, where he talks about some changes we made in SP1 and links to an article on <a href="https://msdn.microsoft.com/en-us/vstudio/ff716700">Visual Studio (Performance) Troubleshooting</a>.&nbsp; Check it out and let us know if it helps, and what other type of information would be useful.</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Visual Studio 2010 Survey</title>
      <link>https://docs.microsoft.com/archive/blogs/ddperf/visual-studio-2010-survey</link>
      <pubDate>Sun, 10 Oct 2010 07:18:38 GMT</pubDate>
      <dc:creator><![CDATA[David Berg]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ddperf/2010/10/10/visual-studio-2010-survey/</guid>
      <description><![CDATA[We'd like to know what you think about Visual Studio 2010.&nbsp; 
We are especially interested in...]]></description>
      <content:encoded><![CDATA[<p>We'd like to know what you think about Visual Studio 2010.&nbsp; </p>
<p>We are especially interested in hearing about your experience with regards to <strong>performance</strong>, <strong>reliability</strong>,<strong> </strong>and<strong> quality</strong>.&nbsp; The more details you share with us in this survey, the better we can understand your&nbsp;experience and apply what we learn into future versions.</p>
<p>The survey is very short and should take you no more than a few minutes. You can get&nbsp;started by clicking on&nbsp;<a href="https://go.microsoft.com/fwlink/?LinkId=203459" title="Visual Studio 2010 Survey"><strong><span style="color: #366df4;">Visual Studio 2010 Survey</span></strong></a>.&nbsp;&nbsp;&nbsp;</p>
<p>It's important that we here from you whether you love us or hate us.&nbsp; The more people who respond, the better we can understand how we're doing and whether or not we're doing the right things to make a difference.</p>
<p>Regards and thanks for your time,</p>
<p>David Berg<br />Developer Division Performance Engineering Team</p>]]></content:encoded>
    </item>
    <item>
      <title>VS2010 Performance and Bad Video Drivers/Hardware - Redux</title>
      <link>https://docs.microsoft.com/archive/blogs/ddperf/vs2010-performance-and-bad-video-drivershardware-redux</link>
      <pubDate>Thu, 16 Sep 2010 23:19:00 GMT</pubDate>
      <dc:creator><![CDATA[David Berg]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ddperf/2010/09/16/vs2010-performance-and-bad-video-drivershardware-redux/</guid>
      <description><![CDATA[Since we shipped Visual Studio 2010 we've continued to have a small but notable series of complaints...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: x-small;">Since we shipped Visual Studio 2010 we've continued to have a small but notable series of complaints about performance that we've been able to attribute to bugs in video drivers and GPUs.</span></p>
<p><span style="font-size: x-small;">The issue first came up back during </span><a href="https://blogs.msdn.com/b/ddperf/archive/2009/10/29/vs2010-performance-and-bad-video-drivers-hardware.aspx"><span style="font-size: x-small;">VS 2010 beta in October of 2009</span></a><span style="font-size: x-small;">.&nbsp; Since then we've learned that while old, buggy drivers are the usual cause, some newer drivers and GPUs aren't as good at supporting VS's UI as we'd like.&nbsp; (This is also an issue with VMs and VM hosts as Video Virtualization technology isn't very good and requires CPU level TLB virtualization support for decent performance, which most CPUs don't have.)</span></p>
<p><span style="font-size: x-small;">Fortunately, the software rendering inside WPF is pretty good, so the easy fix here is to force WPF to ignore the GPU and use software rendering (I've tested this on my own system, and I found that WPF's software rendering was actually <span style="text-decoration: underline;">slightly</span> faster than GPU based rendering on my high end CPU with a mid-range graphics card - your mileage may vary).</span></p>
<p><span style="font-size: x-small;">But first, if you're seeing slow / broken screen updates you should verify you have the latest display drivers for your system.&nbsp; (See "</span><a href="https://support.microsoft.com/kb/963021"><span style="font-size: x-small;">Guidelines for troubleshooting graphics issues in WPF applications</span></a><span style="font-size: x-small;">" for more information.)</span></p>
<p><span style="font-size: x-small;">If that doesn't fix it, then there are three ways to force WPF to use software rendering.&nbsp; </span></p>
<p><span style="font-size: x-small;">First and preferred, the final RTM version of VS2010 includes a <a href="https://support.microsoft.com/kb/2023207">UI for forcing hardware rendering off</a> - for just VS.&nbsp; With VS2010 open, go to Tools | Options, then select Environment | General (as shown below).&nbsp; Then uncheck "Automatically adjust visual experience..." and "Use hardware graphics acceleration..."&nbsp; </span></p>
<p><span style="font-size: x-small;">&nbsp;<img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/00/79/0513.Turn%20off%20HW%20acceleration.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-00-79/0513.Turn-off-HW-acceleration.png" border="0" /></span></p>
<p><span style="font-size: x-small;">That should be sufficient.&nbsp; </span></p>
<p><span style="font-size: x-small;">However, if you want to </span><span style="font-size: x-small;">force software rendering mode for ALL WPF applications (not just VS), you have a second option.&nbsp; Change (or add) one registry key:</span></p>
<p><span style="font-size: x-small;">&nbsp;[HKEY_CURRENT_USER\Software\Microsoft\Avalon.Graphics]</span></p>
<p><span style="font-size: x-small;">"DisableHWAcceleration"=dword:00000001</span></p>
<p><span style="font-size: x-small;">Note that this key probably won't exist, and you'll probably need to create it.&nbsp; To turn hardware acceleration back on, just change the "1" to a "0".</span></p>
<p><span style="font-size: x-small;">A third alternative is to adjust the hardware acceleration options from the display control panel.&nbsp; However, we don't recommend this option as it impacts the entire machine, the details vary by manufacturer, and the exact impact of all the different options is untested.</span></p>
<p><span style="font-size: x-small;">If you try any of these - let us know how it works for you (</span><a href="mailto:DevPerf@Microsoft.com"><span style="font-size: x-small;">DevPerf@Microsoft.com</span></a><span style="font-size: x-small;">).&nbsp; If it does improve performance, be sure to let us know how much and attach a DXDIAG output so we'll know which video driver / hardware configurations aren't working well.</span></p>
<p><span style="font-size: x-small;">Regards,</span></p>
<p><span style="font-size: x-small;">David Berg</span></p>
<p><span style="font-size: x-small;">Developer Division Performance Engineering Team</span></p>]]></content:encoded>
    </item>
    <item>
      <title>Visual Studio 2010 runs faster when the Windows Automation API 3.0 is installed</title>
      <link>https://docs.microsoft.com/archive/blogs/ddperf/visual-studio-2010-runs-faster-when-the-windows-automation-api-3-0-is-installed</link>
      <pubDate>Mon, 16 Aug 2010 06:08:34 GMT</pubDate>
      <dc:creator><![CDATA[David Berg]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ddperf/2010/08/16/visual-studio-2010-runs-faster-when-the-windows-automation-api-3-0-is-installed/</guid>
      <description><![CDATA[If you're running Visual Studio 2010 on XP or Vista you may benefit from installing this upgrade:...]]></description>
      <content:encoded><![CDATA[<p>If you're running Visual Studio 2010 on XP or Vista you may benefit from installing this upgrade: <a href="https://support.microsoft.com/kb/981741">https://support.microsoft.com/kb/981741</a></p>
<p style="padding-left: 30px;">Applications that use Windows Automation APIs can significantly decrease Microsoft Visual Studio IntelliSense performance if Windows Automation API 3.0 is not installed. For example, the Windows pen and touch services can significantly decrease Visual Studio IntelliSense performance if Windows Automation API 3.0 is not installed. This article describes how to install the Windows Automation API 3.0 update. This update is available as a stand-alone download for 32-bit editions of Windows XP and for Windows Server 2003. This update is not available for 64-bit editions of Windows XP. The Windows Automation API is a component of the platform update for Windows Vista and of the platform update for Windows Server 2008. </p>
<p>Note that if you're running Windows XP SP2 you'll be told the patch isn't applicable, that's because you need to upgrade to XP SP3 first.&nbsp; If you're running Vista or Windows Server 2008 you may already have the upgrade, since it's part of the automatic updates.&nbsp; If not you can download the upgrade at the link above.&nbsp; Windows 7 and Windows Server 2008 R2 ships with with Windows Automation API 3.0, so no upgrade is required.</p>
<p>The problem is that earlier versions of the Windows Automation API try to read the entire contents of list boxes that we post to the screen, which blocks us from virualizing them.&nbsp; This is particularly a problem with intellisense as the number of items in an intellisense list is HUGE and it pops up on every character you type.</p>
<p>The API is typically activated when using accessibility devices (such as screen readers), pen / tablet computers,&nbsp;or touch devices, but some software activates it anyway (including iPhone synchronization).&nbsp; Once activated it affects the entire system.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Are you a candidate to run Visual Studio 2010 on a 64-bit OS?</title>
      <link>https://docs.microsoft.com/archive/blogs/ddperf/are-you-a-candidate-to-run-visual-studio-2010-on-a-64-bit-os</link>
      <pubDate>Thu, 29 Apr 2010 00:56:00 GMT</pubDate>
      <dc:creator><![CDATA[David Berg]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ddperf/2010/04/29/are-you-a-candidate-to-run-visual-studio-2010-on-a-64-bit-os/</guid>
      <description><![CDATA[Brian Harry's just posted an article on configuring an ideal Visual Studio development...]]></description>
      <content:encoded><![CDATA[<P>Brian Harry's just posted an article on configuring an ideal Visual Studio development machine.&nbsp; You can read about it here: <A href="https://blogs.msdn.com/bharry/archive/2010/04/29/your-visual-studio-2010-dream-machine.aspx" mce_href="https://blogs.msdn.com/bharry/archive/2010/04/29/your-visual-studio-2010-dream-machine.aspx">https://blogs.msdn.com/bharry/archive/2010/04/29/your-visual-studio-2010-dream-machine.aspx</A>. By the way, if you scroll down and peruse the comments that customers have posted there, you will see recommendations for several other configuration options. Some of these go well beyond the simpler &amp; less expensive ones Brian discussed. If you rely on Visual Studio in your daily work, you may want to give serious consideration to some of these advanced configuration options.</P>
<P><FONT size=3><FONT face=Calibri>One of topics Brian addresses in his blog was the benefit of running Visual Studio on a 64-bit OS. We’d like to drill into that topic a little deeper in this post.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p><FONT size=3><FONT face=Calibri>Visual Studio’s devenv.exe process still runs as a 32-bit process. Under a 32-bit OS, a 32-bit process can only address up to 2 GB of private virtual memory. (For the sake of simplicity, we are going to ignore the <B style="mso-bidi-font-weight: normal">/3 GB</B> boot option for 32-bit Windows machines.) The remaining 2 GB of the 4 GB virtual address space is reserved for system addresses. This 2 GB max is an architectural limit on the size of a 32-bit process. All the code and data that gets loaded has to fit in this 2 GB virtual memory space. This may seem a little strange, but as developers working on Visual Studio, but we consider your code – and forms, XAML, DBML, DGML, PDBs for debugging, TFS Work items, and whatever else your Solution loads – as the data Visual Studio has to load &amp; process. The problem arises when Visual Studio needs to load some combination of our code and your data that exceeds this 2 GB architectural limit.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Actually, memory fragmentation issues prevent a 32-bit process like devenv.exe from ever reaching its 2 GB architectural limit. Due to fragmentation, when a 32-bit process address space starts to grow into the 1.7 – 1.8 GB range, the risk that a virtual memory allocation request will fail starts to increase sharply. When a virtual memory allocation request fails, Visual Studio encounters an End of Memory error and crashes. <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Obviously, this is a scenario you want to avoid. The cleanest way to get around the problem is to run Visual Studio on a 64-bit OS. On a 64-bit version of Windows, the private area of a 32-bit process expands to encompass the full 4 GB virtual memory addressing range. Due to fragmentation, you can’t quite get to the 4 GB upper limit either, but the effect of the change is to allow devenv.exe to address twice as much private virtual memory. Please don’t take this as a challenge, but&nbsp;we have yet to see a customer scenario that exhausts the full 4 GB address range. <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>So, if you think you could be a good candidate for running Visual Studio 2010 under a 64-bit OS, here is what to look for.&nbsp;We will run through a scenario we ran recently on the final RTM version of Visual Studio 2010 Ultimate. The test project is a smallish Web solution with a handful of simple ASP.NET Pages that use LINQ to query the MS SQL Server AdventureWorks demo database. This is a version of an app&nbsp;one of us&nbsp;built last year originally for stress testing some Visual Studio components he was working on. We would characterize this app as “borderline realistic.” For example, the AdventureWorks database has fifty or so inter-related Tables, and its SaleOrderDetail Table contains in excess of 120,000 rows. So it is not a trivial “Hello World” type of app, but the web forms themselves are pretty basic, lacking many of the UI components that you are likely to put into a real-world e-commerce application. <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3 face=Calibri>Table 1 shows the main steps in my test scenario and the amount of virtual memory Visual Studio consumed at the end of end of each step. The tool&nbsp;we recommend for measuring virtual memory usage at the process level is </FONT><A href="https://technet.microsoft.com/en-us/sysinternals/dd535533.aspx"><FONT color=#0000ff size=3 face=Calibri>VMMap</FONT></A><FONT size=3><FONT face=Calibri>, one of the free Sysinternals utilities. With VMMap, I can see the overall virtual memory usage of the devenv.exe process, broken down according to different types of allocations, which is something&nbsp;we will drill into in a moment.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Here is a summary of the steps of the scenario&nbsp;we ran and the amount of virtual memory allocated by the devenv.exe process at the end of each step.<o:p></o:p></FONT></FONT></P>
<P mce_keep="true">
<TABLE style="BORDER-COLLAPSE: collapse; mso-yfti-tbllook: 1184; mso-padding-alt: 0in 0in 0in 0in" class=MsoNormalTable border=0 cellSpacing=0 cellPadding=0 class="MsoNormalTable">
<TBODY>
<TR style="mso-yfti-irow: 0; mso-yfti-firstrow: yes">
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: black 1pt solid; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 45.9pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=61>
<P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center><SPAN style="FONT-SIZE: 12pt"><FONT face=Calibri>Step<o:p></o:p></FONT></SPAN></P></TD>
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 369pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=492>
<P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center><SPAN style="FONT-SIZE: 12pt"><FONT face=Calibri>Scenario<o:p></o:p></FONT></SPAN></P></TD>
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 63.9pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=85>
<P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center><SPAN style="FONT-SIZE: 12pt"><FONT face=Calibri>VM Usage<o:p></o:p></FONT></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 1">
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: black 1pt solid; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 45.9pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=61>
<P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center><FONT face=Calibri><FONT size=3>1<o:p></o:p></FONT></FONT></P></TD>
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 369pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=492>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT face=Calibri><FONT size=3>Open VS with empty solution<o:p></o:p></FONT></FONT></P></TD>
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 63.9pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=85>
<P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center><FONT face=Calibri><FONT size=3>300<o:p></o:p></FONT></FONT></P></TD></TR>
<TR style="mso-yfti-irow: 2">
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: black 1pt solid; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 45.9pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=61>
<P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center><FONT face=Calibri><FONT size=3>2<o:p></o:p></FONT></FONT></P></TD>
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 369pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=492>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT face=Calibri><FONT size=3>Open VS with web solution:<o:p></o:p></FONT></FONT></P>
<P style="LINE-HEIGHT: normal; TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-add-space: auto; mso-list: l1 level1 lfo1" class=MsoListParagraphCxSpFirst><SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"><SPAN style="mso-list: Ignore"><FONT size=3>·</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><FONT face=Calibri><FONT size=3>Solution Explorer, Team Explorer, and Server Explorer<o:p></o:p></FONT></FONT></P>
<P style="LINE-HEIGHT: normal; TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-add-space: auto; mso-list: l1 level1 lfo1" class=MsoListParagraphCxSpMiddle><SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"><SPAN style="mso-list: Ignore"><FONT size=3>·</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><FONT face=Calibri><FONT size=3>&nbsp;Connect to TFS<o:p></o:p></FONT></FONT></P>
<P style="LINE-HEIGHT: normal; TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-add-space: auto; mso-list: l1 level1 lfo1" class=MsoListParagraphCxSpMiddle><SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"><SPAN style="mso-list: Ignore"><FONT size=3>·</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><FONT face=Calibri><FONT size=3>Open one .cs file Opened in the VS Editor<o:p></o:p></FONT></FONT></P>
<P style="LINE-HEIGHT: normal; TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-add-space: auto; mso-list: l1 level1 lfo1" class=MsoListParagraphCxSpMiddle><SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"><SPAN style="mso-list: Ignore"><FONT size=3>·</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><FONT face=Calibri><FONT size=3>Open one simple web form opened in Split mode<o:p></o:p></FONT></FONT></P>
<P style="LINE-HEIGHT: normal; TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-add-space: auto; mso-list: l1 level1 lfo1" class=MsoListParagraphCxSpMiddle><SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"><SPAN style="mso-list: Ignore"><FONT size=3>·</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><FONT face=Calibri><FONT size=3>Open one (.dbml) Data Designer <o:p></o:p></FONT></FONT></P>
<P style="LINE-HEIGHT: normal; TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-add-space: auto; mso-list: l1 level1 lfo1" class=MsoListParagraphCxSpLast><SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"><SPAN style="mso-list: Ignore"><FONT size=3>·</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><FONT face=Calibri><FONT size=3>Open one TFS Work Item open<o:p></o:p></FONT></FONT></P></TD>
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 63.9pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=85>
<P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center><FONT face=Calibri><FONT size=3>910<o:p></o:p></FONT></FONT></P></TD></TR>
<TR style="mso-yfti-irow: 3">
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: black 1pt solid; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 45.9pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=61>
<P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center><FONT face=Calibri><FONT size=3>3<o:p></o:p></FONT></FONT></P></TD>
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 369pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=492>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT face=Calibri><FONT size=3>Step 2, plus F5 to Debug Solution, and run to a breakpoint<o:p></o:p></FONT></FONT></P>
<P style="LINE-HEIGHT: normal; TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-add-space: auto; mso-list: l0 level1 lfo2" class=MsoListParagraph><SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"><SPAN style="mso-list: Ignore"><FONT size=3>·</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><FONT size=3><FONT face=Calibri>Intellitrace is active at its low (default) setting<o:p></o:p></FONT></FONT></P></TD>
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 63.9pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=85>
<P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center><FONT size=3><FONT face=Calibri>975<o:p></o:p></FONT></FONT></P></TD></TR>
<TR style="mso-yfti-irow: 4">
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: black 1pt solid; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 45.9pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=61>
<P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center><FONT size=3><FONT face=Calibri>4<o:p></o:p></FONT></FONT></P></TD>
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 369pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=492>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Step 3, run to Breakpoint; plus step 10x and then run to 2<SUP>nd</SUP> Breakpoint<o:p></o:p></FONT></FONT></P></TD>
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 63.9pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=85>
<P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center><FONT size=3><FONT face=Calibri>1060<o:p></o:p></FONT></FONT></P></TD></TR>
<TR style="mso-yfti-irow: 5; mso-yfti-lastrow: yes">
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: black 1pt solid; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 45.9pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=61>
<P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center><FONT size=3><FONT face=Calibri>5<o:p></o:p></FONT></FONT></P></TD>
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 369pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=492>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Step 4, with Resharper installed<o:p></o:p></FONT></FONT></P></TD>
<TD style="BORDER-BOTTOM: black 1pt solid; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 63.9pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: black 1pt solid; PADDING-TOP: 0in" vAlign=top width=85>
<P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center><FONT size=3><FONT face=Calibri>&gt; 1300<o:p></o:p></FONT></FONT></P></TD></TR></TBODY></TABLE></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 9pt"><FONT face=Calibri>Table 1. Virtual memory usage of Visual Studio at the end of each scenario step.<o:p></o:p></FONT></SPAN></B></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>In Step 5,&nbsp;we repeated the full scenario, but this time with Resharper, a popular Visual Studio add-in, installed. As Figure 1 shows, at that point, the virtual memory footprint of Visual Studio 2010 exceeds 1.3 GB. Committed bytes exceeds 1.2 GB. While that is not a particularly dangerous amount of virtual memory for Visual Studio to consume, it is still enough to start to make you wary. <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;<IMG style="WIDTH: 531px; HEIGHT: 363px" title="VMMap screen shot of VS 2010" alt="VMMap screen shot of VS 2010" align=left src="https://rtsdpg.bay.livefilestore.com/y1pGdYZF0QneXOC46VEipluJdVwW1bXzhlItJvCdr6yPqwTB1Q4c-iq1v8vjJRE_5hTL2IjmPH6-pl-X1bgfoqa6wnNg-HF4Djl/VS%20vm%20usage%20with%20resharper%20Screen%20Snaper%20Image.jpg" width=531 height=363 mce_src="https://rtsdpg.bay.livefilestore.com/y1pGdYZF0QneXOC46VEipluJdVwW1bXzhlItJvCdr6yPqwTB1Q4c-iq1v8vjJRE_5hTL2IjmPH6-pl-X1bgfoqa6wnNg-HF4Djl/VS%20vm%20usage%20with%20resharper%20Screen%20Snaper%20Image.jpg"></FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P><o:p><FONT face=Calibri><FONT size=3>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 9pt"></SPAN></B>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 9pt"></SPAN></B>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 9pt"></SPAN></B>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 9pt"></SPAN></B>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 9pt">Figure 1. VMMAP report on Visual Studio’s virtual memory usage for Step 5 in the scenario.&nbsp; (<A title="VMMap report for Visual Studio's devenv process" href="https://rtsdpg.bay.livefilestore.com/y1pGdYZF0QneXOC46VEipluJdVwW1bXzhlItJvCdr6yPqwTB1Q4c-iq1v8vjJRE_5hTL2IjmPH6-pl-X1bgfoqa6wnNg-HF4Djl/VS%20vm%20usage%20with%20resharper%20Screen%20Snaper%20Image.jpg" target=_blank mce_href="https://rtsdpg.bay.livefilestore.com/y1pGdYZF0QneXOC46VEipluJdVwW1bXzhlItJvCdr6yPqwTB1Q4c-iq1v8vjJRE_5hTL2IjmPH6-pl-X1bgfoqa6wnNg-HF4Djl/VS%20vm%20usage%20with%20resharper%20Screen%20Snaper%20Image.jpg">Click</A> for full size image.)</SPAN></B></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 9pt"></SPAN></B>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 9pt"></SPAN></B></FONT><FONT size=3>From the standpoint of Visual Studio responsiveness, it is worth noting that the high water mark for the devenv.exe working set was just under 600 MB in Step 5. So this is a scenario that can still readily fit in a machine with the minimum of 1 GB of RAM, and should perform quite well on a machine with 2 GB of RAM.<o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3>Drilling into the virtual memory footprint using the VMMap report shown in Figure 1, we see that the largest single contributor is Images files, code that Visual Studio is loading. For the scenario in step 5, Visual Studio needs to load 775 MB of executable code.&nbsp;we zoomed the VMMap detail report into the Image data and then sorted by Image file size. You can see that many of the image files that Visual Studio loads are quite large, in excess of 10 MB. Meanwhile, private data areas accounted for only about 220 MB of virtual.<o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3>One thing about the Image files that get loaded<SPAN style="COLOR: #1f497d"> </SPAN>in Visual Studio, the more components of the IDE you use, the more code gets loaded. And once loaded, Visual Studio does not have a mechanism to unload components that you are no longer using. The Image File footprint just keeps on growing throughout your Visual Studio session. <o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3>So, take this simple scenario and apply it to a very large project or solution and exercise a few more Visual Studio components like architectural diagrams and performance profiling, and you may quickly be up against the architectural limit of a 2 GB private process virtual address space. As Visual Studio virtual memory usage approaches that limit, the product becomes unstable on a 32-bit OS.<o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3>As Brian’s blog discusses, to avoid possible instability problems, the workaround is to install and run Visual Studio on a 64-bit version of the OS. Hopefully, this discussion will help you understand better whether you are a good candidate to run Visual Studio on a 64-bit version of the OS. Running VMMap to gain a more detailed look at Visual Studio’s virtual memory usage in your specific environment can also be useful.</FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3></FONT>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3>-- David Berg and Mark Friedman<o:p>&nbsp;</o:p></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><o:p>posted May 3, 2010</o:p></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal></FONT></o:p>&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>Measuring Processor Utilization and Queuing Delays in Windows applications</title>
      <link>https://docs.microsoft.com/archive/blogs/ddperf/measuring-processor-utilization-and-queuing-delays-in-windows-applications</link>
      <pubDate>Sun, 04 Apr 2010 11:20:00 GMT</pubDate>
      <dc:creator><![CDATA[Mark B Friedman]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ddperf/2010/04/04/measuring-processor-utilization-and-queuing-delays-in-windows-applications/</guid>
      <description><![CDATA[Continuing my answer to the mail I received recently from Uriel Carrasquilla… 
Uri’s note,...]]></description>
      <content:encoded><![CDATA[<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>Continuing my answer to the mail I received recently from Uriel Carrasquilla… <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3 face=Calibri>Uri’s note, reprinted in the previous </FONT><A href="https://blogs.msdn.com/ddperf/archive/2010/01/27/statistical-process-control-techniques-in-performance-monitoring-and-alerting.aspx" mce_href="https://blogs.msdn.com/ddperf/archive/2010/01/27/statistical-process-control-techniques-in-performance-monitoring-and-alerting.aspx"><FONT size=3 face=Calibri>post</FONT></A><FONT face=Calibri><FONT size=3>, refers to an "issue" associated with the current technique for measuring processor utilization in Windows. As my reply mentioned, these are documented and well-understood issues. At the core is the methodology used to calculate processor utilization that was originally designed 20 years ago for Windows NT. Since one of the original goals of Windows NT was to be hardware independent, the measurement methodology was also designed so that it was not dependent on any specific set of hardware measurement features. And therein lies a tale.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>This methodology was amply documented in my <I style="mso-bidi-font-style: normal">Windows 2003 Server Performance Guide</I>, published in the Windows 2003 Server Resource Kit. As you know, I wrote that book before I came to work at Microsoft as a full-time employee, but the Windows Server performance team that helped me at the time was quite open to documenting the existing facility, warts and all.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3 face=Calibri>Briefly summarizing what I wrote there (and which still applies today), the % Processor Time counters in Windows are measurements derived using a sampling technique. The OS Scheduler samples the state of the CPU once per system clock tick, driven by a high priority timer-based interrupt. Currently, the clock tick interval the OS Scheduler uses is usually 15.6 ms. (The precise value that the OS uses between timer interrupts is available by calling <SPAN style="mso-spacerun: yes">&nbsp;</SPAN>the </FONT><A href="https://msdn.microsoft.com/en-us/library/ms724394(VS.85).aspx%20" mce_href="https://msdn.microsoft.com/en-us/library/ms724394(VS.85).aspx%20"><FONT color=#0000ff size=3 face=Calibri>GetSystemTimeAdjustment()</FONT></A><FONT face=Calibri><FONT size=3> function.) If the processor is running the Idle loop when the quantum interrupt occurs, it is recorded as an Idle Time sample. If the processor is running some application thread, that is recorded as a busy sample. Busy samples are accumulated continuously at both the thread and process level. When a clock interrupt occurs, the Scheduler performs a number of other tasks, including adjusting the dispatching priority of threads that are currently executing, stopping the progress of any thread that has exceeded its time slice, as well as performing its CPU accounting. <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>The <I style="mso-bidi-font-style: normal">System\Processor Queue Length</I> counter in Perfmon is an <I style="mso-bidi-font-style: normal">instantaneous</I> counter that reflects the current number of Ready threads waiting in the OS Scheduler queue. When a performance monitoring application such as Perfmon requests the Processor Queue counter, there is a measurement function that traverses the Scheduler Ready Queue and counts the number of threads waiting for an available processor. Thus, the <I style="mso-bidi-font-style: normal">System\Processor Queue Length</I> counter represents one sampled observation, and needs to be interpreted with that in mind. (If memory serves, the data collection process that Charles’ analysis relies upon gathers samples of this measurement several times per minute, &amp; his servers are not idle by design. Which basically means I think what he is doing is just fine.)<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>What I believe Uri is referring to with regard to this processor Queue Length metric not being “correct” is anomalies in this measurement that are due to the kind of phased behavior you can sometimes see on an otherwise idle system. Even on an mostly idle system, a sizable number of threads can be waiting on the same clock interrupt (typically, polling the system state once per second), one of which also happens to be the Perfmon measurement thread, also cycling once per second. These sleeping threads tend to clump together so that they get woken up <I style="mso-bidi-font-style: normal">at the exact same time</I> by the timer interrupt. (As I mentioned, this happens mainly when the machine is idling with little or no real work to do.) These awakened threads then flood the OS dispatching queue at exactly the same time. If one of these threads is the Perfmon measurement thread that gathers the Processor Queue Length measurement, you can see how this “clumping” behavior could distort the measurements. The Perfmon measurement thread executes at an elevated priority level of 15, so it is scheduled for execution ahead of any other User mode threads that were also awakened by the same Scheduler clock tick. The effect is that at the precise time when the Processor ready queue length is measured, there are likely to be a fair number of Ready Threads. Compared to the modeling assumption where processor scheduling is subject to random arrivals, one observes a disproportionate number of Ready Threads waiting for service, even (or especially) when the processor itself is not very busy overall.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>This anomaly is best characterized as a <I style="mso-bidi-font-style: normal">low-utilization effect</I> that perturbs the measurement when the machine is loafing. It generally ceases to be an issue when processor utilization climbs or there are more available processors on the machine. But this bunching of timer-based interrupts remains a serious concern, for instance, whenever Windows is running as a guest virtual machine under VMware or Hyper-V. (Please don’t get me started on that topic.) <SPAN style="mso-spacerun: yes">&nbsp;</SPAN>Another interesting side discussion is how this clumping of timer-based interrupts interacts with power management, but I do not intend to go there either.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>To summarize, the CPU utilization measurements at the system, process and thread level in Windows are based on a sampling methodology. Similarly, the processor queue length is also sampled. Like any sampling approach, the data gathered is subject to typical sampling errors, including <o:p></o:p></FONT></FONT></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class=MsoListParagraphCxSpFirst><SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"><SPAN style="mso-list: Ignore"><FONT size=3>·</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><FONT face=Calibri><FONT size=3>accumulating a sufficient number of sample observations to be able to make a reliable statistical inference about the underlying population, and<o:p></o:p></FONT></FONT></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 10pt 0.5in; mso-list: l0 level1 lfo1" class=MsoListParagraphCxSpLast><SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"><SPAN style="mso-list: Ignore"><FONT size=3>·</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><FONT size=3><FONT face=Calibri>ensuring that there aren’t systemic sources of sampling error that causes sub-classes of the underlying population to be under or over-sampled markedly <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3><FONT face=Calibri>So, these CPU measurements face familiar issues with sampling size and the potential for systematic sampling bias, as well as the usual difficulty in ensuring that the sample data is <I style="mso-bidi-font-style: normal">representative</I> of the underlying population (something known as <I style="mso-bidi-font-style: normal">non-sampling error</I>). For example, the interpretation of the CPU utilization data that Perfmon gathers at the process and thread level is subject to limitations based on a small sample size for collection intervals less than, for example, 15 seconds. The <I style="mso-bidi-font-style: normal">Performance Guide</I> has a more detailed discussion of these issues, if you are interested.</FONT></FONT></P><FONT size=3 face=Calibri></FONT><FONT face=Calibri><o:p>
<H3 style="MARGIN: 10pt 0in 0pt"><FONT color=#4f81bd><FONT face=Cambria><FONT size=3>Event-driven measurement approaches.<o:p></o:p></FONT></FONT></FONT></H3>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>What exactly Windows is going to do about this, I couldn't say -- I work in a different part of the company -- but I have consistently lobbied for a more accurate, event-driven approach to gathering CPU measurements. Efficient power management, for example, strongly argues for an event-driven approach. You do not want the OS to wake up periodically on an idle machine that could otherwise be powered down just to perform its CPU usage accounting duties, for example. <o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>It is encouraging that recent versions of Windows have taken major steps in this direction, supporting a more accurate event-driven approach using instrumentation added to the Scheduler to measure CPU utilization. The improvements in this area have not gotten much notice, which is something I will try to rectify a bit here. Windows exploits a machine timing facility that is present in both x86 and x64 hardware, namely, the <B style="mso-bidi-font-weight: normal">rdtsc</B> Read TimeStamp Counter instruction. Moreover, these improvements position the Windows OS so it can replace its legacy CPU measurement facility with something more reliable and accurate sometime in the near future. Unfortunately, converting all existing features in Windows, including Perfmon and Task Manager, to support the new measurements is a big job, not without its complications and not always as straightforward as one would hope. (One of the complications is using <B style="mso-bidi-font-weight: normal">rdtsc</B> on older hardware where the hardware tick rate changes when there is a power management event. There are also issues of clock drift across multiprocessor cores when they are not re-synchronized periodically. I do not want to take the time to discuss these issues in detail here.)<o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>To see this new processor measurement facility at work, access the new Resource Monitor application (resmon.exe) that is available beginning in Vista and Windows Server 2008. Resource Monitor can be launched directly from the command line, or from either Performance Monitor or Task Manager. In case you are not familiar with it, here is a screen shot that shows Resource Monitor in action on a Windows Server 2008 R2 machine, calculating CPU utilization over the last 60 seconds of operation, breaking out that utilization by process. The CPU utilization measurements that ResMon calculates are based on new OS Scheduler instrumentation. These measurements are very accurate, about as good as it gets from a vantage point inside the OS.<o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true"><IMG style="WIDTH: 402px; HEIGHT: 302px" title="Windows Resource Monitor" alt="Windows Resource Monitor" align=left src="https://5l3vgw.bay.livefilestore.com/y1pX1wNrsIvjzPmgE1gAtYmHpWhyV51wumpGCzUzdb1hVKHtsSIMsvqf1LAaymfwIr8WhHs612ZOfbnAc_zwq4MHRNI1EIGW7ug/Win7%20Resource%20Monitor.jpg" width=402 height=302 mce_src="https://5l3vgw.bay.livefilestore.com/y1pX1wNrsIvjzPmgE1gAtYmHpWhyV51wumpGCzUzdb1hVKHtsSIMsvqf1LAaymfwIr8WhHs612ZOfbnAc_zwq4MHRNI1EIGW7ug/Win7%20Resource%20Monitor.jpg"></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3></FONT>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3></FONT>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3></FONT>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3></FONT>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3></FONT>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3></FONT>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3></FONT>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3></FONT>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3></FONT>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3></FONT>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3><STRONG><FONT size=2>Figure 1. The Windows 7 Resource Manager application.&nbsp; (<A title="Windows Resource Manager" href="https://public.bay.livefilestore.com/y1pmGNsLRE7KXC71flyu1tDbdviKnxOsXXi4gjqrnPoelib2crxOBZa-nLKVN7LyRX7GZoevqdD1wcHt3_ZwnhNUQ/Win7%20Resource%20Monitor.jpg" target=_blank mce_href="https://public.bay.livefilestore.com/y1pmGNsLRE7KXC71flyu1tDbdviKnxOsXXi4gjqrnPoelib2crxOBZa-nLKVN7LyRX7GZoevqdD1wcHt3_ZwnhNUQ/Win7%20Resource%20Monitor.jpg">Click</A> for full size image.)<o:p></o:p></FONT></STRONG></FONT></P><FONT size=3><FONT size=2><o:p>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>The Resource Monitor measures CPU busy in real time using event-orient measurement data gathered by the OS Scheduler each time a context switch occurs. A context switch occurs in Windows whenever the processor switches the processor execution context to run a different thread. Context switches also occur as a result of high priority Interrupt Service Routines (ISRs), as well as the Deferred Procedure Calls (DPCs) that ISRs schedule to complete the interrupt processing. Starting in Windows 6, the OS Scheduler began issuing </FONT><FONT size=3><STRONG>rdtsc</STRONG> instructions to get the internal processor clock each time a context switch occurs. (Note: The Windows OS Scheduler not only orders ready threads in its dispatcher queue by priority, it also lets a higher priority thread preemptively interrupt the execution of a lower priority one. This is known as <I style="mso-bidi-font-style: normal">Preemptive Scheduling with Priority Queuing</I>. Once executing, a thread is also subject to a maximum time-slice interval, sometimes referred to as the <I style="mso-bidi-font-style: normal">quantum</I>. When the Scheduler determines that a thread’s time-slice has expired, the thread is also subject to preemption in favor of another thread from the ready queue of equal priority.</FONT><SPAN style="LINE-HEIGHT: 115%; FONT-SIZE: 9pt; mso-bidi-font-size: 11.0pt">) </SPAN><FONT size=3><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>Meanwhile, the hardware manufacturers have improved the performance of the <STRONG>rdtsc</STRONG> instruction, making it considerably more efficient for the Scheduler to gather these processor utilization measurements. <o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>You will notice in the example screen shot shown here in Figure 1 that Resource Manager has calculated that System Interrupts (from ISR and DPC routines) accounts for most of the processor utilization during the last 60 second interval. The machine being monitored is mainly doing file I/O, so this is expected. Although the Resource Monitor display doesn’t say so explicitly, it is worth noting that this is all work being performed in kernel mode.<o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>Conceptually, a context switch event is something like <STRONG>switch</STRONG>(<I style="mso-bidi-font-style: normal">oldThreadId,</I> <I style="mso-bidi-font-style: normal">newThreadId</I>), with an <STRONG>rdtsc</STRONG> time stamp identifying when the context switch occurred. The Context Switch event also provides the old thread’s Wait Reason code, which helps you to understand why the sequence of thread scheduling events occurred. For reference, a Windows context switch is defined </FONT><A href="https://msdn.microsoft.com/en-us/library/ms682105(VS.85).aspx"><FONT color=#0000ff size=3>here</FONT></A><FONT size=3>, while the contents of the ETW (Event Tracing for Windows) context switch event record are defined </FONT><A href="https://msdn.microsoft.com/en-us/library/aa964744(VS.85).aspx"><FONT size=3>here</FONT></A><FONT size=3>. Also, see the series of articles by Insung Park and Alex Bendetov that were published in MSDN Magazine entitled “<A href="https://msdn.microsoft.com/en-us/magazine/ee412263.aspx"><SPAN style="COLOR: windowtext; TEXT-DECORATION: none; text-underline: none"><FONT size=3>Core OS Events in Windows 7</FONT></SPAN></A><FONT size=3>” for additional background and perspective. <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>(Note: You have to hunt a bit to find the current values of the KWait_Reason enumeration. Officially, the KWait_Reason enumeration is published in the Wdm.h header file available in the Windows Driver Kit (WDK). Unfortunately, in MSDN, ordinarily the most authoritative places to find something like this, the available documentation tends to lag recent releases of Windows. For instance, the version of the enum provided to the .NET developer available here is considerably out of date. The explain text in Perfmon for the Thread\Thread Wait Reason counter is also not current. If you do not have access to the WDK, try either ProcessHacker or NirSoft instead for more up-to-date documentation.) </FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>The same calculation that the Resource Manager in Windows 7 uses can be performed after the fact using event data from ETW. In their article, Insung and Alex write, “In state machine construction, combining Context Switch, DPC and ISR events enables a very accurate accounting of CPU utilization.” This is the technique used in the </FONT><A href="https://msdn.microsoft.com/en-us/performance/default.aspx"><FONT color=#0000ff size=3>Windows Performance Toolkit</FONT></A><FONT size=3> (WPT, which is also known as xperf), for example, to calculate its CPU utilization statistics. (For reference, there is a discussion that illustrates using the WPT to analyze ISR and DPC event data in a previous blog entry entitled “Mainstream NUMA and the TCP/IP stack” posted </FONT><A href="https://blogs.msdn.com/ddperf/archive/2008/06/10/mainstream-numa-and-the-tcp-ip-stack-part-i.aspx"><FONT color=#0000ff size=3>here</FONT></A><FONT size=3>.)<o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>The new Concurrency Visualizer, which my colleague Hazim Shafi discusses in </FONT><A href="https://msdn.microsoft.com/en-us/magazine/ee336027.aspx"><FONT color=#0000ff size=3>a recent MSDN Magazine article </FONT></A><FONT size=3>entitled “Performance Tuning with the Concurrency Visualizer in Visual Studio 2010 in the Visual Studio 2010 Profiler”, also consumes Context Switch events to calculate processor utilization for the application being profiled. An interesting twist in the Concurrency Visualizer’s CPU Utilization View is that the view pivots based on the application you are profiling, which is likely how a developer engaged in a performance investigation wants to see things. Based on the sequence of context switch trace events, the Concurrency Visualizer calculates processor utilization by the process, aggregates it for the current selection window, and displays it in the CPU Utilization View. In the CPU Utilization View, all other processor activity for processes (other than one being profiled) is lumped together under a category called “Other Processes.” System-processes and the “Idle process,” which is a bookkeeping mechanism, not an actual process that is dispatched, are also broken out separately. See Hazim’s article for more details. <o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>Beyond its CPU utilization calculations, the Concurrency Visualizer’s primary focus is on being able to reconstruct the sequence of events that impact an application’s execution progress. The Concurrency Visualizer’s Threads View is the main display showing an application’s execution path. The view here is of execution progress on a thread by thread basis. For each thread in your application, the Concurrency Visualizer shows the precise sequence of context switch events that occurred. These OS Scheduler events reflect that thread’s execution state. See Figure 2 for an example of this view.<o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>Figure 2 shows the execution path of six application threads, a Main thread, a generic worker thread, and 4 CLR worker threads that the application created by instantiating a </FONT><A href="https://msdn.microsoft.com/en-us/library/3dasc8as(VS.100).aspx"><FONT size=3>ThreadPool</FONT></A><FONT size=3> object. (There were originally more threads than this, but I have hidden some that were inactive over the entire run.) For each thread, the execution state of the thread – whether it is running or whether it is blocked –is indicated over time. The upper part of the display is a timeline that shows the execution state of each thread over time. The execution progress of each thread display is constructed horizontally from left to right from rectangles that indicate the start and end of a particular thread state. An interval when the thread was running shows as green. An interval where the thread is sleeping is shown in blue. A ready thread that is blocked from executing because a higher priority thread is running is shown in yellow. (This state is labeled “preemption.”) A thread in a synchronization delay waiting on a lock is shown as red.<o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>On the lower left of the display is a Visible Timeline Profile. This summarizes the state of all threads that are visible within the selected time window. In the screen shot in Figure 2, I have zoomed into a window that is approximately 150 milliseconds wide. During that interval, the threads shown were in a state where they were actively executing instruction only 11% of the time. For 25% of the time interval, threads were blocked waiting on a lock. There is a tabbed display at the lower right. If you click on the “Profile Report” tab, a histogram displays that summarizes the execution state of each individual thread over the time window. In the screen shot, I have clicked on the “Current stack,” which displays the call stack associated with the ETW context switch event. If the thread is blocked, the call stack indicates where in the code the thread will resume execution once it unblocks. We will drill into that call stack in a moment.<o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>Note: The Threads View also displays call stacks from processor utilization samples that ETW gathers on a system-wide basis once per millisecond. These are available during any periods when the thread is executing instructions (and ETW execution sampling is active).<o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>One of the other ETW events that the Concurrency Visualizer analyzes is the </FONT><A href="https://msdn.microsoft.com/en-us/library/dd765158(VS.85).aspx"><FONT size=3>ReadyThread</FONT></A><FONT size=3> event. The interval between a ReadyThread event and a subsequent Context Switch that signals that a ready Thread is being dispatched measures CPU queue time delay directly. Using event data, it is possible to measure CPU queuing delays to a degree of precision that far exceeds anything that can be done using performance counters.<o:p></o:p></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3>The Concurrency Visualizer screen shot in Figure 2 illustrates the calculation of CPU queue time delay. <SPAN style="mso-spacerun: yes">&nbsp;</SPAN>Thread 6920, which happens to be a CLR thread pool worker thread, is shown at a point in time where it was preempted by a higher priority task. The specific delay that I zoomed in on in the screen shot is preemption due to the scheduling of a high priority LPC or ISR – note this category also encompasses assorted APCs and DPCs. In this specific example, execution of Thread 6920 was delayed for 0.7718 milliseconds. According to the trace, that is the amount of time between Thread 6920 being preempted by a high priority system routine and a subsequent context switch where the ready thread was finally re-dispatched. </FONT></o:p></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"><IMG style="WIDTH: 491px; HEIGHT: 413px" title="Thread 6920 preempted by an ISR" alt="Thread 6920 preempted by an ISR" align=left src="https://public.bay.livefilestore.com/y1psA60dtVg4Nh_gGSu9X72_Y7sgeRdJKr_37IOLqa11r7AR_ibr5K6zOqkqdGk4op643-na84TRUpksKJZiuSjBg/Concurrency%20visualizer%20screen%20shot%20showing%20preemption%20by%20a%20higher%20priority%20ISS%20or%20DPC%20event.jpg" width=491 height=413 mce_src="https://public.bay.livefilestore.com/y1psA60dtVg4Nh_gGSu9X72_Y7sgeRdJKr_37IOLqa11r7AR_ibr5K6zOqkqdGk4op643-na84TRUpksKJZiuSjBg/Concurrency%20visualizer%20screen%20shot%20showing%20preemption%20by%20a%20higher%20priority%20ISS%20or%20DPC%20event.jpg"></SPAN></FONT></STRONG></P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"></SPAN></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"></SPAN></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"></SPAN></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"></SPAN></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"></SPAN></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"></SPAN></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"></SPAN></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"></SPAN></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"></SPAN></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"></SPAN></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"></SPAN></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"></SPAN></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"></SPAN></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><SPAN style="mso-spacerun: yes"></SPAN></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2></FONT></STRONG>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2>Figure 2. Screen shot of the Concurrency Visualizer illustrating thread preemption by a higher priority system routine.&nbsp; (<A title="Thread 6920 preempted by an ISR" href="https://public.bay.livefilestore.com/y1psA60dtVg4Nh_gGSu9X72_Y7sgeRdJKr_37IOLqa11r7AR_ibr5K6zOqkqdGk4op643-na84TRUpksKJZiuSjBg/Concurrency%20visualizer%20screen%20shot%20showing%20preemption%20by%20a%20higher%20priority%20ISS%20or%20DPC%20event.jpg" target=_blank mce_href="https://public.bay.livefilestore.com/y1psA60dtVg4Nh_gGSu9X72_Y7sgeRdJKr_37IOLqa11r7AR_ibr5K6zOqkqdGk4op643-na84TRUpksKJZiuSjBg/Concurrency%20visualizer%20screen%20shot%20showing%20preemption%20by%20a%20higher%20priority%20ISS%20or%20DPC%20event.jpg">Click</A> for full size image.)<o:p></o:p></FONT></STRONG></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal>The tool also displays the call stack of the preempted thread. The call stack indicates that the CLR’s garbage collector (GC) was running at the time that thread execution was preempted. From the call stack, it looks like the GC is sweeping the Large Object Heap (LOH), trying to free up some previously allocated virtual memory. This is not an opportune time to get preempted. You can see that one of the other CLR worker threads, Thread 6420, is also delayed. Notice from the color coding that Thread 6420 is delayed waiting on a lock. Presumably, one of the other active CLR worker threads in the parent process holds the lock that Thread 6420 is waiting for. <o:p></o:p></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal>This is one of those “Aha” moments. If you click on the synchronization delay that Thread 6420 is experiencing, as illustrated in Figure 3, you can see that the lock that Thread 6420 is trying to acquire is, in fact, currently held by Thread 6920. Clicking on the tab that says “Current Stack” (not shown) indicates that the duration of the synchronization delay that Thread 6420 suffered in this specific instance of lock contention was about 250 milliseconds. <o:p></o:p></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal>The scenario here shows one CLR worker thread blocked on a lock that is held by another CLR worker thread, which in turn finds itself being delayed due to preemptions from higher priority Interrupt processing. We can see that whatever high priority work preempted Thread 6920 has the side effect of also delaying Thread 6420, since 6420 was waiting on a lock that Thread 6920 just happened to be holding at the time. The tool in Figure 3 displays the Unblocking stack from Thread 6920 which shows the original memory allocation from the Dictionary.Resize() method call being satisfied, releasing a global GC lock. When Thread 6920 resumed execution following its preemption, the GC operation completes, releasing the global GC lock. Thread 6920 continues to execute for another 25 microseconds or so, before it is preempted because its time slice expired. Even as Thread 6920 blocks, Thread 6420 continues to wait while a different CLR thread pool thread (4664) begins to execute instead. Finally, after another 25 microseconds delay, Thread 6420 resumes execution. For a brief period both 6420 and 4664 execute in parallel from approximately the 7640 to 7650 microsecond milestones. (However, they are subject to frequent preemptions during that period of overlapped execution.) Welcome to the wonderful world of&nbsp;<I style="mso-bidi-font-style: normal">indeterminancy</I> in concurrent programming.<o:p></o:p></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true"><IMG style="WIDTH: 541px; HEIGHT: 413px" title="Thread 6420 delayed waiting on a lock" alt="Thread 6420 delayed waiting on a lock" align=left src="https://public.bay.livefilestore.com/y1pwyW9xNPqEHc-r2iqHj2NluFVeNqc4-NSgJoJ83e9GzhMlfifaSquwuZHN4qZqWPEhgR5vp5ou6ipEtVsJFO8NA/Concurrency%20visualizer%20screen%20shot%20showing%20a%20different%20thread%20blocked%20by%20a%20GC%20lock%20jpg.jpg" width=541 height=413 mce_src="https://public.bay.livefilestore.com/y1pwyW9xNPqEHc-r2iqHj2NluFVeNqc4-NSgJoJ83e9GzhMlfifaSquwuZHN4qZqWPEhgR5vp5ou6ipEtVsJFO8NA/Concurrency%20visualizer%20screen%20shot%20showing%20a%20different%20thread%20blocked%20by%20a%20GC%20lock%20jpg.jpg"></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true">&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true">&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true">&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true">&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true">&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true">&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true">&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true">&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true">&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true">&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true">&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true">&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal mce_keep="true">&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2>Figure 3. CLR Worker Thread 6420 blocked because it is waiting on a GC lock that happens to be held by Thread 6920, which is subject to preemption by higher priority system routines. (<A title="Thread 6420 delayed waiting on a lock" href="https://public.bay.livefilestore.com/y1pwyW9xNPqEHc-r2iqHj2NluFVeNqc4-NSgJoJ83e9GzhMlfifaSquwuZHN4qZqWPEhgR5vp5ou6ipEtVsJFO8NA/Concurrency%20visualizer%20screen%20shot%20showing%20a%20different%20thread%20blocked%20by%20a%20GC%20lock%20jpg.jpg" target=_blank mce_href="https://public.bay.livefilestore.com/y1pwyW9xNPqEHc-r2iqHj2NluFVeNqc4-NSgJoJ83e9GzhMlfifaSquwuZHN4qZqWPEhgR5vp5ou6ipEtVsJFO8NA/Concurrency%20visualizer%20screen%20shot%20showing%20a%20different%20thread%20blocked%20by%20a%20GC%20lock%20jpg.jpg">Click</A> for full size image.)</FONT></STRONG></P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2><o:p></o:p></FONT></STRONG>&nbsp;I won’t take the time now to go into what this little concurrent CLR thread pool application is doing. Suffice to say that I wrote it to illustrate some of the performance issues developers can face trying to do parallel programming, which is the other topic I have been blogging about. (I should note that the test program puts the worker threads to sleep periodically to simulate synchronous I/O waits.) As I started to run the test app I developed using the Concurrency Visualizer, I was able to see blocking issues like this one where the Common Language Runtime introduced synchronization and locking considerations that are otherwise opaque to the developer. I eventually tweaked the test app into an especially ghoulish version I call the LockNestMonster program to shine an even brighter light on these issues. (More about this later when I resume blogging about concurrent programming in .NET.)<o:p></o:p></P>
<H3 style="MARGIN: 10pt 0in 0pt"><FONT color=#4f81bd><FONT face=Cambria><FONT size=3>Time-slicing. <o:p></o:p></FONT></FONT></FONT></H3>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal>The Concurrency Visualizer also breaks out preemption due to the expiration of a thread’s time-slice, the duration of a time slice being one of the few tuning adjustments available in the OS. For the record, I normally recommend that system administrators <I style="mso-bidi-font-style: normal"><U>not</U></I> fiddle with this tuning knob, unless they have a whole lot of extra time on their hands. (This older <A href="https://support.microsoft.com/kb/111405"><FONT color=#0000ff>KB article</FONT></A> provides some flavor for what is involved.) For those of you that cannot resist the temptation, the <SPAN style="mso-spacerun: yes">&nbsp;</SPAN>Concurrency Visualizer Threads View is the first Windows performance tool that can help you determine if changing the OS default time-slice value is doing your application any good, or harm, for that matter. <o:p></o:p></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal>In Figure 4, I clicked on the large yellow block on the right hand side of the execution time bar graph for Thread 6920 indicating another long delay. As in Figure 3, I have hidden all but the three active CLR thread pool threads. Using a combination of zooming to a point of interest in the event stream and filtering out extraneous threads, Figure 4 shows that the Concurrency Visualizer computes an execution time profile for just those events that are visible in the current window. Overall, the three active CLR worker threads are only able to execute 18% of the time, while they are delayed by synchronization 9% of the time and subject to preemption 39% of the time. (You can click on the Profile Report tab in the lower right portion of the display and see a profile report by thread.) <o:p></o:p></P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption mce_keep="true"><IMG style="WIDTH: 541px; HEIGHT: 413px" title="Time slice quantum expiration" alt="Time slice quantum expiration" src="https://public.bay.livefilestore.com/y1pIUdtMiovFTJ3M9eUrDmJduTMusQTD04M89k_gUT3CcA3oIUDxbEdWNEGt9qkpsdtNY_pvkH94GbvQ1DttYt-_A/Concurrency%20visualizer%20screen%20shot%20showing%20preemption%20due%20to%20quantum%20expiration.jpg" width=541 height=413 mce_src="https://public.bay.livefilestore.com/y1pIUdtMiovFTJ3M9eUrDmJduTMusQTD04M89k_gUT3CcA3oIUDxbEdWNEGt9qkpsdtNY_pvkH94GbvQ1DttYt-_A/Concurrency%20visualizer%20screen%20shot%20showing%20preemption%20due%20to%20quantum%20expiration.jpg"></P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption><STRONG><FONT size=2>Figure 4. Using the Concurrency Visualizer to drill into thread preemption delays. (<A title="Preemption due to quantum time-slice expiration" href="https://public.bay.livefilestore.com/y1pIUdtMiovFTJ3M9eUrDmJduTMusQTD04M89k_gUT3CcA3oIUDxbEdWNEGt9qkpsdtNY_pvkH94GbvQ1DttYt-_A/Concurrency%20visualizer%20screen%20shot%20showing%20preemption%20due%20to%20quantum%20expiration.jpg" target=_blank mce_href="https://public.bay.livefilestore.com/y1pIUdtMiovFTJ3M9eUrDmJduTMusQTD04M89k_gUT3CcA3oIUDxbEdWNEGt9qkpsdtNY_pvkH94GbvQ1DttYt-_A/Concurrency%20visualizer%20screen%20shot%20showing%20preemption%20due%20to%20quantum%20expiration.jpg">Click</A> for full size image.)</FONT></STRONG></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal>At the point indicated in the tool, the time-slice quantum for Thread 6920 expired and the Scheduler preempted the executing thread in favor of some other ready thread. Looking at the visualization, it should be apparent that the ready thread the Scheduler chose to execute next was another CLR thread pool worker thread, namely Thread 4664, which then blocked Thread 6920 from continuing. The tool reports that a <I style="mso-bidi-font-style: normal">context switch</I>(6920, 4664) occurred, and that Thread 6920 was delayed for about 275 milliseconds before it resumed execution as a result of being preempted.<o:p></o:p></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal>As illustrated in this example, the Concurrency Visualizer uses the ETW-based event data from a profiling run to construct a state machine that reflects the precise execution state of each application thread over the time interval being monitored. It goes considerably beyond calculating processor queue time at the thread level. It understands how to weave the sequence of Ready Thread and Context switch events together to create this execution time profile. It summarizes the profiling data, calculating the precise amount time of time each thread is delayed by synchronous IO, page faults (i.e., Memory Management overhead), processor contention, preemption by priority work, and lock contention over the profiling interval. Furthermore, it analyzes the call stacks gathered at each Context Switch event, looking for signatures that identify the specific blocking reason. And, specifically, to help with lock contention issues, which are otherwise often very difficult to identify, it also identifies the thread that ultimately unblocks the thread that was found waiting to acquire a lock. <o:p></o:p></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal>I will discuss another new facility for capturing CPU time accurately at the thread level as your program executes in the next blog post in this series.<o:p></o:p></P>
<P style="MARGIN: 0in 0in 10pt" class=MyCaption mce_keep="true">-- Mark Friedman</P></FONT></o:p></FONT>]]></content:encoded>
    </item>
    <item>
      <title>Statistical Process Control Techniques in Performance Monitoring and Alerting</title>
      <link>https://docs.microsoft.com/archive/blogs/ddperf/statistical-process-control-techniques-in-performance-monitoring-and-alerting</link>
      <pubDate>Tue, 26 Jan 2010 17:31:00 GMT</pubDate>
      <dc:creator><![CDATA[Mark B Friedman]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ddperf/2010/01/26/statistical-process-control-techniques-in-performance-monitoring-and-alerting/</guid>
      <description><![CDATA[Being focused on the upcoming release of Visual Studio 2010 for the past six months or so, I,...]]></description>
      <content:encoded><![CDATA[<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>Being focused on the upcoming release of Visual Studio 2010 for the past six months or so, I, unfortunately, have been neglecting to blog about it. Before I get back to the series of blog posts I started about writing in parallel programming, I thought I’d first answer the mail.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><o:p><FONT size=3 face=Calibri></FONT></o:p>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>Concerning a recent presentation by Charles Loboz, my colleague at Microsoft, at CMG09 in Texas (DEC 2009), Uriel Carrasquilla, a very knowledgeable and resourceful performance analyst at NCCI in Florida, writes, <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3><EM>“Mr. Loboz indicated that the theoretical calculations were based on Windows reporting of CPU busy and CPU queue length. My results indicate that the CPU queue length reported by Microsoft can't be correct.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I found that other CMG researchers came up with the same conclusion.<o:p></o:p></EM></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3><EM>“I used similar ideas for my Linux, AIX and Sun Solaris data as reported by SAR, and Mr. Loboz ideas work like a charm.<o:p></o:p></EM></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3><EM>“Question:<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>are you aware of this problem with Microsoft performance reporting? Is anybody working on this issue?”<o:p></o:p></EM></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>Uri,<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>The short answer is, <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>“The derivation and interpretation of the System\Processor Queue Length performance counter is well-documented in the <I style="mso-bidi-font-style: normal">Windows 2003 Server Performance Guide</I>, published back in the Windows 2003 Server Resource Kit. I believe the Processor Queue Length performance counter continues to be a very useful metric to track, as Charles and his team that is responsible for capacity planning for the many of the Microsoft online properties do.”<o:p></o:p></FONT></FONT></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 10pt 0.5in; mso-list: l0 level1 lfo1" class=MsoListParagraph><SPAN style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore"><FONT size=3>n</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><FONT face=Calibri><FONT size=3>Mark<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>I will post a more expansive answer soon, allowing me to expound a little on a question that gets asked quite frequently, namely, “How are measures of CPU utilization in Windows derived and how can they be interpreted?”<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>First, though, I’d like to mention some of the work Charles Loboz and his team have been doing in the context of capacity planning to support some of the massive applications Microsoft provisions and supports. Consider an application like Hotmail that supports something in the neighborhood of 500 million mailboxes (give or take a couple hundred million) and a customer base that is global in scale. That is an order of magnitude larger than the largest corporate entity responsible for a single e-mail or messaging infrastructure. (My guess is that the largest corporate entity responsible for a single e-mail infrastructure is the US Department of Defense. Although, it might be the US Army instead since the different service branches probably operate separate infrastructures.) Performance monitoring and capacity planning on the scale of Hotmail or Search is certainly unprecedented. Do you think performance and capacity planning are important in an application the size of Hotmail. The answer is, “You bet.” The investment in hardware and power consumption alone justifies the capacity planning effort.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>I had an opportunity to see some of the material that Charles was working on back in the summer &amp; gave him some feedback on measurements and what valid inferences can be drawn from them. I haven’t read the final published version, but, I am certainly in sympathy with the approach he has adopted. (BTW, people like Uri that attended the recent CMG Conference have access to Charles’ paper, but no one else at the moment. As soon as Charles posts it somewhere publicly, I will point this blog entry to it.)<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3 face=Calibri>Although the scale Charles has to deal with is something new, the approach isn’t. I remember I also sent Charles a pointer to Igor Trobin's work, which I believe is very complementary. Igor writes an interesting blog called “</FONT><A href="https://itrubin.blogspot.com/" mce_href="https://itrubin.blogspot.com/"><FONT size=3 face=Calibri>System Management by Exception</FONT></A><FONT size=3 face=Calibri>.” In addition, Jeff Buzen and Annie Shum published a very influential paper on this subject called “MASF: Multivariate Adaptive Statistical Filtering” back in 1995. (Igor’s papers on the subject and the original Buzen and Shum paper are all available at </FONT><A href="https://www.cmg.org/" mce_href="https://www.cmg.org/"><FONT size=3 face=Calibri>www.cmg.org</FONT></A><FONT size=3 face=Calibri>.) My colleague </FONT><A href="https://bezsys.blogspot.com/" mce_href="https://bezsys.blogspot.com/"><FONT size=3 face=Calibri>Boris Zibitsker</FONT></A><FONT face=Calibri><FONT size=3> has also made a substantial contribution to what I consider a very useful approach, namely applying statistical process control (SPC) techniques to mine for gold within the enormous amounts of performance data that IT organizations routinely gather. <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3 face=Calibri>For perspective, Carnegie Mellon’s Software Engineering Institute (SEI) is usually credited with the original application of SPC techniques to software engineering. Len Bass at SEI wrote an excellent book entitled </FONT><A href="https://www.amazon.com/Software-Architecture-Practice-2nd-Bass/dp/0321154959/ref=ntt_at_ep_dpi_1" mce_href="https://www.amazon.com/Software-Architecture-Practice-2nd-Bass/dp/0321154959/ref=ntt_at_ep_dpi_1"><FONT size=3 face=Calibri>Software Architecture in Practice</FONT></A><FONT size=3 face=Calibri> that embraces a broader perspective on quality in software development that I share. Len’s work on software quality metrics is close to my current interests here in Developer Division, especially around the potential value of scenario-driven development processes. (More on scenarios in the next blog post. Len’s submitted to a brief interview on Channel 9 recently that is posted </FONT><A href="https://channel9vip.orcsweb.com/posts/mattdeacon/Talking-Architects-with-Len-Bass/" mce_href="https://channel9vip.orcsweb.com/posts/mattdeacon/Talking-Architects-with-Len-Bass/"><FONT size=3 face=Calibri>here</FONT></A><FONT face=Calibri><FONT size=3>.) <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>Within the application life-cycle, performance, unfortunately, is considered one of the <I style="mso-bidi-font-style: normal">non-functional</I> requirements associated with a system specification, which often means it is relegated to a secondary role during the much of the application life-cycle. In the specification process, getting the business requirements and translating them into system specifications correctly is the most pressing problem for developers of Line of Business applications. Performance is one of those aspects of software quality that often doesn’t get expressed during the software development life cycle until very late in the process when design flaws that lead to scalability problems are very expensive to fix. <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>Len Bass’s suggestion is that the requirements definition of a scenario should include a response time specification that can then be monitored throughout the development life cycle, just like any other set of requirements. That is the approach that we advocate using here in the Microsoft Developer Division for the software products that we built here. In developing Visual Studio 2010, for example, we made major commitments to performance requirements and regularly conduct automated acceptance testing against those requirements. However, you can also see from the many recent blogs on VS 2010 performance coming from the Microsoft Developer Division that we have not exactly gotten this down to a science yet.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>The Len Bass and SEI approach is informed by experience building real-time control systems to fly airplanes, for example, where performance goals absolutely have to be met or the system cannot function as designed. <B style="mso-bidi-font-weight: normal"><SPAN style="mso-spacerun: yes">&nbsp;</SPAN></B>The performance requirements for real-time control systems applications are fundamentally easy to specify. If the computer system doesn’t recognize a condition and respond to it in time, the plane is going to crash. Bass makes the case for that<STRONG> </STRONG>system performance being one of those important Quality Attributes that needs to be addressed at the outset of the development life cycle, beginning with the architectural specification and continuing through the design, development and QA processes, to the delivered software’s operational phase, where it finally becomes the focus of performance analysts and capacity planners like Charles Loboz, Uriel Carrasquilla,&nbsp;and Igor Torbin. <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT face=Calibri><FONT size=3>What if you need to specify performance requirements for your LOB application, but don’t know where to start? Consider these two approaches:<o:p></o:p></FONT></FONT></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 38.55pt; mso-list: l1 level1 lfo2; mso-add-space: auto" class=MsoListParagraphCxSpFirst><SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"><SPAN style="mso-list: Ignore"><FONT size=3>·</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><FONT size=3 face=Calibri>Research in human factors engineering has generated a set of performance requirements for specific types of human-computer interactions in order to promote usability and improve customer satisfaction. </FONT><A href="https://stevenseow.com/" mce_href="https://stevenseow.com/"><FONT size=3 face=Calibri>Steve Seow</FONT></A><FONT size=3 face=Calibri>, another colleague here in Microsoft, has an excellent, concise book on this topic called “</FONT><A href="https://www.amazon.com/Designing-Engineering-Time-Psychology-Perception/dp/0321509188/" mce_href="https://www.amazon.com/Designing-Engineering-Time-Psychology-Perception/dp/0321509188/"><FONT size=3 face=Calibri>Designing and Engineering Time</FONT></A><FONT face=Calibri><FONT size=3>,” complete with application responsiveness guidelines to help improve customer satisfaction. If you are in a position to design a new application from scratch from First Principles, Steve’s book will be an invaluable guide.<o:p></o:p></FONT></FONT></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 10pt 38.55pt; mso-list: l1 level1 lfo2; mso-add-space: auto" class=MsoListParagraphCxSpLast><SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"><SPAN style="mso-list: Ignore"><FONT size=3>·</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><FONT size=3><FONT face=Calibri>If the application currently exists in some form or another, measure its current performance. When you deliver the next version of the application, any significant decrease in performance from one release to the next will be perceived as an irritant and received negatively by existing users. In other words, measure the scenario of interest on the current system &amp; use that as a <EM>baseline</EM> that you won’t regress in a subsequent version. <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt 2.55pt" class=MsoNormal><FONT size=3 face=Calibri>If you have to start somewhere, measuring current levels of performance around key scenarios and using them as a baseline gives you a place to start, at least. My experience is that the current level of performance sets expectations that the next version of the application must meet if you want your customers to be satisfied. In this context, Steve Seow's book&nbsp;cites psychological research into how much of a response time difference is necessary to be perceived as a difference. (About 20% in either direction makes a difference.) This reminds me of </FONT><A href="https://en.wikipedia.org/wiki/Gregory_Bateson" mce_href="https://en.wikipedia.org/wiki/Gregory_Bateson"><FONT size=3 face=Calibri>Gregory Bateson</FONT></A><FONT size=3><FONT face=Calibri>’s adage that “information is a difference that <I style="mso-bidi-font-style: normal">makes</I> a difference.” <o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt 2.55pt" class=MsoNormal><FONT size=3><FONT face=Calibri>I do think that over time, humans adapt themselves to the response times they experience, such that, eventually, the response times of the new version become the new baseline. In other words, our positive or negative perception tends to atrophy over time. For example, consider the last time you acquired a new desktop or portable computer that was noticeably faster than its predecessor. How long was it before that rush of enthusiasm for the fast, new machine started to diminish? About 30 days, in my experience.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Twenty-five years ago, I was in a similar position to Charles, responsible for performance and capacity planning at a large telecommunications company for maybe 20 IBM mainframe computers, which was considered a whole lot of machines to keep track of back in those days. We used a product called MICS (full disclosure, I was a developer on MICS for a brief period in the mid-80s) to warehouse the performance data we were gathering from these machines and the SAS language for statistical reporting. Subsequently, at Landmark Systems, I designed a “management by exception” feature for our monitoring products that our customers loved based on very simple statistical process control techniques. Today, for Charles’ team that needs to monitor performance on 100,000s of servers, these statistical techniques are the only viable approach.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3><FONT face=Calibri>But, of course, Uri is correct. You do have to choose the right metrics. I believe Charles has. I will discuss the CPU utilization metrics in Windows <A title="next post in series" href="https://blogs.msdn.com/ddperf/archive/2010/04/04/measuring-processor-utilization-and-queuing-delays-in-windows-applications.aspx" mce_href="https://blogs.msdn.com/ddperf/archive/2010/04/04/measuring-processor-utilization-and-queuing-delays-in-windows-applications.aspx">in my next post</A>.</FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3><FONT face=Calibri></FONT></FONT>&nbsp;</P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3><FONT face=Calibri>-- Mark Friedman<o:p>&nbsp;</o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>]]></content:encoded>
    </item>
    <item>
      <title>Looking at Virtual Memory Usage</title>
      <link>https://docs.microsoft.com/archive/blogs/ddperf/looking-at-virtual-memory-usage</link>
      <pubDate>Tue, 08 Dec 2009 07:43:00 GMT</pubDate>
      <dc:creator><![CDATA[David Berg]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ddperf/2009/12/08/looking-at-virtual-memory-usage/</guid>
      <description><![CDATA[Brian Harry is continuing a great series of posts on VS2010 performance, you can read the latest in...]]></description>
      <content:encoded><![CDATA[<P>Brian Harry is continuing a great series of posts on VS2010 performance, you can read the latest in that series <A class="" title="BHarry's blog - Virtual Memory Usahe" href="https://blogs.msdn.com/bharry/archive/2009/12/08/looking-at-virtual-memory-usage.aspx" mce_href="https://blogs.msdn.com/bharry/archive/2009/12/08/looking-at-virtual-memory-usage.aspx">here</A>; where Brian talks about the issues we've been seeing around Virtual Memory Exhaustion and what we're doing to address it.</P>
<P mce_keep="true">&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>Improvements in Intellisense post Beta 2</title>
      <link>https://docs.microsoft.com/archive/blogs/ddperf/improvements-in-intellisense-post-beta-2</link>
      <pubDate>Fri, 04 Dec 2009 22:06:00 GMT</pubDate>
      <dc:creator><![CDATA[David Berg]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ddperf/2009/12/04/improvements-in-intellisense-post-beta-2/</guid>
      <description><![CDATA[Brian Harry has posted a discussion of Intellisense performance improvements in VS2010 that we've...]]></description>
      <content:encoded><![CDATA[<P><A class="" title="bharry - Improvements in Intellisense Post Beta 2" href="https://blogs.msdn.com/bharry/archive/2009/12/04/improvements-in-intellisense-post-beta-2.aspx" mce_href="https://blogs.msdn.com/bharry/archive/2009/12/04/improvements-in-intellisense-post-beta-2.aspx">Brian Harry has posted a discussion of Intellisense performance improvements</A> in VS2010 that we've made since Beta 2, including bothe before and after videos.&nbsp; He also touches a little on the massive performance effort we're making as a division to address the performance issues identified by our external and internal customers.</P>
<P mce_keep="true">&nbsp;</P>]]></content:encoded>
    </item>
  </channel>
</rss>