-
-
Re: x alex,tg: linoleum vs llvm vs assemScritto daNon Autenticatoil 2010-11-19 15:10:00.0 alle 2010-11-19 15:10:00.0> mi spieghi le differenze che io non ci
> capisco?
Non puoi usare uno dei thread esistenti invece di aprirne uno nuovo powered by Sere1?
-
Re: x alex,tg: linoleum vs llvm vs assem
- Scritto da:
> > mi spieghi le differenze che io non ci
> > capisco?
>
> Non puoi usare uno dei thread esistenti invece di
> aprirne uno nuovo powered by Sere1?
>
Gli altri thread parlano di licenze e di futile resistenza alla gpl: verrete tutti assimilati.-
Re: x alex,tg: linoleum vs llvm vs assemScritto daNon Autenticatoil 2010-11-19 15:16:00.0 alle 2010-11-19 15:16:00.0> > > mi spieghi le differenze che io non ci
> > > capisco?
> >
> > Non puoi usare uno dei thread esistenti invece
> di
> > aprirne uno nuovo powered by Sere1?
> >
>
> Gli altri thread parlano di licenze e di futile
> resistenza alla gpl: verrete tutti assimilati.
Ah allora sei giustificato.
Più che altro quando arriva alex.tg vorrei che ci riassumesse le sue intenzioni. Condivido il suo timore di fondo ma non vorrei che i timori gli ottenebrassero la vista delle opportunità.
-
-
-
Re: x alex,tg: linoleum vs llvm vs assemLLVM?
Aspe', prima vado a vedere cos'e`...
Ah, ecco. Prima differenza che mi viene in mente e` che, stando alla wiki, e` del 2003, cioe` ci hanno pensato dopo che io avevo avuto bisogno di qualcosa come Linoleum. Mica e` colpa mia se sono arrivati troppo tardi e m'ero gia` fatto da solo e m'erano venute le occhiaie. Il concetto (mio) antenato di Linoleum, che chiamavo originariamente BULK, era del '97.
Ora cerco di capire come funziona e ti dico se ci sono differenze e quali...-
Re: x alex,tg: linoleum vs llvm vs assemLLVM
Anche Linoleum comincia per L.
can provide the middle layers of a complete compiler system, taking intermediate form (IF) code from a compiler and outputting an optimized IF that can then be converted and linked into machine-dependent assembler code for a target platform.
Linoleum non produce ne` importa object code, non parla con nessun'altro "compilatore" se non se` stesso. Il compilatore Linoleum fa da compilatore, assemblatore e linker tutto in uno e passa direttamente da codice sorgente a file eseguibile.
LLVM can accept the IF from the GCC toolchain, allowing it to be used with a wide array of existing compilers written for that project.
Linoleum vive nel suo mondo solitario e non accetta regali dagli sconosciuti. E` affetto da asperger o forse autismo ad alta funzionalita`, di preciso non saprei dire.
LLVM can also generate relocatable machine code at compile-time or link-time or even binary machine code at run-time.
Linoleum genera sempre codice macchina rilocabile al momento di compilare. Mai nel runtime.
LLVM supports a language-independent instruction set and type system.
Linoleum e` uguale.
Each instruction is in static single assignment form (SSA), meaning that each variable (called a typed register) is assigned once and is frozen. This helps simplify the analysis of dependencies among variables.
In Linoleum ogni istruzione e` convertita in un compatibility pattern e ogni operando va a rimpiazzare un ISMO (Instruction Set Mobile Operand). In soldoni, anche se i dettagli sono un po' meno banali, il compilatore fondamentalmente concatena "moduli" riempiendo gli spazi.
LLVM allows code to be compiled statically, as it is under the traditional GCC system,
Linoleum solo questo.
or left for late-compiling from the IF to machine code in a just-in-time compiler (JIT) in a fashion similar to Java.
No, mai.
O e` umanamente leggibile o e` eseguibile, niente compromessi.
The type system consists of basic types such as integers or floats and five derived types: pointers, arrays, vectors, structures, and functions.
Il type system consiste di un tipo: l'unita`. Una locazione di memoria delle dimensioni della parola dell'architettura ospite. L'indirizzamento n-flat e` un indirizzamento di tipo flat, a origine locale, i cui elementi discreti sono unita`, non bytes o altro. Cosa ci fai con ciascuna unita` sono rigorosamente cazzi tuoi nei quali il compilatore non ti rompera` i coglioni. Ovviamente, anche gli errori catastrofici saranno tutti tuoi, stupido essere umano.

For example, a class in C++ can be represented by a combination of structures, functions and arrays of function pointers.
Oh anche in Linoleum, una volta che hai stabilito nel tuo codice (o in una libreria) cos'e` una struttura, una funzione, un vettore di puntatori a funzioni, una volta che hai un heap, e tutte le seghe mentali necessarie agli stupidi esseri umani.

