Performance Improvements in Visual C++

Performance Improvements in Visual C++

  • Comments 59

Hi, my name is Jim Springfield, and I’m an architect on the Visual C++ team.  I recently spent two months working on some core improvements to how VC deals with Intellisense as well as overall UI responsiveness.

We observed a strong correlation between the severity of these performance issues and the size of the projects and solutions exhibiting these problems.  As a result, we worked closely with some large ISV customers who were reporting problems with our IDE.  These customers typically had solutions with over a hundred projects comprising thousands of files.  While I can’t identify them by full name, I want to give a shout out to them and thank them for their time and effort.  So, thank you to Bob, Don, Dick, Rainer, Kelly, and Mike, you know who you are.

While I was working on these changes as a Quick Fix Engineering patch (or, “QFE”) for Visual Studio 2005, I was also tracking the changes for Visual Studio 2008 “Orcas,” and I am happy to report that all of these changes will be available in VS2008 as well as available in a publicly available QFE (also called a General Distribution Release, or “GDR”) for VS2005.

The GDR can be downloaded from the link below.  You will be prompted to login with a Windows Live ID or Passport first and then taken to the actual download location. http://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=9436

I wish I could say everything in these areas is fixed as a part of our efforts.  However, the reality is that there were some issues that needed more substantial work and which was impossible to accomplish in this time frame.  We are already working on the next release beyond VS2008 and addressing these issues will be one of our top priorities.  We are fundamentally changing how we approach Intellisense and we are designing with the largest solutions in mind.  We will be blogging about the direction this work is going, so watch this space for additional information on these efforts as the work we are doing here is quite interesting.

To give you a feel for the scope of the changes we made to address these issues in VS2005 and VS2008, this work touched 46 source files across three DLL’s.  Overall, 4664 lines of code were changed or added.  I would like to take this opportunity to give you a bit of insight into the nature of problems we identified and the solutions we implemented.

Different lock implementation for accessing the NCB (Intellisense)

The .NCB file (an in-memory Intellisense data) was protected with a simple critical section to prevent simultaneous access from multiple threads.  However, often there were multiple threads that just wanted to read information the NCB, not modify it, so we replaced the NCB critical section with a multi-reader/single-writer lock.  This allows multiple threads to read the NCB at one time which can happen when an Intellisense request is happening on the background thread and the foreground thread needs to access it as well.  A classic example of this problem was getting a QuickInfo tooltip.  The foreground thread would need to do some basic querying of the NCB to create the QuickInfo request, which would then be processed on the background thread.  However, if the background thread already had the lock, then the foreground would block until the background was done.  This was really noticeable when scrolling around a large function.  Similar problems happened with AutoComplete requests as well.

Reduced the number of “throw-away” requests

When quickly navigating around a file, we would generate QuickInfo and CodeDefintionWindow (if the window was open) requests as the cursor touched different areas of the code.  This could result in a bunch of background requests that would run and then be ignored.  We made a change to only allow one of these types of items in the queue at a time.

Improved speed when changing active configuration and other options

There were a few things that were incredibly slow to change in a solution.  Modifying certain options (such as adding an include directory) or changing the active configuration would take a really long time for large solutions.  There was some really inefficient work going on in these cases which has been removed or redone.

Goto Definition improvements

“Goto Definition” in many situations will parse the file to the cursor in order to know the exact type of the identifier under the cursor.  This was happening on the foreground thread and if there was a low-priority item on the background thread running, the foreground would have to wait for the background one to finish.  This was changed to queue the item to the background queue, which causes any low-priority items to be aborted. As a result of this work, we had one customer reporting a two minute delay drop to 10-20 seconds.

Reduced CPU consumption

There is now throttling of the background thread when doing most of the parsing.  Even though the background was running at lower priority, there was concern about it using 100% of the CPU and some reported issues of it interfering with other applications.  We now process low-priority background items (such as Intellisense population) using only ~80% of a CPU’s time.  Any high-priority items (i.e. Intellisense requests) will still be processed during this time.

File lookup in projects

We changed the project system to make looking up files in projects much more efficient.  This improves several scenarios such as adding files to projects, changing configurations, etc.

More information in status bar

There is now more information displayed in the status bar.  It looks like this:  “Updating Intellisense… (xxx)”.   The number in parentheses shows how many background thread work items are in progress.  For customers that aren’t seeing Intellisense ever complete, this information may be useful.

Wait cursor

We now display the wait cursor at times when the IDE may not be able to respond immediately.  This gives better feedback to people that the IDE isn’t just hung, and may be displayed in the following situations:

·         Closing a project

·          “Goto Definition” is invoked or when a foreground parse is required

·         After loading a solution and doing initialization

·         Reparsing a solution after a configuration change

Improved idle-time processing

We made a variety of improvements to how the IDE handles its idle-time processing.  This work involved changes to ensure that lower priority idle tasks are treated as such by the IDE, enabling longer-running idle tasks to be spread out over multiple idle cycles, and ensuring our idle logic is smart enough to break early for later completion when a higher priority task is waiting.  Overall, these changes make the whole UI/editing experience smoother.

Map of files added to project

Looking up files in a project was doing just a linear search of the files.  This caused big slowdowns when doing certain operations such as adding a file to a project that already contained lots of files.

Miscellaneous performance and correctness improvements

·         We identified a few internal algorithms that exhibited poor performance (i.e. O(N^2) or O(N^3)) at large scale and replaced these with algorithms that scale more linearly.

·         We found instances of function-static data being used in multi-threaded scenarios and made these thread safe by moving this data to Thread Local Storage.

·         We improved performance of an internal hash table with a better-performing hashing function that exhibits fewer collisions.

