it-swarm.it

Compilatore JIT per C, C ++ e simili

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

Spiegazione:

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

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

Tuttavia, penso che sia controverso se il vantaggio in termini di prestazioni di compilazione JIT sia superiore al suo stesso sovraccarico.

33

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

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

CLing (come puoi immaginare dal gioco) si basa su Clang/LLVM. Si comporta come un interprete. Cioè, gli dai un po 'di codice sorgente, gli dai un comando per l'esecuzione, e viene eseguito. L'enfasi qui è principalmente sulla convenienza e sulla compilazione veloce, non sulla massima ottimizzazione. In quanto tale, sebbene tecnicamente una risposta alla domanda stessa, ciò non soddisfa molto bene l'intento del PO.

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

Per quanto riguarda l'intento apparente della domanda originale, penso che il punto fondamentale della mia risposta originale sia ancora valido: mentre un compilatore JIT può adattarsi a cose come i dati che varia da un'esecuzione all'altra, o anche variando dinamicamente durante una singola esecuzione, la realtà è che questo fa una differenza relativamente piccola almeno come regola generale. Nella maggior parte dei casi, eseguire 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 sia vicino alla velocità che un compilatore convenzionale produrrebbe.

Sebbene sia possibile postulare situazioni in cui le informazioni disponibili per un compilatore JIT potrebbero consentire a quest'ultimo di generare un codice sostanzialmente migliore rispetto a un compilatore convenzionale, nella pratica si verificano casi di questo sembra essere abbastanza insolito (e nella maggior parte dei casi in cui sono stato in grado di verificarne il verificarsi, è stato davvero a causa di un problema nel codice sorgente, non con il modello di compilazione statica).

33
Jerry Coffin

Sì, ci sono compilatori JIT per C++. Dal punto di vista della prestazione pura, penso che l'ottimizzazione guidata profilo (PGO) sia ancora superiore.

Tuttavia, ciò non significa che la compilazione JIT non sia ancora utilizzata nella pratica. Ad esempio, Apple utilizza LLVM come JIT per la propria pipeline OpenGL. Questo è un dominio in cui sono presenti molte più informazioni in fase di runtime, che possono essere utilizzate per rimuovere molti codici morti.

Un'altra interessante applicazione di JIT è Cling, un interprete C++ interattivo basato su LLVM e Clang: https://root.cern.ch/cling

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 in realtà viene utilizzato nel CERN, ad esempio, per sviluppare il codice per Large Hadron Collider.

11
Philipp Claßen

C++/CLI è jeds. Concesso, C++/CLI è non C++ ma è piuttosto vicino. Detto questo, JIT di Microsoft non fa i tipi super intelligenti/carini di ottimizzazioni basate sul comportamento di runtime di cui stai chiedendo, almeno non per quanto ne so. Quindi questo non aiuta davvero.

http://nestedvm.ibex.org/ trasforma MIPS in Java bytecode che verrebbe poi spazzato via. Il problema con questo approccio dalla tua domanda è che butti via molte informazioni utili quando arrivano alla JIT.

7
Logan Capaldo

In primo luogo, suppongo che vorresti un jit di traccia piuttosto che un metodo jit.

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

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

2
dan_waterworth