Wydajność: Multicore JIT w .NET 4.5

Uruchomienie aplikacji .NET może być procesem powolnym. Związanie jest to oczywiście z potrzebą skompilowania kodu do postaci maszynowej. W przeciwieństwie do np. C++, w plikach jest przechowywany kod tymczasowy. W większości przypadków nie jest to problemem, ale dla naprawdę dużych aplikacji może być to odczuwalne. Szczególnie ma to znaczenie dla ASP.NET, gdzie zależy nam jak na najkrótszym opóźnieniu.

Jednym ze sposobów jest użycie nGen, który wygeneruje kod maszynowy. Ma to taką wadę, że trzeba wywołać go np. w instalatorze, ponieważ kod maszynowy jest oczywiście generowany dla konkretnego komputera.

Multicore JIT to z kolei zoptymalizowana kompilacja. Zasada jest bardzo prosta. Zamiast dokonywać kompilacji na jednym rdzeniu (i blokując MainThread), praca jest odpowiednio rozdzielana między CPU. Przynosi to dość duże korzyści, nawet 50%. Szczególnie aplikacje takie jak ASP.NET czy WPF zyskają na tym.

Pozostaje pytanie, jak metody są kompilowane. W podejściu sekwencyjnym, metoda jest kompilowana kiedy ma zostać wywołana pierwszy raz. W przypadku Multicore, z góry musimy znać całą ścieżkę, aby móc rozdzielić odpowiednio pracę. Z tego względu MultiCore działa w dwóch trybach. Gdy aplikacja jest uruchamiana pierwszy raz, wtedy cała ścieżka jest “nagrywana” i zapisywana do pliku. Podczas kolejnych uruchomień, profil ścieżki jest ładowany i może zostać już dokonana kompilacja równoległa. Warto zaznaczyć, że można przechowywać profile w różnych plikach. Jest to przydatne, gdy przekazywane są parametry uruchomieniowe, od których zależy konkretnie jaka seria metod będzie wywoływana.

Przejdźmy do kodu:

public static void Main() 
{
    ProfileOptimization.SetProfileRoot(@"C:\Test");
    ProfileOptimization.StartProfile("Startup.Profile1");
}  

Pierwsza metoda określa lokalizację (folder) w którym będą znajdowały się profile. Druga z kolei rozpoczyna konkretny profil.

Załóżmy, że mamy parametry uruchomieniowe i w zależności od nich, różne metody muszą zostać skompilowane:

public static void Main(string[] args) 
{
    System.Runtime.ProfileOptimization.SetProfileRoot("c:\\test");

    if (args[0] == "1") 
    {
        System.Runtime.ProfileOptimization.StartProfile("Profile1");
    } 
    else if (args[0] == "2") 
    {
        System.Runtime.ProfileOptimization.StartProfile("Profile2");
    }
}

Wszystkie aplikacje ASP.NET mają domyślnie aktywny multicore jit i nie trzeba nic konfigurować. Jeśli chcemy z kolei wyłączyć go, możemy to zrobić za pomocą web.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration>
 <!-- ... -->
 <system.web> 
 <compilation profileGuidedOptimizations="None" /> 
 <!-- ... --> 
 </system.web> 
</configuration>

Multicore, jak wspomniałem, ma znaczenie dla rozbudowanych aplikacji. Optymalizacja jest dość znacząca ponieważ wynosi 30-50%.

One thought on “Wydajność: Multicore JIT w .NET 4.5”

  1. Bardzo interesująca informacja. Czy aplikacje WPF również mają domyślnie aktywny multicore jit ?

    Czy ma to również zastosowanie dla aplikacji innych typów: Silverlight, Windows Store, Windows Phone ?

    Pozdrawiam,
    Lukas

Leave a Reply

Your email address will not be published.