12

Sto facendo un sondaggio di funzionalità in preparazione per un progetto di ricerca.Lingue e macchine virtuali: funzionalità difficili da ottimizzare e perché

Denominare una lingua o una lingua tradizionale che è difficile da ottimizzare, e perché la funzione è o non vale il prezzo pagato, o, invece, solo ridimensionare le mie teorie di seguito con prove aneddotiche. Prima che qualcuno segnali questo come soggettivo, sto chiedendo esempi specifici di lingue o funzionalità e idee per l'ottimizzazione di queste funzionalità o caratteristiche importanti che non ho considerato. Inoltre, ogni riferimento a implementazioni che dimostrino le mie teorie giuste o sbagliate.

superiore sulla mia lista di difficile da ottimizzare le caratteristiche e le mie teorie (alcune delle mie teorie sono testati e sono basate su esperimenti di pensiero):

1) Runtime overloading dei metodi (aka multi-metodo di spedizione o la firma spedizione base). È difficile ottimizzare se combinato con funzionalità che consentono la ricompilazione o l'aggiunta di un metodo. O è solo difficile, comunque? Chiamare il caching del sito è una ottimizzazione comune per molti sistemi runtime, ma i multi-metodi aggiungono complessità aggiuntiva e rendono meno pratico i metodi in linea.

2) Tipo morphing/varianti tipizzazione basato (aka valore al contrario di variabile in funzione) ottimizzazioni tradizionali semplicemente non può essere applicato quando non si sa se il tipo di someting può cambiare in un blocco di base. Combinato con multi-metodi, l'inlining deve essere fatto con attenzione se non del tutto, e probabilmente solo per una data soglia di dimensione del callee. vale a dire. è facile prendere in considerazione la creazione di fasci di proprietà semplici (getter/setter), ma l'integrazione di metodi complessi può causare un aumento di codice. L'altro problema è che non posso semplicemente assegnare una variante a un registro e JIT alle istruzioni native perché devo portare in giro le informazioni sul tipo, o ogni variabile ha bisogno di 2 registri invece di 1. Su IA-32 questo è scomodo, anche se migliorato con i registri extra di x64. Questa è probabilmente la mia caratteristica preferita dei linguaggi dinamici, in quanto semplifica moltissime cose dal punto di vista del programmatore.

3) continuazioni di prima classe - Ci sono diversi modi per la loro attuazione, e mi hanno fatto in entrambi gli approcci più comuni, uno è la copia dello stack e l'altro come attuare il runtime di utilizzare lo stile continuazione di passaggio, pile di cactus, cornici stack copy-on-write e garbage collection. Le continuazioni di prima classe hanno problemi di gestione delle risorse, es. dobbiamo salvare tutto, nel caso in cui la continuazione sia ripresa, e non sono a conoscenza se alcune lingue supportano il fatto di lasciare una continuazione con "intento" (cioè. "Non tornerò qui, quindi puoi scartare questa copia del mondo"). Avendo programmato nel modello di threading e nel modello di contination, so che entrambi possono ottenere la stessa cosa, ma l'eleganza delle continuazioni impone una notevole complessità al runtime e può anche influire sull'efficienza della cache (la localizzazione delle modifiche dello stack più con l'uso di continuazioni e co-routine). L'altro problema è che non si associano all'hardware. Ottimizzare le continuazioni si sta ottimizzando per il caso meno comune e, come sappiamo, il caso comune dovrebbe essere veloce e i casi meno comuni dovrebbero essere corretti.

4) Aritmetica del puntatore e possibilità di mascherare i puntatori (memorizzazione in numeri interi, ecc.) Doveva lanciare questo, ma potrei davvero vivere senza questo abbastanza facilmente.

