jit compilation module overview
play

JIT Compilation Module Overview JIT Compilation Native vs. Managed - PowerPoint PPT Presentation

JIT Compilation Module Overview JIT Compilation Native vs. Managed Compilation Managed Execution Phases Assembly Loading & Initialization JIT Compilation JIT Optimizations Whats new in NGEN 4.0? When to use NGEN? 2 Running Code


  1. JIT Compilation

  2. Module Overview JIT Compilation Native vs. Managed Compilation Managed Execution Phases Assembly Loading & Initialization JIT Compilation JIT Optimizations What’s new in NGEN 4.0? When to use NGEN? 2

  3. Running Code Behavior in Windows 2000 - Legacy entry point mscoree!CorExeMain gets used Behavior in Windows XP - The operating system loader checks for managed modules by examining a bit in the common object file format (COFF) header - The bit being set denotes a managed module - If the loader detects managed modules, it loads mscoree.dll, and clr!CorValidateImage and clr!CorImageUnloading notify the loader when the managed module images are loaded and unloaded clr!CorValidateImage performs the following: - Ensures that the code is valid managed code - Changes the entry point in the image to an entry point in the runtime On 64-bit Windows, _CorValidateImage modifies the image that is in memory by transforming it from PE32 to PE32+ 3

  4. Native compile vs Managed compile Simplified view of native code compilation Native Code .CPP or .C file .OBJ File (Machine .EXE or .DLL File containing C or C++ Compile Link language) (Machine language) code Type describing information Type describing information 4

  5. Native compile vs Managed compile Simplified view of managed code compilation Managed Code Machine Language Assembly(.EXE or .CS File containing C# generated in memory Compile .DLL) containing MSIL Execute code at runtime by JIT and Metadata compiler 5

  6. Managed Execution Phases Phase .NET Source code .NET Source code Compile Time Compile IL and Metadata IL and Metadata IL and Metadata Run Time JIT (CLR) Native Code Native Code 6

  7. JIT Compilation What does JIT do? Checks if function is called 1 st time - JIT compiles IL code to native code if true Stores native code in memory Updates MethodDescriptor field - Reference updated to point to memory location of native code 7

  8. Managed Execution JIT Compilation MyModule::Main No First call? Retrieve address of native code from MethodDesc Yes CILJit::compileMethod (x86) PreJit::compileMethod (x64) [verifies and compiles the IL] Execute the native code Execute the native code Native code, GCInfo, EH data,etc. Store native code in memory Store the address in MethodDesc 8

  9. MethodDescriptor Contains implementation of a managed method Generated as part of the class loading procedure Initially points to IL Code Can be determined during debugging - !SOS.DumpMD <MethodDesc address> 0:004> !dumpmd 009969a8 Method Name: MyApp.MainForm.menu_Click(System.Object, System.EventArgs) Class: 00cd5c0c MethodTable: 00996ad4 mdToken: 0600028d Module: 00992c3c IsJitted: no CodeAddr: ffffffff Transparency: Critical 9

  10. Managed Execution Assembly Loading and Initialization MSCoreEE.dll is loaded Process starts and loads the .NET Process Main thread starts executing Framework by calling _CorExeMain Initializes CLR ClassLoader is called Reads MetaData tables Execute Main Build InMemory representation JIT compile the Main method MethodTable & EEClass 10

  11. Anatomy of a managed non-value instance (very schematic) Loader Heap EEClass MethodTable GC Heap Full EEClass* ( “ Cold ” ) Instance metadata “ Hot ” metadata MethodTable* MethodDesc Method Desc* Pointer to VTables • PreJittedStub Field layout • JItted code •“ IL ” stub * == Pointer 11

  12. !DumpClass & DumpMT 12

  13. JIT Optimizations Summary Types of Optimization: - JIT Inlining - JIT Tail Calls 13

  14. JIT Optimizations Tail Calls When the last thing a function does is call another function - Calls without Optimization: static public void Main() Call One() { Call Two() Helper(); Call Three() } - With Optimization: static public void Helper() { Call One() One(); Call Two() Two(); Jump Three() Three(); } - will use the same stack space as the caller. - improve data locality, memory usage, static public void Three() and cache usage. { ... } 14

  15. JIT Optimizations Tail Calls Tail Call Feature set different between X86 and X64 - Can lead to e.g. Stack Overflow Exception on X86 Debug but works fine on X64 ( where x86 stack just enough in release with tail call, but overflows without optimization) No Tail Calls possible if: - Caller doesn't return immediately after the call - Stack arguments between caller and callee are incompatible in a way that would require shifting things around in the caller's frame before the callee could execute - Caller and callee return different types - We inline the call instead (inlining is way better than tail calling, and opens the door to many more optimizations) - Security issues - The debugger / profiler turned off JIT optimizations - Full list see: .NET 2.0 Tail limits and .NET 4.0 Tail Limits 15

  16. JIT Optimizations – Inlining class Test { Without inlining static int And(int i1, int i2) { return i1 & i2; } static int i; static public void Main() { i = And(i, 0); } } class Test With inlining { static int i; static public void Main() { i = 0 // xor edx,edx } } 16

  17. JIT Optimizations – Inlining Main() Without Inlining: <Setup stack> mov ecx,dword ptr ds:[183368h] ; setup first argument (i) xor edx,edx ; setup second argument (0) call dword ptr ds:[183818h] (Inline.Program+Test.And(Int32, Int32), mdToken: 06000002 ) ; Call And(…) mov dword ptr [ebp-4],eax ; save return value mov eax,dword ptr [ebp-4] ; assign result to static mov dword ptr ds:[00283368h],eax ; assign result to static <cleanup stack> ret ; return And(Int32, Int32) <Setup stack> mov eax,dword ptr [ebp-4] ; move arg 1 to eax and eax,dword ptr [ebp-8] ; Add argument 2 to eax (return register) <cleanup stack> ret ; return to caller 17

  18. JIT Optimizations – Inlining With Inlining - And(.,.) is inlined now - No add reg,reg - because not needed (argument is 0) MethodDesc Table Entry MethodDesc JIT Name 53dda7e0 53bb4934 PreJIT System.Object.ToString() 53dde2e0 53bb493c PreJIT System.Object.Equals(System.Object) 53dde1f0 53bb495c PreJIT System.Object.GetHashCode() 53e61600 53bb4970 PreJIT System.Object.Finalize() 001dc019 001d3828 NONE Inline.Program+Test..ctor() 001dc011 001d3810 NONE Inline.Program+Test.And(Int32, Int32) 00270070 001d381c JIT Inline.Program+Test.Main() Main() xor edx,edx ; generate final result mov dword ptr ds:[1D3368h],edx ; move result to static ret ; return 18

  19. Demo: JIT Compilation !dumpmt – md bp cmdStartJit_Click

  20. JIT Optimizations Additional Config Instruct CLR not to optimize the code (during jit) without recompiling the dll: - Use an ini file (and symbols) • MyDll.ini: [.NET Framework Debugging Control] GenerateTrackingInfo=1 (per default on up from .NET 2.0) AllowOptimize=0 • (useable for GAC as well) Instruct CLR to ignore (optimized) Ngen Image - Use Environment variable: set COMPLUS_ZapDisable=1 20

  21. JIT Performance Counters - % Time in Jit % elapsed time in JIT compilation since JIT started Updated at the end of every JIT compilation phase. A JIT compilation phase occurs when a method and its dependencies are compiled. A value > 5% can indicate a problem - Is Ngen an option? • http://msdn.microsoft.com/en-us/magazine/cc163610.aspx - Do you use multiple AppDomains? • loading assemblies as domain neutral can help - Minimize the classes and assemblies within code path • Use code coverage to determine these components. - See .NET Framework Usage Performance Rules/DA0009 21

  22. JIT Performance Counters -summary Performance counter Description Displays the total number of Microsoft intermediate language (MSIL) bytes compiled by # of IL Bytes the just-in-time (JIT) compiler since the application started. This counter is equivalent to JITted the Total # of IL Bytes Jitted counter. # of IL Methods Displays the total number of methods JIT-compiled since the application started. This JITted counter does not include pre-JIT-compiled methods. Displays the percentage of elapsed time spent in JIT compilation since the last JIT % Time in Jit compilation phase. This counter is updated at the end of every JIT compilation phase. A JIT compilation phase occurs when a method and its dependencies are compiled. Displays the number of MSIL bytes that are JIT-compiled per second. This counter is IL Bytes Jitted / not an average over time; it displays the difference between the values observed in the sec last two samples divided by the duration of the sample interval. Displays the peak number of methods the JIT compiler has failed to compile since the Standard Jit application started. This failure can occur if the MSIL cannot be verified or if there is an Failures internal error in the JIT compiler. Total # of IL Displays the total MSIL bytes JIT-compiled since the application started. This counter is Bytes Jitted equivalent to the # of IL Bytes Jitted counter. 22

Recommend


More recommend