2015-11-11 11 views
5

Ngen e RyuJIT sono due cose completamente indipendenti sotto .NET 4.6 (specialmente con tecniche di ottimizzazione e algoritmi diversi)?Ngen vs RyuJIT - codice di esecuzione x64 più veloce quando (pre) avvio non importa

Cosa produce il codice nativo x64 più veloce (meglio ottimizzato) se non ci interessa il costo del jitter stesso e/o del tempo di avvio freddo/caldo?

Stiamo eseguendo un'app server di lunga durata. La fase di funzionamento continuo è molto importante dal punto di vista delle prestazioni. La fase (pre) di avvio non è importante per noi. Fino ad ora siamo stati su .NET 4.5 e abbiamo sempre generato immagini native di Ngen. Siamo ora in fase di aggiornamento a .NET 4.6 e vogliamo essere sicuri che ciò non riduca le prestazioni della nostra fase di funzionamento continuo. Ho letto alcune informazioni che RyuJIT è un'ottima scelta per migliorare il tempo di JIT, ma che il codice jited può essere meno ottimizzato rispetto a Ngen - vedi ad es. this github comment on one of the RyuJIT bugs.

risposta

10

Non c'è abbastanza differenza tra NGen e RyuJIT per renderti felice. Fanno molto diversi lavori, NGen jits avanti nel tempo e RyuJIT jits in tempo mentre il processo è in esecuzione. Ma NGen non ha il suo jitter, chiede a RyuJIT di portare a termine il lavoro. Il codice macchina generato non è fondamentalmente diverso. Ci sono alcune ottimizzazioni che non possono essere fatte in anticipo, il codice NGen-ed è leggermente più lento.

Tecnicamente NGen potrebbe fare un lavoro migliore poiché l'ottimizzatore potrebbe impiegare più tempo ad analizzare il codice e cercare di trovare la migliore ottimizzazione possibile. Ma Microsoft non ne approfitta. Non è completamente cristallino perché non lo fa, ma sicuramente ha qualcosa a che fare con il numero di telefono del supporto 1-800. L'ottimizzazione del codice è sempre la parte più rischiosa di un generatore di codice e gli errori nei jitter esistenti sono sempre stati bug di ottimizzazione. Che questo potrebbe cambiare un giorno non è impensabile.

Sarai in vantaggio quando potrai sfruttare .NET nativo. Genera il codice in anticipo con il back-end del compilatore C++. Ma attualmente, e sicuramente per un po 'di tempo a venire, è supportato solo per le app pacchettizzate. Il tipo che viene consegnato tramite Windows Store, dovrai scegliere come target Store, Phone o Universal e utilizzare lo Store come veicolo di implementazione. Il pacchetto è molto importante per far funzionare .NET Native, solo in modo decente in modo che possa vedere quale codice deve essere tradotto. E spesso ha ancora bisogno di aiuto per farlo bene, Reflection è un problema difficile da risolvere, il motivo per cui lo hai sul tuo computer. Si noti che lo stesso problema non esiste per NGen, si basa ancora sul jitter per ottenere un po 'di codice in tempo. Come il codice target di Riflessione e i generici. Che questo potrebbe cambiare un giorno non è impensabile.

Come indicato, il codice NGen è leggermente più lento. Quindi, se non ti preoccupi dei ritardi di avviamento a caldo, allora non vuoi usare NGen.

Ultimo ma non meno importante, RyuJIT fa non generare codice più veloce rispetto al suo predecessore. Che ha già fatto un ottimo lavoro di ottimizzazione. Troppo decente. Il progetto RyuJIT è stato avviato per risolvere i problemi nel jitter legacy x64, il tipo che era piuttosto fondamentale nella base del codice e che poteva essere risolto solo con una drastica riscrittura. L'ottimizzazione era uno di questi, non aveva limiti superiori per il tempo che ci passava. Dare tempi di scatto molto irragionevoli con metodi ampi. Quindi se vuoi spremere l'ultima oncia disattivando intenzionalmente RyuJIT in modo che ricada sul jitter legacy x64 è qualcosa che dovresti provare.

+0

Hans, elogiando la qualità del codice di .NET JIT mi spezza il cuore. – usr

+0

@Hans Passant Grazie per una risposta molto dettagliata! 'Il codice NGen-ed è leggermente più lento.' - Intendi solo la fase di avvio (a causa di ulteriori file sul disco che devono essere trovati e caricati in memoria) o ci sono altri motivi?Purtroppo abbiamo alcuni percorsi critici di codice (invio dell'ordine) che devono eseguire rapidamente anche la prima esecuzione (il profilo JIT potrebbe essere la strada da percorrere - ma Ngen è ancora molto più affidabile in questo) – Jan

+0

@usr - stai leggendo i miei post con occhiali di colore grigio. Lode?? Non ho saltato .NET Native. –

Problemi correlati