2012-08-16 13 views
7

Zauważyłem, że jitter C# wytwarza wymiernie wolniejszy kod niż kompilator C++, nawet jeśli nie ma użytych konstruktów "managed overhead" (takich jak tablice z sprawdzonym indeksowaniem).Udoskonalenia jittera C# w przyszłych wersjach frameworków

kwantyfikowania, że ​​czasowe następujące proste pętli:

public static int count = 1000000000; 
public static int Main() 
{ 
    int j = 0; 
    for (int i = 0; i < count; ++i) 
    { 
     j += (i % 2 == 0) ? ((i + 7) >> 3) : (i * 7); 
    } 
    return j; 
} 

Ta pętla zaczyna 3.88s Wykonywanie (sporządzoną w/o). Równoważna pętla skompilowana z VC 2010 (-O2) zajmuje 2,95s.

Aby sprawdzić, czy faktycznie wygenerowano niższy kod, porównałem kody maszynowe: utworzono listing (/ FA) z kompilatora VC i dołączono debugger do programu C# (po zakończeniu pętli).

Rzeczywiście, wersja C++ używa pewnych sprytnych sztuczek. Na przykład, aby uniknąć kosztownego mnożenia przez 7, istnieje osobny rejestr, który jest zwiększany o 7 na każdą liczbę pętli. Wersja C# wykonuje mnożenie (imul) za każdym razem. Są też inne różnice.

Rozumiem, że jitter C# ma znacznie mniej czasu na skompilowanie kodu w czasie wykonywania niż VC w czasie kompilacji. Ale np. Jitter Java dynamicznie optymalizuje często używane metody. C# nie wydaje się tego robić.

Moje pytanie brzmi: czy planowane są ulepszenia jittera C# w przyszłych wersjach frameworków?

+0

Visual Studio RC 2012 z .NET 4.5 jest dostępne do pobrania od wczoraj. Pobierz go (to nic nie kosztuje) i uruchom tam ten sam test. –

+0

Przestałem wstrzymywać oddech na nowe optymalizacje zrobione przez jittera dawno temu. MS wydaje się myśleć, że jest wystarczająco dobre w tym dziale. – harold

+0

@harold Od kiedy? –

Odpowiedz

3

Czy planowane są ulepszenia jittera C# w przyszłych wersjach frameworków?

Pytasz, czy nie było w rzeczywistości tajne spotkanie w zeszłym miesiącu pomiędzy Microsoft i Xamarin gdzie ustalono, że podczas gdy oni oboje spędziliśmy ostatnią dekadę poprawy ich odpowiednich trema, że ​​od tej pory były chore usprawniając i nie zawracając sobie głowy, a MS ponownie wyznaczyłoby wszystkich, podczas gdy Xamarin odrzuciłby wszelkie przesłane łaty, które poprawiłyby jittera?

Powiedziałbym, że jest to mało prawdopodobne, i że tak jak każdy inny aktywnie opracowany projekt oprogramowania na świecie, istnieją plany poprawy tego.

Poza tym, jeśli naprawdę chciałbym uruchomić kod, który podałeś tak szybko, jak to możliwe, zoptymalizowałbym go ręcznie do return 161315136;. Kod taki jak ten może udowodnić, że implementacja A jest wolniejsza niż implementacja B w danym przypadku, ale nie mówi nic o tym, gdzie osoby odpowiedzialne za wdrożenie powinny skoncentrować swoje wysiłki. buduje

+0

Ten kod był dowodem na to, że winę za C# należy obwiniać, ponieważ C# jest wolniejszy od C++, a nie tylko "zarządzany narzut", o którym wspomina wiele osób (w tym Herb Sutter). Oczywiście wydajność jest znacznie większa niż prostych operacji i oddziałów całkowitych. – kaalus

+0

Tak, ale oprócz wyników, które uzyskał @HansPassant, pojawia się pytanie, jakie to ma znaczenie. Czy to konieczne, aby zespoły jittera wkładały swoje wysiłki w? A gdyby tak było, czy byłoby to wystarczająco interesujące, aby każdy z nich mógł pisać? Mogę sobie wyobrazić, że byłoby to zgodne z "i zrobiliśmy kilka innych ulepszeń", które można znaleźć w artykułach na takie tematy, a nie z powodu błądzenia blogów na temat mnożenia w pętli robionej szybciej. –

+0

Myślę, że są znaczne zyski, które należy zrobić, poprawiając jitter C#. Chciałbym zobaczyć dopasowanie C# lub przewyższyć Javę w grze The Computer Language Benchmarks Game (http://shootout.alioth.debian.org). C# ma natywne typy wartości i szkoda, że ​​Java jest znacznie szybsza w większości przypadków. Mimo, że testują z Mono, nie wdrażają tam MS. – kaalus

9

Release, VS2008SP1, .NET 3.5SP1, średnio 10 testów:

.NET, x86: 2.646 seconds 
C++, x86: 2.652 seconds 
.NET, x64: 2.352 seconds 
C++, x64: 2.090 seconds 

klasycznych błędów są przy założeniu, że I/O jest znacząca, mierząc czas jitting, uruchamiając build debugowania, testowania z debugerem więc optymalizator jittera jest wyłączony.

x64 jitter wykorzystuje tę samą sztuczkę, którą wspomniano, nie jest unikalny dla C++ generator kodu:

00000030 xor   r9d,r9d 
... 
00000059 add   r9d,7 

Nowością dla .NET 4.5 jest Profil Guided Optimization.

Przyszłe plany nigdy nie są udostępniane przez firmę taką jak Microsoft i nie ma sensu się z nich zgadywać.

+0

To powinna być zaakceptowana odpowiedź. – hoodaticus

Powiązane problemy