Cos'è uint_fast32_t e perché dovrebbe essere usato al posto dei normali int e uint32_t?


110

Quindi la ragione per typedef: ed i tipi di dati primitivi è di astrarre la rappresentazione di basso livello e renderla più facile da comprendere ( uint64_tinvece del long longtipo, che è di 8 byte).

Tuttavia, c'è uint_fast32_tche ha lo stesso typedefdi uint32_t. L'uso della versione "veloce" renderà il programma più veloce?


long long forse non è di 8 byte, è possibile avere un long long con 1 byte (nel caso CHAR_BIT sia almeno 64) o con 3738383 byte. anche uint64_t può essere 1,2,4 o 8 byte, CHAR_BIT deve essere 64, 3, 16 o 8 per quello.
12431234123412341234123

Risposte:


135
  • intpuò essere piccolo fino a 16 bit su alcune piattaforme. Potrebbe non essere sufficiente per la tua applicazione.
  • uint32_tnon è garantita l'esistenza. È un opzionale typedefche l'implementazione deve fornire se e solo se ha un tipo intero senza segno di esattamente 32 bit. Alcuni, ad esempio, hanno byte a 9 bit, quindi non hanno estensione uint32_t.
  • uint_fast32_tafferma chiaramente il tuo intento: è un tipo di almeno 32 bit che è il migliore dal punto di vista delle prestazioni. uint_fast32_tpuò essere infatti lungo 64 bit. Dipende dall'implementazione.

... c'è uint_fast32_tche ha lo stesso typedef di uint32_t...

Quello che stai guardando non è lo standard. È un'implementazione particolare (BlackBerry). Quindi non puoi dedurre da lì che uint_fast32_tè sempre lo stesso di uint32_t.

Guarda anche:


36
Buona risposta. Per completezza, si potrebbe forse sottolineare anche la differenza uint_least32_t, che è la stessa uint_fast32_ttranne che favorisce un negozio più piccolo piuttosto che la velocità.
Damon

2
Perché il numero intero più veloce con una larghezza di almeno 32 bit dovrebbe essere maggiore di 32 bit? Ho sempre pensato che se ci sono meno bit, ci saranno meno bit su cui la CPU deve lavorare, quindi più velocemente. Cosa mi manca qui?
Shane Hsu

12
@ShaneHsu: diciamo che una CPU a 64 bit avrà un'estate a 64 bit, che somma i numeri a 64 bit in un ciclo. Non importa se tutto ciò che vuoi fare è lavorare su numeri a 32 bit, non sarà più veloce di un ciclo. Ora, sebbene non sia così su x86 / amd64, gli interi a 32 bit potrebbero non essere nemmeno indirizzabili. In tal caso, lavorare su di essi richiede operazioni aggiuntive per estrarre i 32 bit da, diciamo, unità allineate a 64 bit. Vedi anche la domanda collegata. Lo standard C ++ è scritto in modo che possa funzionare su una macchina che ha parole a 37 bit ... quindi nessun tipo a 32 bit lì.
Yakov Galka

42

La differenza sta nella loro esattezza e disponibilità.

Il documento qui dice:

