2012-02-29 4 views
5

Un argomento a favore di linguaggi JIT come C# e Java è che possono ottimizzare meglio dal momento che la profilazione runtime da parte della macchina virtuale può ottimizzare il codice meglio del codice di C++ ottimizzato staticamente.Una macchina virtuale per C++ per l'ottimizzazione delle prestazioni

Tuttavia, mi chiedevo se potessimo usare anche una macchina virtuale per ottimizzare il codice in fase di esecuzione per C++, o meglio qualsiasi linguaggio simile. Ad esempio, potremmo prendere l'IR generato dal compilatore LLVM e creare una macchina virtuale che interpreti, JIT e ottimizzi il codice, analogamente a Java e C#.

Naturalmente, non ci sarebbe garbage collection, ma il fattore di ottimizzazione sarebbe lì. Qualcuno ha lavorato su questo. Ci sono documenti, strumenti su questo? Quanto sarà buono questo approccio?

+3

[Una ricerca di Google per "Clang" + "JIT"] (https://www.google.com/search?q=clang+jit) richiama molte informazioni. – ruakh

+1

Google fa qualcosa di interessante quando aggiorna Chrome ... Il programma viene parzialmente decompilato, in modo da ottenere una forma un po 'simbolica, quindi l'aggiornamento viene applicato come una patch per quel modulo e quindi viene ricompilato. Inoltre, ai vecchi tempi le persone scrivevano programmi polimorfi che si riscrivevano in fase di esecuzione (ad esempio, quando rilevano che una condizione 'if' non sarà mai falsa, sostituiranno semplicemente l'istruzione con un' nop'). Quindi, non c'è motivo per cui questo non dovrebbe essere fattibile. Non sto nemmeno menzionando "possibile", perché sappiamo che è il caso. –

+0

Possono davvero ottimizzare meglio, ma non lo fanno. –

risposta

2

In teoria, sì, è possibile creare un JIT per C++. Potrebbe trarre vantaggio da alcune cose nell'architettura sottostante per ottimizzare in modo aggressivo il codice. Avrebbe anche lo svantaggio di rendere l'applicazione più lunga da caricare in fase di esecuzione.

Naturalmente, non ci sarebbe stato garbage collection e quindi il sovraccarico dovuto ad esso, ma il fattore di ottimizzazione sarebbe lì. Ha qualcuno ha lavorato su questo. Ci sono documenti, strumenti su questo? Quanto è buono questo ?

Grande equivoco qui. Imporre GC su tutta la linea per ogni tipo definito dall'utente è un overhead importante. È uno dei motivi per cui i dispositivi mobili Android, iOS e Windows sono tutti rivolti a C/C++ per applicazioni ad alte prestazioni, nonostante l'iniziale tentativo di utilizzare inizialmente solo macchine virtuali gestite.

Ovviamente il livello aggiuntivo di riferimento indiretto indica che il GC è libero di fare cose come la memoria compatta, ma un programma C/C++ ottimizzato funzionerebbe già con la memoria compattata dall'inizio. Significherebbe anche che la memoria è inizialmente più frammentata, che è un killer delle prestazioni per il tipo di applicazioni ad alte prestazioni con C++ (una che si occupa di buffer ampi e contigui, ad esempio, come l'elaborazione video, ray tracing o audio in lavorazione).

Inoltre, trasformare ogni istanza UDT in un riferimento significa che tutto è nell'heap, il che sta effettivamente trasformando le operazioni che in origine sono un paio di cicli di clock in centinaia.

Detto questo, per arrivare al cuore della tua domanda, certo, il codice C++ può essere costruito usando JIT, ma potresti scoprire che non ci sono davvero motivi così convincenti per farlo dato cose come la natura statica in cui le persone generalmente lavorano con il codice C++.

+1

Dicendo "Non ci sarebbe garbage collection e quindi il sovraccarico dovuto ad esso", sto dicendo che poiché non ci sarebbe garbage collection, l'overhead sarebbe di meno. Lo leggi nell'altro modo :)! – MetallicPriest

+0

@MetallicPriest Oh mio male, ho pensato che la frase significava che ci sarebbe stato un sovraccarico a causa della mancanza di GC. Sono abituato agli appassionati di C#/Java che spesso affermano che GC rende in qualche modo più veloce le cose. È vero che può compattare la memoria quando non stiamo guardando, ma bisogna chiedersi perché debba farlo in primo luogo quando, in C++, possiamo semplicemente creare array contigui e compatti di tipi definiti dall'utente (come un matrice) fin dall'inizio. – stinky472

4

LLVM include un compilatore JIT, lli e Clang può già produrre bitcode da C++. Non l'ho provato, ma presumo che tu possa usare lli sui file di codice prodotto (dovresti dover dire dove trovare i file lib C++ per collegarsi) e JIT C++ in fase di runtime. Dovresti anche essere in grado di creare libC++ come bitcode in modo che possa essere anche JITed.

Il client nativo di Google ha un sottoprogetto, Portable Native Client, in cui penso che LLVM IR sia inviato al client, invece dei binari x86, da jittare sul client.

7

Questo è un argomento difettoso. Sì, le macchine virtuali hanno più informazioni su cui lavorare, ma hanno anche meno tempo e spazio rispetto ai compilatori.

Inoltre, sì, assolutamente lo puoi fare se lo vuoi davvero. Ma nessuno lo fa, quindi in genere non sta succedendo.Almeno, non per ragioni di ottimizzazione, potresti farlo per il sandboxing.

+1

Puoi precompilare C++ in bytecode come fa Clang, a quel punto puoi già fare molte ottimizzazioni. – Xeo

+1

@Xeo: Teoricamente sì. Ma l'ottimizzatore di C/C++ è piuttosto vecchio (in termini informatici) e svolge un lavoro relativamente buono. Quindi forse eventuali guadagni extra sono trascurabili. Sarebbe bello vedere qualcuno pubblicare un articolo su di esso (forse l'hanno provato trovato inutile). –