Exposed a mechanism to control some aspects of Intellisense

Some customers have learned to manually disable Intellisense by marking the NCB file as read-only or deleting the Intellisense engine, feacp.dll, from the vcpackages directory, but there has not been a way to control any of this from the IDE.  While working on this QFE, I added a few flags that can be set using VS macros that do things such as disabling Intellisense almost completely or disallowing updates to the NCB while allowing queries.  The second mode is pretty useful for large projects where Intellisense works and is useful but reparsing is painful.  You can now disable updates until you have finished a bunch of edits and then turn it on and get everything parsed up-to-date.  The macros that control these settings can be attached to toolbar buttons for convenient access while coding.  Given how long this entry already is, I will write a separate blog on this soon.

 

PS: Jim wrote the subsequent macros blog and here it is: http://blogs.msdn.com/vcblog/archive/2007/11/19/controlling-intellisense-through-macros.aspx

 

Thanks

Damien

  • This fix seems to have worked for me on VS2005 SP1. I'm also testing out VC++ 2008 Express and am loving the new /MP option which has cut my build times by two-thirds on a quad core :)

    What do you need to enable 64-bit development on VC++ 2008, since the 64-bit compilers are included with the installation, and without them you can't target x64 (a download link would be handy as I'm struggling to find out exactly what I need to install) ?

  • My question should have been "What do you need to enable 64-bit development on VC++ 2008 Express" ?

  • Thank you for your work on performance improvements. I installed your patch on VS2005 SP1 (by the way, the patch takes a very long time to install). I suspect that things are better, except...

    On 2 occasions, VS2005 has hung up after I have made changes to code while debugging. The hang happens after I apply code changes and after VS states "Done".

    During the hang, Task manager reports that VS is using up memory with a delta of around 800 kB each refresh. Normally, VS uses around 128 MB of memory with a VM size of around 120 MB. On each occasion I stopped it with the memory use up to 400 MB and the VM use a little larger.

    If this happens again, is there any information I can pass on that might help debugging this?

  • For one or our large C projects this made a definite improvement. Our other large one is now worse with the IDE hanging. All we get is the hour class (VS not responding). The second solution has 3k+ files in a single project file.

    CD

  • Hi CD,

    Can you contact us so we can investigate? The easiest way to do this is to use the "email" link under "This Blog" in the lefthand navigation pane.

    Ronald Laeremans, Visual C++ Product Unit Manager

  • Hello!

    I cannot install VS80sp1-KB943969-X86-ENU.exe w/ Visual Studio 2005 Professional SP1.

    The installer works and finishes without any errors, but versions of these files are stays UNCHANGED:

    • vcpkg.dll (8.0.50727.762)

    • VCProject.dll (8.0.50727.762)

    • VCProjectEngine.dll (8.0.50727.762)

    Meanwhile, 'http://support.microsoft.com/default.aspx/kb/943969/en-us' says that versions must be as:

    • vcpkg.dll (8.0.50727.943)

    • VCProject.dll (8.0.50727.943)

    • VCProjectEngine.dll (8.0.50727.943)

    As a result, this hotfix is not applied and is not work.

    The KB943969 hotfix is shown in updates list for Visual Studio 2005 (is it means that hotfix has been installed correctly?)!

    Could You help me, please?

    My system info:

    • OS: Windows XP Professional x64 Edition Version 2003 Service Pack 2 (“Regional Options” are set to Russian; AMD Opteron CPU).

    • Microsoft Visual Studio 2005 Version 8.0.50727.762 ENU (information from “About Microsoft Visual Studio” window).

    • Microsoft Visual Studio 2005 Professional Edition - ENU Service Pack 1 (KB926601)

    • Security Update for Microsoft Visual Studio 2005 Professional Edition - ENU (KB937061)

    • Refactor! for Visual Studio & PowerToys

    Thanks.

  • A week days after installing the QFE, I think after making some changes to the core code of my solution (120 projects, 1.6M lines) the IDE start to allocate memory starting by 210MB then this memory start to increase and suddenly it jumps to 650MB and continue increasing up to 780MB and my PC appear to be hanged (I actually have only 1GB of RAM on my DELL Optiplex 745) until I terminate the VS2005.

    My machine runs Windows XP SP2. and now I'm trying to open the project on my other Vista machine with 2GB of RAM. and I will inform you with the results later.

    Thanks.

  • After testing on Vista with 2GB of RAM, the amount of RAM allocated by IDE is only 340MB.

    Thanks.

  • Thats a great work !!!

  • I have already reported a hang with the new intellisense loaded. I have just had a different problem:

    I loaded my solution (containing some 15 projects, all native C++) and right clicked on a function name and asked to go to definition. VS2005 hung up using 0% CPU and Intellisense was showing (377) files to parse. Perhaps a deadlock between the editor request and building the Intellisense database?

    The only way out was to kill the application.

  • I have just had another lockup. When I open my solution (with many sub projects), after a few seconds Intellisense starts scanning my files and diplays a number that starts around (470). If I ask to lookup a name while the intellisense message is visible, on at least 2 occasions the IDE has locked up with devenv.exe using 0% CPU. There is no way out (I have waited a long time) except to kill devenv.

  • Greg, can you save a crash dump of devenv.exe at the time of the freeze and send us the dmp file? This will help us investigate your issue further. Please contact me at vcperf at microsoft dot com.

    Thank you,

    Marian

  • Extracting acetaninophen from ultracet. Ultracet.

  • Celexa and pregnancy. Celexa nsaids. Withdrawals from celexa. Celexa dosage. Celexa. Generic celexa.

Page 4 of 4 (59 items) 1234