I miei sentimenti sono che molte delle funzioni di alto livello, in particolare nelle lingue dinamiche , semplicemente non si associano all'hardware. Le implementazioni del microprocessore hanno miliardi di dollari di ricerca dietro le ottimizzazioni sul chip, tuttavia la scelta delle caratteristiche linguistiche può marginalizzare molte di queste caratteristiche (funzionalità come la cache, aliasing top of stack da registrare, parallelismo delle istruzioni, buffer degli indirizzi di ritorno, loop buffer e previsione dei rami).Le macro-applicazioni di micro-funzioni non si espandono necessariamente come piace pensare a qualche sviluppatore, e l'implementazione di molti linguaggi in una VM finisce per mappare le operazioni native in chiamate di funzione (ad esempio, più una lingua è dinamica e più dobbiamo cercare/cache in fase di runtime, nulla può essere assunto, quindi il nostro mix di istruzioni è costituito da una percentuale maggiore di branching non locale rispetto al codice compilato staticamente tradizionale e l'unica cosa che possiamo davvero bene JIT è la valutazione dell'espressione di tipi non dinamici e operazioni su tipi costanti o immediati. A mio parere, le macchine virtuali e i core JIT del codice byte non sono forse sempre giustificati per alcune lingue.

Apprezzo le tue risposte.

+0

Forse dovrebbe essere CW? –

risposta

5

Un paio di commenti:

  • tutte le lingue Con la spedizione dinamica, anche sulla base di un singolo oggetto, sembrano piuttosto difficile da attuare in maniera efficace. Guarda tutto lo sforzo compiuto nell'ottimizzazione run-time di Self (o più recentemente, JavaScript, con SpiderMonkey).

  • Non trascurare continuazioni delimitate. La giuria è ancora fuori, ma sono significativamente più facili da ottimizzare rispetto alle continuazioni classiche non rimandate. Leggi l'articolo di Gasbichler e Sperber.

1

è la mia sensazione viscerale che bytecode macchine virtuali e core JIT sono forse non sempre giustificato per alcune lingue a causa di questo.

Non hai IronPython ottenere scritto per dimostrare che una macchina virtuale non poteva fare così come l'implementazione nativa del linguaggio (Python). E poi l'autore di IronPython è rimasto piuttosto scioccato quando ha scoperto che IronPython si è comportato molto bene per un linguaggio dinamico su una VM bytecode?

Il gruppo interno di .Net di Microsoft ha dichiarato di ritenere che alla fine il JITter supererà un compilatore/linker "normale" (per esempio C/C++).

Penso che la giuria sia ancora fuori su questo. Difficile chiamarlo in entrambi i modi. Scegli la lingua che meglio si adatta al lavoro ...

+0

"Scegli la lingua che meglio si adatta al lavoro ..." - Grazie, sono d'accordo, ma questo non è l'obiettivo della mia domanda. Riguarda l'ottimizzazione e le funzionalità, in particolare. Per quanto riguarda IronPython, non conosco la risposta alla tua domanda, ma mi interessa leggere se hai riferimenti che posso seguire. – codenheim

+0

La mia domanda era retorica. IronPython era così buono da smentire la teoria secondo cui i linguaggi dinamici non erano adatti per le macchine virtuali bytecode. Da qui il paragrafo successivo su Microsoft che supporta quel punto di vista. E quello conduce all'ultimo paragrafo. Preoccuparsi se un linguaggio dinamico è adatto manca il punto. Sono (supponendo che la VM sia abbastanza buona, alcuni di loro non lo sono), quindi puoi semplicemente scegliere la lingua migliore per il lavoro. –

+0

Questa domanda non riguarda se una lingua è adatta, quindi ti preghiamo di tenerla sull'argomento. Sono un linguista e ricercatore/implementatore di macchine virtuali e sto parlando di ottimizzazioni specifiche delle funzionalità e stai parlando di "scegliere lo strumento migliore per il lavoro". Scrivo strumenti per il lavoro. Ora, per IronPython, è un esempio utile, ma alcune delle funzionalità che ho elencato non sono presenti in Python. Python non ha chiusure reali (le variabili sono di sola lettura) o continuazioni di prima classe (CPS non è la stessa cosa). IronPython dimostra che Python può essere implementato bene su CLR, non che tutte le lingue possano. – codenheim