Fix Performance Problems Fast: Advanced VSTS Profiler Use, Page 2
VSTS Profiler Interaction
The VSTS Profiler exposes an API in both native and managed form that allows the amount of data collected in a profiling session to be precisely controlled and also supports the insertion of timestamp and profile mark data into a profile session. The most common usage scenario for the profiler API is when instrumentation profiling is enabled, and the amount of data collected is too large to make a timely determination of the specific area of the code base where the performance problem lays. For C++/CLI applications, the simplest API into the VSTS Profiler is through the classes exposed in the Microsoft.VisualStudio.Profiler.dll, which is located in the Microsoft Visual Studio 9.0\Team Tools\Performance Tools directory. A pure native API exists as well, and can be accessed by including the VSPerf.h header file and adding the VSPerf.lib file in the linker options for the project. These two files are located in the Microsoft Visual Studio 9.0\Team Tools\Performance Tools\PerfSDK directory. Because it is extremely unlikely that the profiler interaction code will need to be shipped as part of the final version of the software product, it is advisable to surround all calls to the profiler in #IFDEF blocks.
Controlling the profiler's data collection is a simple matter of calling the StartProfile, StopProfile, SuspendProfile, and ResumeProfile functions. All four functions require that the scope of the profile session control be nominated—each call can be applied to all processes in the profile session (PROFILE_GLOBALLEVEL), a particular process (PROFILE_PROCESSLEVEL), or a particular thread (PROFILE_THREADLEVEL). The semantics of StartProfile and StopProfile are simple—StartProfile turns profiling on, and StopProfile turns it off. SuspendProfile and ResumeProfile have subtler behavior—SuspendProfile increments a suspend counter, and ResumeProfile decrements it, so to re-enable profiling every call to SuspendProfile must be matched by a corresponding call to ResumeProfile. In situations where it is not clear how many calls to ResumeProfile are required, it is possible to cancel all calls to SuspendProfile by simply calling StartProfile.
Instrumentation profiling can have descriptive information inserted in four distinct ways:
- A thread or process can be named in a profile session by calling NameProfile.
- An event in a profile session can be marked by associating it with an arbitrary 32-bit integer using MarkProfile. For example, it is possible to mark each point where a third-party library is called by designating each call with a mark value three, and each call to a web service with a mark value of four.
- A comment of up to 256 characters can be associated with a mark by calling CommentMarkProfile. To continue on the example in the previous point, it would be possible to include the web service name each time a mark with a value of four is added.
- The occurrence of external events can be recorded in a profile session using CommentMarkAtProfile, which inserts a comment and a mark at a specified point in time.
Comments, marks, and names are quite easy to identify in the results of a profile session. The following code will produce the output shown in Figures 4 and 5:
NameProfile(_T("MyThread"), PROFILE_THREADLEVEL, PROFILE_CURRENTID); CommentMarkProfile(1, _T("Start of call to calculation engine");
Figure 4: Profile Marks with Comments.
Figure 5: Named Threads in a Profile Session.
One of the hallmarks of a good craftsperson is how well they can use their tools to produce the desired result, and the same holds true for a developer. Knowing how to use the VSTS Profiler to track down performance problems in a timely manner is an important skill for all developers, and is particularly important for C++ developers, because C++ code bases typically encompass the largest and most complex software systems that are always expected to perform at the highest level.
Out of the box, the VSTS Profiler helps developers quickly identify performance problems by removing clutter through noise reduction and short function exclusion. For large systems, explicitly controlling when the profiler collects data, and adding marks and comments into the profiling log may be required to separate the performance impacts of various software components that are executing. The VSTS Profiler supports this fine-grained control through both a managed and native interface, and developers can fine tune the collection of data down to a very granular level.
About the Author
Nick Wienholt is an independent Windows and .NET consultant based in Sydney. He is the author of Maximizing .NET Performance and co-author of A Programmers Introduction to C# 2.0 from Apress, and specialises in system-level software architecture and development, with a particular focus of performance, security, interoperability, and debugging.
Nick is a keen and active participant in the .NET community. He is the co-founder of the Sydney Deep .NET User group and writes technical articles for Australian Developer Journal, ZDNet, Pinnacle Publishing, CodeGuru, MSDN Magazine (Australia and New Zealand Edition) and the Microsoft Developer Network. An archive of Nick's SDNUG presentations, articles, and .NET blog is available at www.dotnetperformance.com.
In recognition of his work in the .NET area, he was awarded the Microsoft Most Valued Professional Award from 2002 through 2007.