The LLVM JIT compiler is capable of optimizing unnecessary static branches out of a program at runtime, and is therefore useful for partial evaluation in cases where a program has many optionsmost of which can easily be determined unnecessary in a specific environment. This feature is used in the OpenGL pipeline of Mac OS X Leopard (v10.5) to provide support for missing hardware features.[2] Graphics code within the OpenGL stack was left in intermediate form, and then compiled when run on the target machine. On systems with high-end GPUs the resulting code was quite thin, passing the instructions onto the GPU with minimal changes. On systems with low-end GPUs, LLVM would compile optional procedures that run on the local CPU that emulate instructions that the GPU cannot run internally. LLVM was instrumental in improving performance on low-end machines using Intel GMA chipsets.
Huh? Se vuoi proteggerti dalle cose inutili, non ce le metti in prima istanza. Il compilatore Linoleum puo` selezionare, al momento della compilazione, parti specifiche di una piattaforma (chipset ed SO) se ce n'e` bisogno. Automaticamente andando a cercare diverse versioni di una libreria. Spesso le librerie in Linoleum 2 sono qualcosa di simile a degli oggetti, vivono nel loro namespace e contengono un solo aspetto, il che si tradyce spesso in una sola funzione. Sono "a grana fine". D'altra parte, per fare un'applicazione decente devi raggranellare un fottio di libreriette singole.
On the other hand, in the cases where raw performance is benchmarked, LLVM trails GCC in code quality (speed of the compiled programs) by about 10% on average,
Linoleum non inserisce nel tuo codice seghe mentali, esegue e basta. Molti compatibility patterns del set d'istruzioni orientato all'applicazione si risolvono in un'istruzione atomica, con un rapporto di 1:1 tra il listato Linoleum e il risultante disassemblato dell'eseguibile. Senza seghe mentali (overheads) quel che ottieni e` di solito parecchio veloce.
while compiling 20-30% faster.
Mah, Linoleum compila, assembla e linka. Non dovrebbe essere lento nel farlo. Boh, qui compila se` stesso e le sue librerie (circa 30mila righe) in 0,275 secondi, e non e` che personalmente mi annoi molto ad aspettarlo. Ah, il compilatore e` scritto in Linoleum da uno che aveva la mania, attraverso tutto il listato (21476 righe), di palleggiarsi a mano i dati di piu` frequente accesso nei registri della CPU, avendo anche cura di disporre le istruzioni in modo che risultassero indipendenti su piu` pipelines.
oh no ho sforato il cazzo di limite 7000 caratteri-
Re: x alex,tg: linoleum vs llvm vs assemil resto era:
L'articolo non parla della Virtual Machine di LLVM. Linoleum la chiama modulo di run-time (run-time module), ma e` fondamentalmente una virtual machine. Quello che Linoleum chiama run-time kernel e` una virtual machine che gira direttamente sul firmware ed espone all'applicazione la stessa interfaccia che troverebbe sugli altri sistemi operativi. L'interfaccia in questione si chiama (sia nei run-time modules che nei run-time kernels) "isokernel", ed e` vista come una funzione booleana dall'applicazione, che la conosce (e chiama) per puntatore. L'isokernel analizza le richieste dell'applicazione rilevando cambiamenti in certe variabili e bitmaps di stato (nel workspace e nel namespace globale dell'intera applicazione) che hanno un significato "universale", le traduce in richieste per il sistema ospite, preleva i risultati, li ri-traduce in una forma "universale", e li restituisce in altre variabili di stato. Per esempio:with, [thread command] = suspend thread; [thread suspend timeout] = 1000; isocall;
L'istruzione che chiama l'isokernel e` "isocall", che il compilatore lascia scrivere cosi` per brevita` ma che traduce in "perform: [isokernel]", ovvero "esegui la subroutine, che in questo caso si sa essere funzione booleana, il cui puntatore e` depositato nella locazione, o unita`, del workspace, identificato dall'indirizzo corrispondente al valore della costante 'isokernel'". Questa subroutine rileva che [thread command], ovvero il contenuto dell'unita` all'indirizzo dato dal valore della costante 'thread command', e` stato assegnato a un codice di comando (numerico e costante) etichettato 'suspend thread'. Entra quindi in un suo branch che esegue quel comando, traducendolo nel caso di Windows in:; ; [thread command] = suspend thread ; hc_suspendThread: invoke Sleep, dword ptr [edi + THREADSUSPENDTIMEOUT * 4] retn ; to ik_retn in ik_executeCommands
e nel caso del run-time kernel in:hc_suspendThread: call @@mpcallrate imul eax, [edi + rm_ThreadSuspendTimeout * 4] cdq mov ecx, 1000 div ecx mov ds:[@stout], eax hc_idleLoop: hlt cmp ds:[@stout], esi jg short hc_idleLoop ret ; ik_execute_cmd
e cioe` prendendo in considerazione l'argomento [thread suspend timeout] come un valore espresso in millisecondi.-
Re: x alex,tg: linoleum vs llvm vs assemScritto daNon Autenticatoil 2010-11-20 00:51:00.0 alle 2010-11-20 00:51:00.0straGARAGULP!
A che punto è la documentazione?
Esiste un papiro introduttivo per la nuova versione? Ponce ne scriverà uno?
-
Re: x alex,tg: linoleum vs llvm vs assem> straGARAGULP!
Avevo calibrato il post sulla mente-spugna da QI>=180 di Sviatofork.
> A che punto è la documentazione?
Allo stesso punto di prima dell'estate.
E allora che me rido a fa'? Boh, era per non piangere.
> Esiste un papiro introduttivo per la nuova
> versione? Ponce ne scriverà
> uno?
>
>
Immagino di si`, cosi` come immagino che lui o qualcun'altro lo fara` quando avra` capito come funziona esattamente, cosa che appunto ancora non ho avuto molto tempo... ehm... molta voglia di spiegare. Pero` nel post di sopra, l'accenno a come funge l'isokernel non m'e` venuto malissimo. Me lo annoto mentalmente per arricchirlo un po', magari con schemini esplicativi, e passarlo nella documentazione.-
Re: x alex,tg: linoleum vs llvm vs assemScritto daNon Autenticatoil 2010-11-20 14:47:00.0 alle 2010-11-20 14:47:00.0> > straGARAGULP!
>
> Avevo calibrato il post sulla mente-spugna da
> QI>=180 di
> Sviatofork.
>
> > A che punto è la documentazione?
>
> Allo stesso punto di prima dell'estate.
> E allora che me rido a fa'? Boh, era per non
> piangere.
E io che non ho la spugna di sfiatopork come farò a imparare?-
Re: x alex,tg: linoleum vs llvm vs assem> > > straGARAGULP!
> >
> > Avevo calibrato il post sulla mente-spugna da
> > QI>=180 di
> > Sviatofork.
> >
> > > A che punto è la documentazione?
> >
> > Allo stesso punto di prima dell'estate.
> > E allora che me rido a fa'? Boh, era per non
> > piangere.
>
> E io che non ho la spugna di sfiatopork come farò
> a
> imparare?
Ma con la documentazione, no?
Ehm... no aspe', non e` che ti prenda per i fondelli...
mettiamola cosi`, in modo che secondo me riflette sia la realta`, o almeno un modo di descrivere la realta` che a me sembra appropriato, e che allo stesso tempo dovrebbe risultare incoraggiante:
Linoleum e` composto da relativamente poche regole, un po' come la "teoria del tutto" che la fisica va cercando. Cioe`, ora, non ha niente in comune, in termini di gloria, con un "santo graal" del genere, ma ha in comune la semplicita`. Pero` questa non corrisponde necessariamente a immediata leggibilita`, e quel che ne salta fuori puo` essere, nel complesso, quanto mai astruso.
Per chiarire, se uno si spaventa per i dettagli di quel particolare modulo o kernel di run-time, quelli sono scritti in assembly nativo dell'architettura x86 (o IA-32). Quello e` proprio assembly, e l'avevo messo per illustrare dove va a finire il processore in risposta a una richiesta fatta all'isokernel. A chi programma in Linoleum quello che fa il modulo di run-time non interessa, anche perche` lo farebbe in modo diverso a seconda dell'architettura ospite, per girare sulla quale un'applicazione venisse compilata. Potrebbe interessare pero`, per capire come manipolare, quando e se si rende necessario, l'ambiente di esecuzione della propria applicazione, la modalita` in cui l'isokernel risponde alle richieste: questa fa parte delle nozioni relative al "con cosa si ha a che fare".
Nel caso delle chiamate all'isokernel, che so, un giorno qualcuno, volendo "espandere" in qualche modo la funzionalita` dell'isokernel, e sapendo che qualunque chiamata all'isokernel (comune ai threads) si riferisce a quel puntatore, potrebbe ritenere opportuno piazzare del codice attorno a ciascuna chiamata facendo in modo che le chiamate non vadano direttamente all'isokernel, ma a una propria subroutine che lo "espanda", chiamando il suo puntatore originario "tra le altre cose". In soldoni, in quel caso basterebbe sostituire il contenuto della variabile [isokernel] con l'indirizzo alla propria subroutine; una subroutine che, classificandola un po' meglio, al pari dell'isokernel dovrebbe comportarsi come una funzione booleana, ovvero ritornare al chiamante uno stato "errore/successo".
Ma di per se` un listato Linoleum e` costruito sulla base di poche regole ereditate o stabilite (da me) a priori, e da molte regole stabilite dallo sviluppatore della propria applicazione, oppure dalle librerie usate. E` un po' come giocare col pongo, insomma: Linoleum e` flessibile, diventa quel che si vuole. Questo perche`, in onore al suo nome che non si riferisce solo al vecchio pezzo punk dei NoFX, ha anche molto in comune con l'omonima copertura per pavimenti: si usa per rendere relativamente liscia una superficie sconnessa. In quest'ottica, rappresenta un qualcosa su cui costruire un ambiente, ma appunto, si limita al pavimento e non aggiunge mobilia, lasciandola tutta all'arredatore. Le chiamate all'isokernel sono una delle poche regole da prendere in considerazione, sotto la voce: "col sistema ospite, su cui l'applicazione gira, ci si interfaccia cosi`".
Altre regole di base sono:
- l'applicazione ha a disposizione solo una parte della memoria centrale del computer, che si chiama "workspace";
- il workspace e` nient'altro che un lungo vettore di elementi chiamati "unita`" (di memoria), numerati progressivamente da zero in su`;
- ciascuna unita` di memoria e` costituita da tanti bits quanti ne stanno in ogni "parola" del microprocessore: se l'architettura e` a 32 bit, un'unita` ha 32 bits, se e` a 64 bit ne ha 64, e cosi` via;
- il workspace si puo` ridimensionare (cambiando una variabile di controllo chiamata [ramtop] e chiamando l'isokernel), ma dato che questo tipo di modifica e` globale - agisce cioe` sullo stato di TUTTA l'applicazione - di solito e` meglio definire (o scegliere gia` pronto) un modo piu` sofisticato per gestire il workspace unico spezzettandolo e dimensionandolo automaticamente quando una parte dell'applicazione, librerie incluse, richiede un po' di memoria nel workspace: qui entrerebbe in gioco un gestore dell'heap; ma come il resto del mobilio, il gestore dell'heap e` sia opzionale (anche se di fatto spesso necessario, se l'applicazione e` decentemente complessa o usa librerie che vi si appoggiano) che "a scelta" dell'arredatore.
Anche le regole di sintassi sono poche:
- qualsiasi istruzione termina con un punto e virgola;
- quasi ovunque nel sorgente (uniche eccezioni i periodi "libraries" e "stockfile", dove si specificano nomi di file completi di percorsi relativi) ciascuna istruzione e` composta da un "codice simbolico" che identifica l'operazione, e da operandi: il codice simbolico e` composto da tutti i segni non facenti parte dei caratteri con cui si scrivono le espressioni lineari (i caratteri alfanumerici piu` le parentesi quadre, il punto decimale e l'underscore); il resto dell'istruzione sono gli operandi, delimitati dai segni stessi, e costituiti da espressioni;
- le espressioni possono essere anche costituite da un solo "simbolo", inteso come il nome di un registro, di una variabile, di una costante, di un'etichetta di codice o del workspace;
- a seconda di quali simboli si usano nelle espressioni, si realizzano vari tipi di "indirizzamento", cioe` di modi di riferirsi ai contenuti della memoria (del workspace);
- in proposito, una cosa importantissima da capire e` che mettere l'intera espressione tra parentesi quadre realizza quel che si chiama "indirizzamento diretto", cioe` quell'espressione sta a significare, nel ruolo di operando di un'istruzione, che ci si riferisce al CONTENUTO dell'unita` del workspace il cui indirizzo e` il risultato dell'espressione; ad esempio, "[isokernel]" e` proprio un operando del genere: l'espressione e` costituita dalla sola costante chiamata "isokernel", e dato il di cui sopra, significa il contenuto dell'unita` che ha l'indirizzo corrispondente al valore della costante "isokernel".
um... temo che tutto il manuale non possa scrivero qui nei 7000 caratteri del MARGINE del messaggio. Pero` magari da` un'idea.
-
Re: x alex,tg: linoleum vs llvm vs assemScritto daNon Autenticatoil 2010-11-20 19:12:00.0 alle 2010-11-20 19:12:00.0> - ciascuna unita` di memoria e` costituita da
> tanti bits quanti ne stanno in ogni "parola" del
> microprocessore: se l'architettura e` a 32 bit,
> un'unita` ha 32 bits, se e` a 64 bit ne ha 64, e
> cosi` via;
Ummmete... non dà problemi di portabilità? Tipo un'applicazione presuppone unità di memoria a 64 bit, ma quando viene eseguita su una macchina a 32 bit l'applicazione non può più far stare nelle celle i dati che manipolava in origine.-
Re: x alex,tg: linoleum vs llvm vs assem> > - ciascuna unita` di memoria e` costituita da
> > tanti bits quanti ne stanno in ogni "parola" del
> > microprocessore: se l'architettura e` a 32 bit,
> > un'unita` ha 32 bits, se e` a 64 bit ne ha 64, e
> > cosi` via;
>
> Ummmete... non dà problemi di portabilità? Tipo
> un'applicazione presuppone unità di memoria a 64
> bit, ma quando viene eseguita su una macchina a
> 32 bit l'applicazione non può più far stare nelle
> celle i dati che manipolava in
> origine.
Si`, e` inevitabile, infatti il compilatore incoraggia a usare una direttiva nei sorgenti che non sono "agnostici" relativamente alla dimensione delle unita`: la direttiva "unit = 32". Questa ferma il compilatore con un errore se la dimensione specificata nel sorgente non corrisponde a quella dell'architettura-bersaglio per cui si sta tentando di generare l'eseguibile.
Come gestire queste differenze, e quelle di "endianness", e` uno dei punti piu` lunghi e difficili da0 spiegare. All'atto pratico, pero`, di problemi ce ne sono relativamente pochi, specie se l'accesso a stringhe di bit nelle unita` e` centralizzato in apposite librerie (che sono sempre state disponibili: data/bits e data/bytes). Altro modo per aggirare questi problemi senza ricorrere a (piu` lente) chiamate a funzioni di librerie e` usare manipolazioni binarie (shifts, mascheramenti, rotazioni...) calcolate in base alle costanti dipendenti dall'architettura: per questo molti listati includono per prima cosa la libreria che fornisce queste costanti, ovvero "arch/cpu/base". Di per se`, le istruzioni Linoleum considerano bits e bytes sempre disposti in uno schema big-endian. Ti faccio un esempio:a & ff000000h; a > 24;
Isola il primo byte (o byte #0, o byte piu` significativo) del registro A. L'equivalente C sarebbe:
a = (a & 0xff000000) >> 24;
Ma questo lega il sorgente a unita` di 32 bit.
Se invece lo scrivo come:a & arch . first byte; a > [arch . bits per unit] minus 8;
Lo rendo "agnostico" alla dimensione delle unita`: al momento di scegliere la versione della libreria "arch" corrispondente al parametro "--cpu", il compilatore seleziona ad esempio "main/lib/arch/i386/base" e dichiara una costante "first byte" nel namespace "arch" che vale ff000000. Allo stesso modo sa che "arch . bits per unit" vale 32 e sottraendo 8 trova 24. Ma per un processore a 64 bit troverebbe una costante "first byte" che vale ff00000000000000 e l'altra che vale 64, trasformando automaticamente il codice sopra in:a & ff00000000000000h; a > 56;
La stessa libreria fornisce funzioni che trattano la lettura e la scrittura di dati conservati in una "endianness" standard (ovvero big endian) perche` possano essere scambiati tra architetture diverse, ad esempio "arch . file read" ed "arch . file write". Il resto dei problemi tipici sono appunto gli overflows interi e le parziali perdite di precisione in virgola mobile. C'e` quindi si`, del lavoro da fare per portare un sorgente che fa affidamento sugli overflows, o sulla capacita` delle unita` di contenere numeri piu` grandi di 2 32, o sull'accesso diretto ai bits che compongono un'unita`, ma i casi sono relativamente pochi, ben noti e, secondo me, gestibili. D'altronde, mi sa che non e` che ci sia molto altro da fare.-
Re: x alex,tg: linoleum vs llvm vs assemum... magari ho detto male una cosa: piu` che "considerare" bits e bytes in big-endian, librerie e costanti citate li "enumerano" con quell'ordine. All'interno di un'unita`, l'ordine e` per forza "da sinistra verso destra e dal bit piu` significativo al meno significativo".
-
Re: x alex,tg: linoleum vs llvm vs assemScritto daNon Autenticatoil 2010-11-20 21:39:00.0 alle 2010-11-20 21:39:00.0> > > - ciascuna unita` di memoria e` costituita da
> > > tanti bits quanti ne stanno in ogni "parola"
> del
> > > microprocessore: se l'architettura e` a 32
> bit,
> > > un'unita` ha 32 bits, se e` a 64 bit ne ha
> 64,
> e
> > > cosi` via;
> >
> > Ummmete... non dà problemi di portabilità? Tipo
> > un'applicazione presuppone unità di memoria a 64
> > bit, ma quando viene eseguita su una macchina a
> > 32 bit l'applicazione non può più far stare
> nelle
> > celle i dati che manipolava in
> > origine.
>
> Si`, e` inevitabile, infatti il compilatore
> incoraggia a usare una direttiva nei sorgenti che
> non sono "agnostici" relativamente alla
> dimensione delle unita`: la direttiva "unit =
> 32". Questa ferma il compilatore con un errore se
> la dimensione specificata nel sorgente non
> corrisponde a quella dell'architettura-bersaglio
> per cui si sta tentando di generare
> l'eseguibile.
>
> Come gestire queste differenze, e quelle di
> "endianness", e` uno dei punti piu` lunghi e
> difficili da0 spiegare. All'atto pratico, pero`,
> di problemi ce ne sono relativamente pochi,
> specie se l'accesso a stringhe di bit nelle
> unita` e` centralizzato in apposite librerie (che
> sono sempre state disponibili: data/bits e
> data/bytes). Altro modo per aggirare questi
> problemi senza ricorrere a (piu` lente) chiamate
> a funzioni di librerie e` usare manipolazioni
> binarie (shifts, mascheramenti, rotazioni...)
> calcolate in base alle costanti dipendenti
> dall'architettura: per questo molti listati
> includono per prima cosa la libreria che fornisce
> queste costanti, ovvero "arch/cpu/base". Di per
> se`, le istruzioni Linoleum considerano bits e
> bytes sempre disposti in uno schema big-endian.
> Ti faccio un
> esempio:
>
>a & ff000000h; > a > 24;
>
> Isola il primo byte (o byte #0, o byte piu`
> significativo) del registro A. L'equivalente C
> sarebbe:
>
> a = (a & 0xff000000) >> 24;
>
> Ma questo lega il sorgente a unita` di 32 bit.
> Se invece lo scrivo come:
>
>a & arch . first byte; > a > [arch . bits per unit] minus 8;
>
> Lo rendo "agnostico" alla dimensione delle
> unita`: al momento di scegliere la versione della
> libreria "arch" corrispondente al parametro
> "--cpu", il compilatore seleziona ad esempio
> "main/lib/arch/i386/base" e dichiara una costante
> "first byte" nel namespace "arch" che vale
> ff000000. Allo stesso modo sa che "arch . bits
> per unit" vale 32 e sottraendo 8 trova 24. Ma per
> un processore a 64 bit troverebbe una costante
> "first byte" che vale ff00000000000000 e l'altra
> che vale 64, trasformando automaticamente il
> codice sopra
> in:
>
>a & ff00000000000000h; > a > 56;
>
> La stessa libreria fornisce funzioni che trattano
> la lettura e la scrittura di dati conservati in
> una "endianness" standard (ovvero big endian)
> perche` possano essere scambiati tra architetture
> diverse, ad esempio "arch . file read" ed "arch .
> file write". Il resto dei problemi tipici sono
> appunto gli overflows interi e le parziali
> perdite di precisione in virgola mobile. C'e`
> quindi si`, del lavoro da fare per portare un
> sorgente che fa affidamento sugli overflows, o
> sulla capacita` delle unita` di contenere numeri
> piu` grandi di 2 32, o sull'accesso diretto ai
> bits che compongono un'unita`, ma i casi sono
> relativamente pochi, ben noti e, secondo me,
> gestibili. D'altronde, mi sa che non e` che ci
> sia molto altro da
> fare.
Non ho comunque capito la logica e lo scopo di avere unità di dimensione diversa su architetture diverse. Non si poteva fare 32 per tutti?-
Re: x alex,tg: linoleum vs llvm vs assem> Non ho comunque capito la logica e lo scopo di
> avere unità di dimensione diversa su architetture
> diverse. Non si poteva fare 32 per
> tutti?
Non e` una scelta, ma una necessita`: se un processore e` a 32 bit, ha registri di 32 bits e sposta dati preferibilmente in gruppi di 32 bits. Se e` a 64 ma lo puoi (ammesso che si possa) far funzionare a 32 (IA-64 puo`, come del resto sia AMD-64 che IA-32 possono funzionare anche a 16 bit), a parte dimezzare il suo spazio d'indirizzamento e la "larghezza di banda" nei passaggi di dati tra memoria e registri, nel farlo le prestazioni degradano sensibilmente. Sarebbe un po' come dire a un destro di scrivere con la sinistra: e` stato "progettato" per usare la destra, percio` si trova spiazzato ed e` piu` lento nell'usare la sinistra. Una CPU a 32 bit deve "pensarci su", per operare a 16 bit.
Comunque, non e` che l'attuale AMD-64 o x86-64 non possa far funzionare programmi Linoleum a 32 bit (anche perche` mancano versioni a 64 bit del run-time module e del set d'istruzioni operante in "long mode"), pero` non ne sfrutta i vantaggi e per giunta si trova relativamente penalizzata rispetto ad applicazioni a 64 bit.
Se posso fare una previsione azzardata, ma secondo me plausibile, una volta che Linoleum e altri software a 32 bit saranno interamente passati ai 64 bit, avranno fatto l'ultimo doloroso "salto del fosso" per tutto il secolo. Insomma, er... 64 bit di spazio d'indirizzamento dovrebbero bastare per tutti™.-
Re: x alex,tg: linoleum vs llvm vs assemScritto daNon Autenticatoil 2010-11-20 23:00:00.0 alle 2010-11-20 23:00:00.0> > Non ho comunque capito la logica e lo scopo di
> > avere unità di dimensione diversa su
> architetture
> > diverse. Non si poteva fare 32 per
> > tutti?
>
> Non e` una scelta, ma una necessita`: se un
> processore e` a 32 bit, ha registri di 32 bits e
> sposta dati preferibilmente in gruppi di 32 bits.
> Se e` a 64 ma lo puoi (ammesso che si possa) far
> funzionare a 32 (IA-64 puo`, come del resto sia
> AMD-64 che IA-32 possono funzionare anche a 16
> bit), a parte dimezzare il suo spazio
> d'indirizzamento e la "larghezza di banda" nei
> passaggi di dati tra memoria e registri, nel
> farlo le prestazioni degradano sensibilmente.
> Sarebbe un po' come dire a un destro di scrivere
> con la sinistra: e` stato "progettato" per usare
> la destra, percio` si trova spiazzato ed e` piu`
> lento nell'usare la sinistra. Una CPU a 32 bit
> deve "pensarci su", per operare a 16
> bit.
E già: linoleum, come si conviene a un assempler, usa i registri interni del processore finché può perché molto più veloci delle locazioni di memoria RAM. Se i registri sono a 64 bit, immagazzinarci numeri a 32 bit sarebbe uno spreco (ma per retrocompatibilità coi vecchi programmi si può fare?) mentre usarli per tenere ciascuno due parole di bit che poi il programma tratta come numeri a 32 bit comporterebbe tutta una serie di operazioni che rallentano il programma.
> Comunque, non e` che l'attuale AMD-64 o x86-64
> non possa far funzionare programmi Linoleum a 32
> bit (anche perche` mancano versioni a 64 bit del
> run-time module e del set d'istruzioni operante
> in "long mode"), pero` non ne sfrutta i vantaggi
> e per giunta si trova relativamente penalizzata
> rispetto ad applicazioni a 64 bit.
Dunque esiste un modo per usare applicazioni scritte per un processore a 32 bit su uno a 64, sia pure non sfruttando la potenza del processore.
> Se posso fare una previsione azzardata, ma
> secondo me plausibile, una volta che Linoleum e
> altri software a 32 bit saranno interamente
> passati ai 64 bit, avranno fatto l'ultimo
> doloroso "salto del fosso" per tutto il secolo.
> Insomma, er... 64 bit di spazio
> d'indirizzamento dovrebbero bastare per
> tutti™.
A meno che non siano all'orizzonte processori a 128 bit, e così via.
-
Re: x alex,tg: linoleum vs llvm vs assem>
E già: linoleum, come si conviene a un
> assempler, usa i registri interni del processore
> finché può perché molto più veloci delle
> locazioni di memoria RAM.
Piu` che "finche` puo`", e` un "dove il programmatore lo desidera". I registri li "palleggia" il programmatore. I simboli da A ad E (maiuscole o minuscole sono SEMPRE intercambiabili ovunque in Linoleum) sono registri, non variabili. Se scrivi:
a = b;
Ottieni un'istruzione che copia il contenuto numerico del registro B nel registro A. E ti stai riferendo ai registri perche` i nomi sono proprio quelli. Ne deriva che non puoi dichiarare una variabile che si chiama A, B, C, D o E, certo... pazienza. I nomi di variabili e costanti, e simboli utente in generale, se proprio vogliono essere composti da una sola lettera, sono validi a partire da F. Ora, se invece scrivi:
[f] = [g];
Ottieni un'istruzione che copia il contenuto numerico della VARIABILE g nella VARIABILE f. Nota le quadre: coi registri non servono per una questione spinosa da spiegare, ma molt logica. Vediamo un po'... bisogna che parta dal menzionare che per Linoleum, il nome di un simbolo e` SEMPRE un valore costante. Anche i nomi delle variabili, di per se`, sono costanti numeriche ASSOCIATE all'indirizzo di memoria (nel workspace) che ne contiene il valore. Quindi se scrivi "f" e la variabile "f" e` associata all'indirizzo 100, il compilatore "vede" il nome "f" come una rappresentazione letterale del numero 100. Come se alla dichiarazione della variabile, il compilatore dichiarasse una costante "f = 100"; dopodiche`, al momento di costruire il workspace, all'indirizzo 100 mettera` il valore assegnato dal sorgente alla variabile "f". Ecco, gia` qui parte il mal di testa eh? Lo supponevo.
Se comunque premetti quello, allora i nomi dei registri non ha senso scriverli nella stessa notazione (nome solo = costante che ne rappresenta l'indirizzo, nome tra parentesi quadre = contenuto della variabile), perche`... i registri NON HANNO indirizzi, solo nomi. D'altro canto, cio` permette, senza estendere l'alfabeto dei simboli e cioe` riutilizzando le parentesi quadre in una notazione "avvolgente", di usare i nomi dei registri per realizzare indirizzamenti indiretti, dove uno spiazzamento (chiamato anche un offset, un delta, er... un'addizione algebrica) viene aggiunto a un indirizzo costante. In soldoni, l'indirizzamento indiretto serve per accedere a vettori e matrici usando indici variabili. Ad esempio nei loops:a = 0; b = 1; c = 10; "loop" [r [a]] = b; + a; + b; ' ? c ^ loop;
Il registro A viene usato come indice, che nel ciclo andra` da 0 a 9, per riempire un vettore "r" (presumibilmente allocato come lungo 10 unita`) coi numeri da 1 a 10 (il valore del registro B nel ciclo). Il registro C fa da contatore di fine ciclo: l'istruzione in fondo e` un "integer loop until zero" che ogni volta decrementa C e, se e` maggiore di zero, salta all'etichetta "loop". In questo caso [r [a]] e` un'espressione che realizza indirizzamento indiretto: nel suo generatore di indirizzi, il processore aggiunge la costante rappresentata dall'indirizzo della prima locazione di "r" al valore di A. Nella locazione risultante, l'assegnazione (=) infila il valore di B.
*nevralgie*
A che serve?
Be', a notare questo: l'aritmetica che genera l'indirizzo e` svolta senza che al processore venga inviata un'istruzione per sommare i due indirizzi. Cioe`, l'espressione [r [a]] e` in grado di rimpiazzare:d = r; d + a; [d] = b;
ovvero un'addizione esplicita, come istruzione a parte che prende il suo tempo, occupa il processore e allunga l'eseguibile, per raggiungere la locazione r + a.
All'inizio magari e` spaventoso, ma in fondo non e` difficile.
Concludendo, piuttosto che usarli lui quando gli pare giusto, Linoleum da` accesso a 5 registri generici (general-purpose), che cioe` non sono dedicati a scopi specifici. Dove e come usarli lo decide il programmatore. Se l'architettura ne ha meno di 5 usabili come registri generici (a parte gli ANTICHI Motorola come il 6510, non mi vengono in mente esempi), allora alcuni registri saranno emulati con locazioni di memoria; se l'architettura ne ha piu` di 5 (piu` un registro di riserva e un registro per la cosidetta "origine del workspace", usati dall'ambiente Linoleum) i registri extra non sono mappati dal compilatore Linoleum, anche se possono essere usati inserendo codice macchina specifico, ma si entra in un discorso complicato. Quel che sceglie col numero di 5 registri generici e` un compromesso che dovrebbe risultare facilmente portabile.
> Se i registri sono a 64
> bit, immagazzinarci numeri a 32 bit sarebbe uno
> spreco (ma per retrocompatibilità coi vecchi
> programmi si può fare?)
Il long mode della x86-64 lo fa di per se`.
> Dunque esiste un modo per usare applicazioni
> scritte per un processore a 32 bit su uno a 64,
> sia pure non sfruttando la potenza del
> processore.
Nel caso di x86-64 non c'e` nessun problema, a parte i mancati vantaggi. Dove c'e` RAX (A, l'accumulatore a 64 bit), e dove ci sono RBX, RCX, RDX, RSI (i registri che Linoleum mappa come B, C, D, E) ci sono anche i loro "fratelli minori" EAX, EBX, ECX, EDX, ESI.
> A meno che non siano all'orizzonte processori a
> 128 bit, e così via.
>
Mah, si`, a qualcosa di certo servirebbe espandere ulteriormente la word (per esempio crittografia, codifica aritmetica...) ma finora mi pare di aver capito che, data la difficolta` di passare (per tutti, non solo per Linoleum) da un mondo all'altro facendo il "salto del fosso", la word e` raddoppiata solo quando ci sono state ragioni... come dire, stringenti. Letteralmente stringenti: lo spazio d'indirizzamento, insomma. Se i registri dove carichi gli indirizzi di memoria sono a 32 bit ma la memoria e` piu` di 4 miliardi di byte indirizzabili singolarmente, allora non la acchiappi tutta, e hai bisogno di piu` cifre binarie. Ma siccome 64 bit indirizzano un CARGO di memoria mai visto ne` all'orizzonte, chi si sbatte a cambiarli piu`?-
Re: x alex,tg: linoleum vs llvm vs assemScritto daNon Autenticatoil 2010-11-21 15:46:00.0 alle 2010-11-21 15:46:00.0> >
E già: linoleum, come si conviene a un
> > assempler, usa i registri interni del processore
> > finché può perché molto più veloci delle
> > locazioni di memoria RAM.
>
> Piu` che "finche` puo`", e` un "dove il
> programmatore lo desidera".
Sì, sarebbe corretto dire così, ma sottintendevo che il programmatore lo desidera. Mica è masochista, il programmatore!
> I registri li
> "palleggia" il programmatore. I simboli da A ad E
> (maiuscole o minuscole sono SEMPRE
> intercambiabili ovunque in Linoleum) sono
> registri, non variabili. Se
> scrivi:
>
> a = b;
>
> Ottieni un'istruzione che copia il contenuto
> numerico del registro B nel registro A. E ti stai
> riferendo ai registri perche` i nomi sono proprio
> quelli. Ne deriva che non puoi dichiarare una
> variabile che si chiama A, B, C, D o E, certo...
> pazienza. I nomi di variabili e costanti, e
> simboli utente in generale, se proprio vogliono
> essere composti da una sola lettera, sono validi
> a partire da F. Ora, se invece
> scrivi:
>
> [f] = [g];
>
> Ottieni un'istruzione che copia il contenuto
> numerico della VARIABILE g nella VARIABILE f.
> Nota le quadre: coi registri non servono per una
> questione spinosa da spiegare, ma molt logica.
> Vediamo un po'... bisogna che parta dal
> menzionare che per Linoleum, il nome di un
> simbolo e` SEMPRE un valore costante. Anche i
> nomi delle variabili, di per se`, sono costanti
> numeriche ASSOCIATE all'indirizzo di memoria (nel
> workspace) che ne contiene il valore. Quindi se
> scrivi "f" e la variabile "f" e` associata
> all'indirizzo 100, il compilatore "vede" il nome
> "f" come una rappresentazione letterale del
> numero 100. Come se alla dichiarazione della
> variabile, il compilatore dichiarasse una
> costante "f = 100"; dopodiche`, al momento di
> costruire il workspace, all'indirizzo 100
> mettera` il valore assegnato dal sorgente alla
> variabile "f". Ecco, gia` qui parte il mal di
> testa eh? Lo supponevo.
>
Finora credo d'aver capito che una lettera rappresenta un indirizzo, quella lettera tra parentesi quadre il contenuto dell'indirizzo.
> Se comunque premetti quello, allora i nomi dei
> registri non ha senso scriverli nella stessa
> notazione (nome solo = costante che ne
> rappresenta l'indirizzo, nome tra parentesi
> quadre = contenuto della variabile), perche`... i
> registri NON HANNO indirizzi, solo nomi. D'altro
> canto, cio` permette, senza estendere l'alfabeto
> dei simboli e cioe` riutilizzando le parentesi
> quadre in una notazione "avvolgente", di usare i
> nomi dei registri per realizzare indirizzamenti
> indiretti, dove uno spiazzamento (chiamato anche
> un offset, un delta, er... un'addizione
> algebrica) viene aggiunto a un indirizzo
> costante. In soldoni, l'indirizzamento indiretto
> serve per accedere a vettori e matrici usando
> indici variabili. Ad esempio nei
> loops:
>
>a = 0; > b = 1; > c = 10; > > "loop" > > [r [a]] = b; > > + a; > + b; > > ' ? c ^ loop;
>
> Il registro A viene usato come indice, che nel
> ciclo andra` da 0 a 9, per riempire un vettore
> "r" (presumibilmente allocato come lungo 10
> unita`) coi numeri da 1 a 10 (il valore del
> registro B nel ciclo). Il registro C fa da
> contatore di fine ciclo: l'istruzione in fondo e`
> un "integer loop until zero" che ogni volta
> decrementa C e, se e` maggiore di zero, salta
> all'etichetta "loop". In questo caso [r [a]] e`
> un'espressione che realizza indirizzamento
> indiretto: nel suo generatore di indirizzi, il
> processore aggiunge la costante rappresentata
> dall'indirizzo della prima locazione di "r" al
> valore di A. Nella locazione risultante,
> l'assegnazione (=) infila il valore di
> B.
>
> *nevralgie*
>
> A che serve?
> Be', a notare questo: l'aritmetica che genera
> l'indirizzo e` svolta senza che al processore
> venga inviata un'istruzione per sommare i due
> indirizzi. Cioe`, l'espressione [r [a]] e` in
> grado di
> rimpiazzare:
>
>d = r; > d + a; > [d] = b;
>
> ovvero un'addizione esplicita, come istruzione a
> parte che prende il suo tempo, occupa il
> processore e allunga l'eseguibile, per
> raggiungere la locazione r +
> a.
>
> All'inizio magari e` spaventoso, ma in fondo non
> e`
> difficile.
>
> Concludendo, piuttosto che usarli lui quando gli
> pare giusto, Linoleum da` accesso a 5 registri
> generici (general-purpose), che cioe` non sono
> dedicati a scopi specifici. Dove e come usarli lo
> decide il programmatore. Se l'architettura ne ha
> meno di 5 usabili come registri generici (a parte
> gli ANTICHI Motorola come il 6510, non mi vengono
> in mente esempi), allora alcuni registri saranno
> emulati con locazioni di memoria; se
> l'architettura ne ha piu` di 5 (piu` un registro
> di riserva e un registro per la cosidetta
> "origine del workspace", usati dall'ambiente
> Linoleum) i registri extra non sono mappati dal
> compilatore Linoleum, anche se possono essere
> usati inserendo codice macchina specifico, ma si
> entra in un discorso complicato. Quel che sceglie
> col numero di 5 registri generici e` un
> compromesso che dovrebbe risultare facilmente
> portabile.
>
> > Se i registri sono a 64
> > bit, immagazzinarci numeri a 32 bit sarebbe uno
> > spreco (ma per retrocompatibilità coi vecchi
> > programmi si può fare?)
>
> Il long mode della x86-64 lo fa di per se`.
>
> > Dunque esiste un modo per usare applicazioni
> > scritte per un processore a 32 bit su uno a 64,
> > sia pure non sfruttando la potenza del
> > processore.
>
> Nel caso di x86-64 non c'e` nessun problema, a
> parte i mancati vantaggi. Dove c'e` RAX (A,
> l'accumulatore a 64 bit), e dove ci sono RBX,
> RCX, RDX, RSI (i registri che Linoleum mappa come
> B, C, D, E) ci sono anche i loro "fratelli
> minori" EAX, EBX, ECX, EDX,
> ESI.
>
> > A meno che non siano all'orizzonte processori a
> > 128 bit, e così via.
> >
>
> Mah, si`, a qualcosa di certo servirebbe
> espandere ulteriormente la word (per esempio
> crittografia, codifica aritmetica...) ma finora
> mi pare di aver capito che, data la difficolta`
> di passare (per tutti, non solo per Linoleum) da
> un mondo all'altro facendo il "salto del fosso",
> la word e` raddoppiata solo quando ci sono state
> ragioni... come dire, stringenti. Letteralmente
> stringenti: lo spazio d'indirizzamento, insomma.
> Se i registri dove carichi gli indirizzi di
> memoria sono a 32 bit ma la memoria e` piu` di 4
> miliardi di byte indirizzabili singolarmente,
> allora non la acchiappi tutta, e hai bisogno di
> piu` cifre binarie. Ma siccome 64 bit indirizzano
> un CARGO di memoria mai visto ne` all'orizzonte,
> chi si sbatte a cambiarli
> piu`?
-
-
-
-
-
-
-
-
-
-
-
-
-
-