Compilatore JIT per C, C ++ e simili

30

Esiste un compilatore just-in-time là fuori per linguaggi compilati, come C e C ++? (I primi nomi che mi vengono in mente sono Clang e LLVM! Ma non credo che attualmente lo supportino.)

Spiegazione:

Penso che il software potrebbe trarre vantaggio dal feedback del profilo di runtime e dalla ricompilazione ottimizzata degli hotspot in fase di esecuzione, anche per linguaggi compilati su macchina come C e C ++.

L'ottimizzazione guidata dal profilo svolge un lavoro simile, ma con la differenza un JIT sarebbe più flessibile in diversi ambienti. In PGO esegui il tuo binario prima di rilasciarlo. Dopo averlo rilasciato, non avrebbe utilizzato feedback di input / ambiente raccolti in fase di runtime. Quindi, se il modello di input viene modificato, viene eseguita la verifica della penalità delle prestazioni. Ma JIT funziona bene anche in quelle condizioni.

Tuttavia ritengo sia controverso che il vantaggio in termini di prestazioni di compilazione JIT superi il proprio overhead.

    
posta Ebrahim Mohammadi 23.12.2010 - 01:47
fonte

4 risposte

32

[Vedi la cronologia delle modifiche per una risposta abbastanza diversa che ora è fondamentalmente obsoleta.]

Sì, ci sono un paio di compilatori JIT per C e / o C ++.

CLing (come puoi immaginare dal gioco) è basato su Clang / LLVM. Funziona come un interprete. Cioè, gli dai un codice sorgente, un comando per farlo funzionare e funziona. L'enfasi qui è principalmente sulla convenienza e sulla compilazione veloce, non sull'ottimizzazione massima. In quanto tale, sebbene tecnicamente sia una risposta alla domanda stessa, questo non si adatta molto bene alle intenzioni dell'OP.

Un'altra possibilità è NativeJIT . Questo risponde alla domanda in qualche modo in modo diverso. In particolare, non accetta il codice sorgente C o C ++, lo compila ed esegue. Piuttosto, è un piccolo compilatore che puoi compilare nel tuo programma C ++. Accetta un'espressione che è fondamentalmente espressa come EDSL all'interno del tuo programma C ++ e genera un codice macchina effettivo da quello, che puoi quindi eseguire. Ciò si adatta molto meglio con un framework in cui è possibile compilare la maggior parte del programma con un normale compilatore, ma con alcune espressioni che non si conosceranno fino al runtime, che si desidera eseguire con qualcosa che si avvicina alla velocità di esecuzione ottimale. / p>

Per quanto riguarda l'apparente intento della domanda originale, penso che il punto fondamentale della mia risposta originale sia ancora valido: mentre un compilatore JIT può adattarsi a cose come dati che variano da un'esecuzione all'altra , o anche variando dinamicamente durante una singola esecuzione, la realtà è che questo fa relativamente poca differenza almeno come regola generale. Nella maggior parte dei casi, l'esecuzione di un compilatore in fase di esecuzione significa che è necessario rinunciare a un bel po 'di ottimizzazione, quindi il meglio che si spera di solito è che è simile alla velocità di un compilatore convenzionale.

Sebbene sia possibile postulare situazioni in cui le informazioni disponibili a un compilatore JIT potrebbero consentirgli di generare codice sostanzialmente migliore di un compilatore convenzionale, casi di questo accadimento nella pratica sembrano essere piuttosto insoliti (e in la maggior parte dei casi in cui sono stato in grado di verificarne l'accadimento, era in realtà dovuta a un problema nel codice sorgente, non con il modello di compilazione statico).

    
risposta data 27.12.2010 - 03:42
fonte
10

Sì, ci sono compilatori JIT per C ++. Dal punto di vista della pura performance, penso che Profile Guided Optimization (PGO) sia ancora superiore.

Tuttavia, ciò non significa che la compilazione JIT non sia ancora stata utilizzata nella pratica. Ad esempio, Apple utilizza LLVM come JIT per la propria pipeline OpenGL. Questo è un dominio in cui sono disponibili molte più informazioni in fase di esecuzione, che possono essere utilizzate per rimuovere un sacco di codice morto.

Un'altra interessante applicazione di JIT è Cling, un interprete interattivo di C ++ basato su LLVM e Clang: link

Ecco una sessione di esempio:

[cling]$ #include <iostream>
[cling]$ std::cout << "Hallo, world!" << std::endl;
Hallo, world!
[cling]$ 3 + 5
(int const) 8
[cling]$ int x = 3; x++
(int) 3
(int const) 3
[cling]$ x
(int) 4

Non è un progetto giocattolo ma è effettivamente usato nel CERN, ad esempio, per sviluppare il codice per Large Hadron Collider.

    
risposta data 30.12.2012 - 03:59
fonte
6

C ++ / CLI è jitted. Certo, C ++ / CLI è non C ++ ma è piuttosto vicino. Detto ciò, il JIT di Microsoft non fa i tipi super intelligenti / carini di ottimizzazioni basate sul comportamento di runtime che stai chiedendo, almeno non a mia conoscenza. Quindi questo davvero non aiuta.

Il link trasforma MIPS in un bytecode Java che verrà poi jitted. Il problema con questo approccio dalla tua domanda è che getti via molte delle informazioni utili al momento in cui arriva al JIT.

    
risposta data 23.12.2010 - 03:20
fonte
1

In primo luogo, presumo che tu voglia una tracciona piuttosto che un metodo jit.

L'approccio migliore da seguire sarebbe la compilazione del codice in llvm IR, quindi l'aggiunta nel codice di tracciamento, prima di produrre un eseguibile nativo. Una volta che un blocco di codice diventa sufficientemente ben utilizzato e una volta che le informazioni sui valori (non i tipi come nei linguaggi dinamici) delle variabili sono state raccolte, il codice può essere ricompilato (dall'IR) con le protezioni basate sui valori delle variabili.

Mi sembra di ricordare che ci sono stati dei progressi nel creare un c / c ++ jit in clang sotto il nome libclang.

    
risposta data 23.12.2010 - 11:27
fonte

Leggi altre domande sui tag