tipo intero senza segno con larghezza di esattamente 8, 16, 32 e 64 bit rispettivamente ( fornito solo se l'implementazione supporta direttamente il tipo ):

uint8_t
uint16_t
uint32_t
uint64_t

E

tipo di intero senza segno più veloce con larghezza di almeno 8, 16, 32 e 64 bit rispettivamente

uint_fast8_t
uint_fast16_t
uint_fast32_t
uint_fast64_t    

Quindi la differenza è abbastanza chiara che uint32_tè un tipo che ha esattamente 32 bit, e un'implementazione dovrebbe fornirlo solo se ha un tipo con esattamente 32 bit, e quindi può digitare quel tipo come uint32_t. Ciò significa che uint32_tpuò o non può essere disponibile .

D'altra parte, uint_fast32_tè un tipo che ha almeno 32 bit, che inoltre mezzi, se un'implementazione può TypeDef uint32_tcome uint_fast32_t se esso fornisce uint32_t. Se non fornisce uint32_t, uint_fast32_tpotrebbe essere un typedef di qualsiasi tipo che abbia almeno 32bit.


3
Ma qual è il motivo che rende ad esempio uint_fast32_t più veloce di uint32_t? Perché è più veloce?
Destructor

2
@PravasiMeet: non si accede a tutti i numeri interi nello stesso modo. Alcuni sono più facili da accedere rispetto ad altri. Più facile significa meno calcoli, più diretto, che si traduce in un accesso più rapido. Ora uint32_tè esattamente a 32 bit su tutti i sistemi (se esiste), il che potrebbe non essere più veloce rispetto a quello che ha, diciamo, 64 bit. uint_fast32_td'altra parte almeno 32 bit, potrebbe essere anche 64 bit.
Nawaz

10
@Destructor: su alcuni processori, se una variabile viene memorizzata in un registro che è più lungo, il compilatore potrebbe dover aggiungere codice extra per tagliare eventuali bit extra. Ad esempio, se uint16_t x;viene memorizzato in un registro a 32 bit su ARM7-TDMI, x++;potrebbe essere necessario valutare il codice come x=((x+1)<<16)>>16);. Sui compilatori per quella piattaforma, uint_fast16_tsarebbe molto probabilmente definito come sinonimo uint32_tdi evitarlo.
supercat

perché [u]int_(fast|least)N_tnon sono anche opzionali? Sicuramente non tutte le architetture sono richieste dallo Standard per supportare tipi primitivi di almeno 64 bit? Eppure la formulazione per stdint.himplica che devono. Mi sembra strano che lo abbiamo imposto dal 1999, alcuni anni prima che i computer a 64 bit diventassero mainstream, per non parlare del ritardo dietro a quella (in molti casi ancora attuale) delle architetture incorporate. Questa mi sembra una grande svista.
underscore_d

1
@underscore_d: non c'è motivo particolare, ad esempio, che lo standard non possa essere applicabile a un'implementazione PIC12 con 16 byte di RAM di dati e spazio per 256 istruzioni. Una simile implementazione dovrebbe rifiutare molti programmi, ma ciò non dovrebbe impedirgli di comportarsi in modo definito per i programmi le cui esigenze potrebbe soddisfare.
supercat

4

Quando sei #include inttypes.hnel tuo programma, hai accesso a molti modi diversi per rappresentare gli interi.

Il tipo uint_fast * _t definisce semplicemente il tipo più veloce per rappresentare un dato numero di bit.

Pensala in questo modo: definisci una variabile di tipo shorte la usi più volte nel programma, il che è totalmente valido. Tuttavia, il sistema su cui stai lavorando potrebbe funzionare più rapidamente con i valori di tipo int. Definendo una variabile come tipo uint_fast*t, il computer sceglie semplicemente la rappresentazione più efficiente con cui può lavorare.

Se non c'è differenza tra queste rappresentazioni, il sistema sceglie quella che vuole e la usa costantemente.


9
Perché inttypes.h e non stdint.h? Sembra che inttypes.h contenga solo vari fluff leggermente utili, oltre a un'inclusione di stdint.h?
Lundin

@underscore_d Conosco la differenza. Ma chi usa stdio.h nei programmi professionali, indipendentemente dall'area di applicazione?
Lundin

@ Lundin non ho idea di chi siano, o se esistono! Ho solo pensato che potrebbe essere utile fornire un link che elabori su cosa sia quel "fluff leggermente utile" ;-) Forse aiuterà le persone a capire che hai ragione e non ne hanno bisogno.
underscore_d

-1

Notare che la versione veloce potrebbe essere più grande di 32 bit. Mentre il fast int si adatterà bene in un registro e sarà allineato e simili: ma, userà più memoria. Se disponi di array di grandi dimensioni, il tuo programma sarà più lento a causa di più accessi alla cache di memoria e larghezza di banda.

Non credo che il CPUS moderno trarrà vantaggio da fast_int32, poiché generalmente il segno che si estende da 32 a 64 bit può verificarsi durante l'istruzione di caricamento e l'idea che esista un formato intero "nativo" più veloce è antiquata.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.