2010-11-07 3 views
18

La maggior parte dei programmi si adatta allo < spazio di indirizzi da 4 GB, ma deve utilizzare le nuove funzionalità disponibili solo per l'architettura x64.Un compilatore C può generare un eseguibile a 64 bit in cui i puntatori sono a 32 bit?

Esistono compilatori/piattaforme in cui è possibile utilizzare i registri x64 e le istruzioni specifiche ma conservare i puntatori a 32 bit per risparmiare memoria?

È possibile farlo in modo trasparente sul codice legacy? Quale passaggio per farlo?

O

Quali cambiamenti sul codice è necessario per ottenere funzionalità a 64 bit, mentre mantenere i puntatori a 32 bit?

+0

Perché è necessario limitare le dimensioni del puntatore a 32 bit? – jveazey

+8

@John: Se i dati sono costituiti da molti puntatori, l'utilizzo di puntatori a 32 bit potrebbe risparmiare molta memoria. – cHao

risposta

16

Un modo semplice per aggirare questo è se avessi solo pochi tipi per le strutture che stai indicando. Quindi potresti semplicemente allocare grandi array per i tuoi dati e fare l'indicizzazione con uint32_t.

Quindi un "puntatore" in tale modello sarebbe solo un indice in un array globale. Solitamente l'indirizzamento con quello dovrebbe essere abbastanza efficiente con un compilatore decente, e ti farebbe risparmiare spazio. Perderesti altre cose a cui potresti essere interessato, ad esempio l'allocazione dinamica.

Un altro modo per ottenere qualcosa di simile è codificare un puntatore con la differenza rispetto alla sua posizione effettiva. Se riesci a garantire che quella differenza si adatti sempre a 32 bit, potresti guadagnare anche tu.

+4

+1 per un modo più semplice per realizzare ciò che OP vuole probabilmente. –

+2

Si noti che con queste soluzioni è possibile accedere a un massimo di 2^32 parole di memoria, che supera i 2^31 byte (2^29 parole a 32 bit) che in genere è possibile allocare in un 32 bit processo su un sistema operativo moderno.Quindi è anche molto interessante sfruttare appieno gli 8 o 16 GB di memoria che si trovano tipicamente nelle workstation dal 2010, mantenendo i "puntatori" a 32 bit. –

1

Dipende dalla piattaforma. Su Mac OS X, i primi 4 GB di uno spazio di indirizzamento di processo a 64 bit sono riservati e non mappati, presumibilmente come funzionalità di sicurezza, pertanto no il valore a 32 bit è sempre errato per un puntatore. Se ci provi, potrebbe esserci un modo per sconfiggerlo. Ho lavorato su di esso una volta scrivendo una classe "pointer" in C++ che aggiunge 0x100000000 al valore memorizzato. (Questo è stato significativamente più veloce rispetto all'indicizzazione in un array, che richiede anche di trovare l'indirizzo base dell'array e moltiplicato prima dell'aggiunta.)

A livello ISA, puoi certamente scegliere di caricare e estendere a zero un 32 bit valore e quindi utilizzarlo come puntatore a 64 bit. È una buona funzionalità per una piattaforma.

Nessuna modifica dovrebbe essere necessaria per un programma a meno che non si desideri utilizzare contemporaneamente puntatori a 64 e 32 bit. In questo caso si torna ai vecchi tempi di avere i puntatori near e far.

Inoltre, si interromperà sicuramente la compatibilità ABI con le API che puntano ai puntatori.

1

