2012-02-11 9 views
37

Recentemente ho scoperto l'esistenza dello standard di tipo più veloce, principalmente int_fast32_t e int_fast64_t.Qual è la differenza tra intXX_t e int_fastXX_t?

Mi hanno sempre detto che, per l'uso normale architettura tradizionale, si dovrebbe utilizzare meglio classica int & lungo che dovrebbero sempre adattarsi alla capacità di lettura processore standard e così evitare inutili conversioni numeriche.

Nel C99 standard, si dice nel §7.18.1.3p2:

"Il nome typedef int_fastN_t indica il tipo integer più veloce firmato con una larghezza di almeno N. Il nome typedef uint_fastN_t designa il più veloce tipo intero senza segno con una larghezza di almeno N. "

E c'è anche una citazione su di esso in §7.18.1.3p1:

"Il tipo designato non è garantito di essere più veloce in ogni caso; se l'implementazione non ha fondati motivi per la scelta un tipo piuttosto che un altro, sceglierà semplicemente un tipo intero che soddisfi i requisiti di firma e larghezza. "

Non è chiaro per me cosa significhi veramente . Non capisco quando dovrei usare questo tipo e quando non dovrei.

Ho cercato su Google un po 'e ho trovato che alcuni opensourceprojects hanno cambiato alcune delle loro funzioni ad esso, ma non tutti loro. Non hanno davvero spiegato il motivo per cui hanno modificato una parte e solo una parte, del loro codice.

Sapete quali sono i casi/usi specifici quando int_fastXX_t sono veramente più veloci di quelli classici?

+1

+1. Mi sono interrogato su questo per un po 'di tempo, e il [C rationale] (http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf) è tranquillo sull'argomento . –

risposta

19

In C99 Standard, 7.18.1.3 Tipi interi di larghezza minima più veloci.

(7.18.1.3p1) "Ognuno dei seguenti tipi designa un tipo intero che è in genere più veloce225) per operare con tutti i tipi di interi che hanno almeno la larghezza specificata."

225) "Il tipo designato non è garantito per essere il più veloce a tutti gli effetti, se l'implementazione non ha fondati motivi per scegliere un tipo piuttosto che un altro, sarà semplicemente selezionare un tipo intero che soddisfi i requisiti di firma e larghezza."

e

(7.18.1.3p2) "Il nome typedef int_fastN_t designa il tipo intero veloce stipulato con una larghezza di almeno N. Il nome typedef uint_fastN_t designa il più veloce senza segno tipo intero con una larghezza di almeno N."

I tipi int_fastN_t e uint_fastN_t sono omologhi ai tipi interi esatta larghezza intN_t e uintN_t. L'attuazione garantisce che prendono almeno N bit, ma l'implementazione può richiedere più bit se può eseguire l'ottimizzazione utilizzando grande tipi,. solo garantisce prendono almeno N bit

ad esempio, su una macchina a 32 bit, uint_fast16_t potrebbe essere definito come un unsigned int piuttosto che come unsigned short perché lavorare con tipi di dimensione di parola macchina sarebbe più efficiente

Un altro motivo della loro esistenza è che i tipi di interi a larghezza esatta sono facoltativi in ​​C, ma sono richiesti i tipi di interi con larghezza minima più rapida ei tipi di interi con larghezza minima (int_leastN_t e uint_leastN_t).

+1

Questo non spiega molto."su una macchina a 32 bit,' uint_fast16_t' potrebbe essere definito come 'unsigned int'" - sì, ma si potrebbe usare direttamente il vecchio 'unsigned int', dato che è la larghezza intera nativa e lo standard garantisce che sia a almeno 16 bit di larghezza. Allo stesso modo, 'long' incontra gli stessi vincoli di' int_fast32_t'. –

+0

Ho letto la logica, ma questo non dice _quando_ è più veloce, per quale tipo di utilizzo specifico? Se questo è _really_ più veloce ogni volta, perché non li usiamo di default? – Coren

+2

@larsmans 'uint_fast16_t' potrebbe essere un alias per' unsigned int' in una macchina a 32 bit e per 'unsigned long' in una macchina a 64 bit. L'uso di 'unsigned int' invece di' uint_fast16_t' nel programma non sarà lo stesso se si intende compilare il programma su macchine diverse. – ouah

2

Probabilmente non ci sarà alcuna differenza se non su hardware esotico dove int32_t e int16_t non esistono nemmeno.

In tal caso è possibile utilizzare int_least16_t per ottenere il tipo più piccolo che può contenere 16 bit. Potrebbe essere importante se vuoi risparmiare spazio.

D'altra parte, utilizzando int_fast16_t potrebbe ottenere un altro tipo, maggiore di int_least16_t ma possibilmente più veloce per l'utilizzo di numeri interi "tipici". L'implementazione dovrà considerare ciò che è più veloce e ciò che è tipico. Forse questo è ovvio per alcuni hardware per scopi speciali?

Sulla maggior parte delle macchine comuni questi tipi a 16 bit saranno tutti un typedef per short e non dovrete preoccuparvi.

2

Gnu libc defines {int, uint} _fast {16,32} _t come 64-bit durante la compilazione per CPU a 64 bit e 32 bit in caso contrario. Le operazioni su numeri interi a 64 bit sono più veloci su CPU Intel e AMD a 64 bit a 64 bit rispetto alle stesse operazioni su numeri interi a 32 bit.

+0

Sì, ma non dovresti 'int' essere 64-bit su una macchina del genere? – potrzebie

+0

No, 'int' può essere piccolo come 16 bit, e le sue dimensioni di solito dipendono dal compilatore ma non dalla piattaforma. Questo è probabilmente un artefatto della transizione da 16 a 32 bit. – user833771

+0

Il tuo link per "più veloce" sta confrontando le modalità CPU a 32 e 64 bit per eseguire alcune attività complesse, ma non sta confrontando le prestazioni degli interi 32-bit e 64-bit nella stessa modalità CPU. – plugwash

1

IMO sono piuttosto inutili.

Il compilatore non si cura di ciò che si chiama un tipo, solo di quale dimensione è e quali regole si applicano ad esso. quindi se int, in32_t e int_fast32_t sono tutti a 32 bit sulla tua piattaforma, quasi sicuramente tutti si comportano allo stesso modo.

La teoria è che gli implementatori del linguaggio dovrebbero scegliere in base a ciò che è più veloce sul loro hardware, ma gli scrittori standard non hanno mai individuato una definizione chiara del più veloce. Aggiungete che al fatto che i manutentori della piattaforma sono riluttanti a cambiare la definizione di tali tipi (perché sarebbe un'interruzione ABI) e le definizioni finiscono per essere scelte arbitrariamente all'inizio della vita di una piattaforma (o ereditate da altre piattaforme che la libreria C era ported from) e mai più toccati.

Se si è a livello di micro-ottimizzazione che si pensa dimensione variabile può fare una differenza significativa, allora punto di riferimento le diverse opzioni con il tuo codice sul processore. Altrimenti non ti preoccupare. I tipi "veloci" non aggiungono nulla IMO utile.