MSDN Magazine - April 2008 - (Page 20) Figure 3 Using a Debugger to Validate Performance Results Operation Measured MethodCalls: EmptyStaticFunction() [count=1000 scale=10.0] MethodCalls: aStructWithInterface.Interface() [count=1000 scale=10.0] Median 1.000 0.031 Mean 0.964 0.029 StdDev 0.102 0.012 Min 0.857 0.021 Max 1.196 0.039 Samples 10 10 lows me to choose the most natural alternative, knowing I was not sacrificing performance to do so. Validating Your Performance Results The MeasureIt application makes collecting data for a broad variety of benchmarks very easy. Unfortunately, MeasureIt does not address an important aspect of using benchmark data: validation. It is extremely easy to measure something other than what you thought you were measuring. The result is data that is simply wrong, and worse than useless. The old adage “if it sounds too good (or bad) to be true, it probably is” definitely applies to performance data. It is imperative that you validate data that you use in any important design decision. What does it mean to validate performance results? It means collecting other information that also will predict the performance result and seeing if the two methodologies agree. For very small micro-benchmarks, inspecting machine instructions and making an estimate based on the number of instructions executed is an excellent check. In a debugger like Visual Studio, it should be as easy as setting a breakWhat does it mean to point in your benchmark validate performance code and switching to the results? It means collecting disassembly window (Deother information that also bug -> Windows ->Diswill predict the performance assembly). Unfortunately, result and seeing if the two the default options for Visual Studio are designed to methodologies agree. simplify debugging, not to do performance investigations, so you need to change two options to make this work. First, go to Tools | Options… | Debugging | General and clear the Suppress JIT Optimization checkbox. This box is checked by default, which means that even when debugging code that should be optimized, the debugger tells the runtime not to do so. The debugger does this so that optimizations don’t interfere with the inspection of local variables, but it also means that you are not looking at the code that is actually run. I always uncheck this option because I strongly believe that debuggers should strive to only inspect, and not to change the program being debugged. Note that unsetting this option has no effect on code that was compiled for debugging since the runtime would not have optimized that code anyway. Next, clear the Enable Just My Code checkbox from Tools | Options | Debugging | General dialog. The Just My Code feature instructs the debugger not to show you code that you did not write. Generally, this feature removes the clutter of call frames that are 20 msdnmagazine CLR Inside Out Validating Micro-Benchmark Data with a Debugger often not of interest to the application developer. However, this feature assumes that any code that is optimized can’t be yours (it assumes your code is compiled using the debug configuration or suppressed JIT Optimizations is turned on). If you allow JIT optimizations but don’t turn off Just My Code, you will find that you never hit any breakpoints because the debugger does not believe your code is yours. Once you have unchecked these options, they remain unchecked for ALL projects. Generally this works out well, but it does mean that you don’t get the Just My Code feature. You may find yourself switching Just My Code on and off as you go from debugging to performance evaluation and back. As an example of using a debugger to validate performance results, you can investigate an anomaly in the data shown in the excerpt in Figure 3. This data shows that calls to an interface method of a C# structure is many times faster than a call to a static method. This certainly seems odd, given that you would expect a static method call to be the most efficient type of call. To investigate this, you set a breakpoint in this benchmark and run the application. Switch to the disassembly window (Debug -> Windows -> Disassembly) and see that the whole benchmark consists of just the following code: aStructWithInterface.InterfaceMethod(); 00000000 ret What this shows is that the benchmark (which is 10 calls to an interface method) has been inlined away to be nothing. The ret instruction is actually the end of the delegate body that defines the whole benchmark. Well, it is not surprising that doing nothing is faster than doing method calls, so this shows the reason for the anomaly. The only mystery is why static methods don’t get inlined, too. This is because for static methods, I specifically went out of my way to suppress inlining with the MethodImplOptions.NoInlining attribute. I intentionally “forgot” to put this on this interface call benchmark to demonstrate that the JIT compiler can make certain interface calls as efficient as non-virtual calls (there is a comment mentioning this above the benchmark). Wrapping Up To reiterate, it is very easy to measure something other than what you intended, especially when measuring small things that are subject to JIT compiler optimizations. It is also very easy to accidentally measure non-optimized code, or measure the cost of JIT compilation of a method rather than the method itself. The MeasureIt /usersGuide command will bring up a user’s guide that discusses many of the pitfalls you might encounter when creating benchmarks. I strongly recommend that you read these details when you are ready to write your own benchmarks.
Table of Contents Feed for the Digital Edition of MSDN Magazine - April 2008 MSDN Magazine - April 2008 Contents Toolbox CLR Inside Out Basic Instincts Cutting Edge Foundations Test Run Service Station Windows with C++ Going Places { End Bracket } MSDN Magazine - April 2008 MSDN Magazine - April 2008 - (Page Intro) MSDN Magazine - April 2008 - Contents (Page Cover1) MSDN Magazine - April 2008 - Contents (Page Cover2) MSDN Magazine - April 2008 - Contents (Page 1) MSDN Magazine - April 2008 - Contents (Page 2) MSDN Magazine - April 2008 - Contents (Page 3) MSDN Magazine - April 2008 - Contents (Page 4) MSDN Magazine - April 2008 - Contents (Page 5) MSDN Magazine - April 2008 - Contents (Page 6) MSDN Magazine - April 2008 - Contents (Page 7) MSDN Magazine - April 2008 - Contents (Page 8) MSDN Magazine - April 2008 - Contents (Page 9) MSDN Magazine - April 2008 - Contents (Page 10) MSDN Magazine - April 2008 - Toolbox (Page 11) MSDN Magazine - April 2008 - Toolbox (Page 12) MSDN Magazine - April 2008 - Toolbox (Page 13) MSDN Magazine - April 2008 - Toolbox (Page 14) MSDN Magazine - April 2008 - Toolbox (Page 15) MSDN Magazine - April 2008 - Toolbox (Page 16) MSDN Magazine - April 2008 - CLR Inside Out (Page 17) MSDN Magazine - April 2008 - CLR Inside Out (Page 18) MSDN Magazine - April 2008 - CLR Inside Out (Page 19) MSDN Magazine - April 2008 - CLR Inside Out (Page 20) MSDN Magazine - April 2008 - CLR Inside Out (Page 21) MSDN Magazine - April 2008 - CLR Inside Out (Page 22) MSDN Magazine - April 2008 - CLR Inside Out (Page 23) MSDN Magazine - April 2008 - CLR Inside Out (Page 24) MSDN Magazine - April 2008 - Basic Instincts (Page 25) MSDN Magazine - April 2008 - Basic Instincts (Page 26) MSDN Magazine - April 2008 - Basic Instincts (Page 27) MSDN Magazine - April 2008 - Basic Instincts (Page 28) MSDN Magazine - April 2008 - Basic Instincts (Page 29) MSDN Magazine - April 2008 - Basic Instincts (Page 30) MSDN Magazine - April 2008 - Basic Instincts (Page 31) MSDN Magazine - April 2008 - Basic Instincts (Page 32) MSDN Magazine - April 2008 - Basic Instincts (Page 33) MSDN Magazine - April 2008 - Basic Instincts (Page 34) MSDN Magazine - April 2008 - Cutting Edge (Page 35) MSDN Magazine - April 2008 - Cutting Edge (Page 36) MSDN Magazine - April 2008 - Cutting Edge (Page 37) MSDN Magazine - April 2008 - Cutting Edge (Page 38) MSDN Magazine - April 2008 - Cutting Edge (Page 39) MSDN Magazine - April 2008 - Cutting Edge (Page 40) MSDN Magazine - April 2008 - Cutting Edge (Page 41) MSDN Magazine - April 2008 - Cutting Edge (Page 42) MSDN Magazine - April 2008 - Cutting Edge (Page 43) MSDN Magazine - April 2008 - Cutting Edge (Page 44) MSDN Magazine - April 2008 - Cutting Edge (Page 45) MSDN Magazine - April 2008 - Cutting Edge (Page 46) MSDN Magazine - April 2008 - Foundations (Page 47) MSDN Magazine - April 2008 - Foundations (Page 48) MSDN Magazine - April 2008 - Foundations (Page 49) MSDN Magazine - April 2008 - Foundations (Page 50) MSDN Magazine - April 2008 - Foundations (Page 51) MSDN Magazine - April 2008 - Foundations (Page 52) MSDN Magazine - April 2008 - Foundations (Page 53) MSDN Magazine - April 2008 - Foundations (Page 54) MSDN Magazine - April 2008 - Foundations (Page 55) MSDN Magazine - April 2008 - Foundations (Page 56) MSDN Magazine - April 2008 - Foundations (Page 57) MSDN Magazine - April 2008 - Foundations (Page 58) MSDN Magazine - April 2008 - Foundations (Page 59) MSDN Magazine - April 2008 - Foundations (Page 60) MSDN Magazine - April 2008 - Foundations (Page 61) MSDN Magazine - April 2008 - Foundations (Page 62) MSDN Magazine - April 2008 - Foundations (Page 63) MSDN Magazine - April 2008 - Foundations (Page 64) MSDN Magazine - April 2008 - Foundations (Page 65) MSDN Magazine - April 2008 - Foundations (Page 66) MSDN Magazine - April 2008 - Foundations (Page 67) MSDN Magazine - April 2008 - Foundations (Page 68) MSDN Magazine - April 2008 - Foundations (Page 69) MSDN Magazine - April 2008 - Foundations (Page 70) MSDN Magazine - April 2008 - Foundations (Page 71) MSDN Magazine - April 2008 - Foundations (Page 72) MSDN Magazine - April 2008 - Foundations (Page 73) MSDN Magazine - April 2008 - Foundations (Page 74) MSDN Magazine - April 2008 - Foundations (Page 75) MSDN Magazine - April 2008 - Foundations (Page 76) MSDN Magazine - April 2008 - Foundations (Page 77) MSDN Magazine - April 2008 - Foundations (Page 78) MSDN Magazine - April 2008 - Foundations (Page 79) MSDN Magazine - April 2008 - Foundations (Page 80) MSDN Magazine - April 2008 - Foundations (Page 81) MSDN Magazine - April 2008 - Foundations (Page 82) MSDN Magazine - April 2008 - Foundations (Page 83) MSDN Magazine - April 2008 - Foundations (Page 84) MSDN Magazine - April 2008 - Foundations (Page 85) MSDN Magazine - April 2008 - Foundations (Page 86) MSDN Magazine - April 2008 - Foundations (Page 87) MSDN Magazine - April 2008 - Foundations (Page 88) MSDN Magazine - April 2008 - Foundations (Page 89) MSDN Magazine - April 2008 - Foundations (Page 90) MSDN Magazine - April 2008 - Foundations (Page 91) MSDN Magazine - April 2008 - Foundations (Page 92) MSDN Magazine - April 2008 - Foundations (Page 93) MSDN Magazine - April 2008 - Foundations (Page 94) MSDN Magazine - April 2008 - Foundations (Page 95) MSDN Magazine - April 2008 - Foundations (Page 96) MSDN Magazine - April 2008 - Foundations (Page 97) MSDN Magazine - April 2008 - Foundations (Page 98) MSDN Magazine - April 2008 - Test Run (Page 99) MSDN Magazine - April 2008 - Test Run (Page 100) MSDN Magazine - April 2008 - Test Run (Page 101) MSDN Magazine - April 2008 - Test Run (Page 102) MSDN Magazine - April 2008 - Test Run (Page 103) MSDN Magazine - April 2008 - Test Run (Page 104) MSDN Magazine - April 2008 - Test Run (Page 105) MSDN Magazine - April 2008 - Test Run (Page 106) MSDN Magazine - April 2008 - Service Station (Page 107) MSDN Magazine - April 2008 - Service Station (Page 108) MSDN Magazine - April 2008 - Service Station (Page 109) MSDN Magazine - April 2008 - Service Station (Page 110) MSDN Magazine - April 2008 - Service Station (Page 111) MSDN Magazine - April 2008 - Service Station (Page 112) MSDN Magazine - April 2008 - Service Station (Page 113) MSDN Magazine - April 2008 - Service Station (Page 114) MSDN Magazine - April 2008 - Windows with C++ (Page 115) MSDN Magazine - April 2008 - Windows with C++ (Page 116) MSDN Magazine - April 2008 - Windows with C++ (Page 117) MSDN Magazine - April 2008 - Windows with C++ (Page 118) MSDN Magazine - April 2008 - Windows with C++ (Page 119) MSDN Magazine - April 2008 - Windows with C++ (Page 120) MSDN Magazine - April 2008 - Windows with C++ (Page 121) MSDN Magazine - April 2008 - Windows with C++ (Page 122) MSDN Magazine - April 2008 - Going Places (Page 123) MSDN Magazine - April 2008 - Going Places (Page 124) MSDN Magazine - April 2008 - Going Places (Page 125) MSDN Magazine - April 2008 - Going Places (Page 126) MSDN Magazine - April 2008 - Going Places (Page 127) MSDN Magazine - April 2008 - { End Bracket } (Page 128) MSDN Magazine - April 2008 - { End Bracket } (Page Cover3) MSDN Magazine - April 2008 - { End Bracket } (Page Cover4)
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.