La seconda parte della domanda è facilmente risolvibile. È molto possibile, infatti molte implementazioni C hanno supporto, per operazioni a 64 bit usando codice a 32 bit. Il tipo C spesso usato per questo è long long (ma controlla il tuo compilatore e l'architettura).

Per quanto ne so non è possibile avere puntatori a 32 bit nel codice nativo a 64 bit.

2

Su x86, n. Su altri processori, come PowerPC, è abbastanza comune - i registri a 64 bit e le istruzioni sono disponibili in modalità a 32 bit, mentre con x86 tende a essere "tutto o niente".

1

Ho paura che se sei preoccupato per la dimensione dei puntatori potresti avere problemi più grandi da affrontare. Se il numero di puntatori sarà di milioni o di miliardi, probabilmente si avranno dei limiti all'interno del sistema operativo Windows prima che si esaurisca la memoria fisica o virtuale.

Mark Russinovich ha scritto un grande articolo relativo a questo, denominato Pushing the Limits of Windows: Virtual Memory.

+0

Lo leggerò. Miliardi di indicatori certamente no (solo i puntatori riempirebbero lo spazio degli indirizzi), ma alcuni milioni è possibile. – Maniero

4

Tecnicamente, è possibile che un compilatore lo faccia. AFAIK, in pratica non è fatto. È stato proposto per gcc (anche con una patch qui: http://gcc.gnu.org/ml/gcc/2007-10/msg00156.html) ma mai integrato (almeno, non è stato documentato l'ultima volta che ho controllato). La mia comprensione è che ha bisogno anche del supporto del kernel e della libreria standard per funzionare (cioè il kernel avrebbe bisogno di configurare le cose in un modo non attualmente possibile e usare l'ABI a 32 o 64 bit esistente per comunicare con il kernel non sarebbe possibile).

+0

Per chi è interessato, sembrano esserci movimenti su questo fronte: http://gcc.gnu.org/ml/gcc/2010-12/msg00480.html – AProgrammer

3

Quali sono esattamente le "caratteristiche a 64 bit" di cui hai bisogno, non è un po 'vago?

trovato questo mentre io alla ricerca di una risposta: http://www.codeproject.com/KB/cpp/smallptr.aspx

prendere anche la discussione sul fondo ...

mai avuto alcun bisogno di pensare a questo, ma è interessante rendersi conto che ci si può preoccupare di quanti puntatori di spazio hanno bisogno ...

+0

Sembra molto interessante anche se probabilmente non è quello che sto cercando . Non ho bisogno di usare più di 4 GB. Ho bisogno di registri più lunghi e più lunghi e, se possibile, di istruzioni avanzate disponibili solo su sistemi a 64 bit. Comunque è una risposta utile. – Maniero

+0

@bigown: ma poi di nuovo, se dici che hai bisogno solo di alcuni milioni di puntatori, importa davvero se occupano 40 Mb o 80 Mb? – steabert

+0

E sulla località? – Maniero

1

Penso che questo sarebbe simile al MIPS n32 ABI: registri a 64 bit con puntatori a 32 bit.

Nell'ABI n32, tutti i registri sono a 64 bit (quindi richiede un processore MIPS64). Ma gli indirizzi e i puntatori sono solo a 32 bit (se archiviati in memoria), riducendo il footprint di memoria. Quando si carica un valore a 32 bit (come un puntatore) in un registro, viene esteso al segno in 64 bit. Quando il processore utilizza il puntatore/indirizzo per un carico o un archivio, vengono utilizzati tutti i 64 bit (il processore non è a conoscenza del n32-ess del SW). Se il tuo sistema operativo supporta i programmi n32 (forse il sistema operativo segue anche il modello n32 o può essere un sistema operativo a 64 bit con supporto n32 aggiunto), può localizzare tutta la memoria utilizzata dall'applicazione n32 in una memoria adatta (ad es. il più alto 2 GB, gli indirizzi virtuali). L'unico problema con questo modello è che quando i registri vengono salvati nello stack (chiamate di funzione, ecc.), Vengono utilizzati tutti i 64 bit, non c'è un modello di dati a 32 bit nell'ABI n32.

Probabilmente tale ABI potrebbe essere implementato anche per x86-64.

4

Vale la pena notare che esiste un ABI in sviluppo per linux, X32, che consente di creare un binario x86_64 che utilizza indici e indici a 32 bit.

Solo relativamente nuovo, ma comunque interessante.

http://en.wikipedia.org/wiki/X32_ABI

+0

il progetto principale è [qui] (https://sites.google.com/site/x32abi/) –

0

Linux ora supporta abbastanza completo per la X32 ABI che fa esattamente ciò che il richiedente chiede, infatti è parzialmente supportato come configurazione con il sistema operativo Gentoo. Penso che questa domanda debba essere rivista alla luce dello sviluppo di risentimento.