Was ist uint_fast32_t und warum sollte es anstelle des regulären int und uint32_t verwendet werden?

108

Der Grund für typedef: ed primitive Datentypen besteht darin, die Darstellung auf niedriger Ebene zu abstrahieren und das Verständnis zu erleichtern ( uint64_tanstelle des long longTyps, der 8 Byte beträgt).

Es gibt uint_fast32_tjedoch das gleiche typedefwie uint32_t. Wird die Verwendung der "schnellen" Version das Programm beschleunigen?

Amumu
quelle
long long ist vielleicht nicht 8 Bytes, es ist möglich, ein long long mit 1 Byte (falls CHAR_BIT mindestens 64 ist) oder mit 3738383 Bytes zu haben. auch uint64_t kann 1,2,4 oder 8 Bytes sein, CHAR_BIT muss dafür 64, 3, 16 oder 8 sein.
12431234123412341234123

Antworten:

134
  • intkann auf einigen Plattformen bis zu 16 Bit betragen. Dies ist möglicherweise nicht ausreichend für Ihre Bewerbung.
  • uint32_tist nicht garantiert zu existieren. Es ist optional, typedefdass die Implementierung Folgendes bereitstellen muss, wenn sie einen vorzeichenlosen Integer-Typ von genau 32 Bit hat. Einige haben zum Beispiel 9-Bit-Bytes, also keine uint32_t.
  • uint_fast32_tgibt Ihre Absicht klar an: Es handelt sich um einen Typ von mindestens 32 Bit, der aus Sicht der Leistung der beste ist. uint_fast32_tkann tatsächlich 64 Bit lang sein. Es liegt an der Umsetzung.

... es gibt uint_fast32_tdas gleiche typedef wie uint32_t...

Was Sie sehen, ist nicht der Standard. Es ist eine bestimmte Implementierung (BlackBerry). Daraus kann man also nicht ableiten, dass uint_fast32_tes immer dasselbe ist wie uint32_t.

Siehe auch:

Yakov Galka
quelle
35
Gute Antwort. Der Vollständigkeit halber könnte man vielleicht auch auf den Unterschied hinweisen, der uint_least32_tderselbe ist, uint_fast32_taußer dass er eher einen kleineren Laden als eine Geschwindigkeit bevorzugt.
Damon
2
Warum sollte die schnellste Ganzzahl mit einer Breite von mindestens 32 Bit größer als 32 Bit sein? Ich dachte immer, wenn es weniger Bits gibt, gibt es weniger Bits, an denen die CPU arbeiten muss, also schneller. Was fehlt mir hier?
Shane Hsu
12
@ShaneHsu: Angenommen, eine 64-Bit-CPU hat einen 64-Bit-Sommer, der 64-Bit-Zahlen in einem Zyklus summiert. Es spielt keine Rolle, ob Sie nur an 32-Bit-Zahlen arbeiten möchten, es wird nicht schneller als ein Zyklus sein. Obwohl dies bei x86 / amd64 nicht der Fall ist, sind 32-Bit-Ganzzahlen möglicherweise nicht einmal adressierbar. In einem solchen Fall erfordert die Bearbeitung zusätzliche Operationen, um die 32-Bit-Einheiten beispielsweise aus 64-Bit-ausgerichteten Einheiten zu extrahieren. Siehe auch die verknüpfte Frage. Der C ++ - Standard ist so geschrieben, dass er auf einem Computer mit 37-Bit-Wörtern funktioniert. Es gibt also überhaupt keinen 32-Bit-Typ.
Yakov Galka
42

Der Unterschied liegt in der Genauigkeit und Verfügbarkeit.

Der Arzt hier sagt:

Ganzzahliger Typ ohne Vorzeichen mit einer Breite von genau 8, 16, 32 bzw. 64 Bit ( nur bereitgestellt, wenn die Implementierung den Typ direkt unterstützt ):

uint8_t
uint16_t
uint32_t
uint64_t

Und

schnellster vorzeichenloser Ganzzeichentyp ohne Vorzeichen mit einer Breite von mindestens 8, 16, 32 bzw. 64 Bit

uint_fast8_t
uint_fast16_t
uint_fast32_t
uint_fast64_t    

Der Unterschied ist also ziemlich klar, dass uint32_tes sich um einen Typ handelt, der genau 32 Bits enthält, und eine Implementierung sollte ihn nur bereitstellen, wenn er einen Typ mit genau 32 Bits hat, und dann kann er diesen Typ als definieren uint32_t. Dies bedeutet, dass uint32_tmöglicherweise verfügbar ist oder nicht .

Auf der anderen Seite uint_fast32_thandelt es sich um einen Typ mit mindestens 32 Bit, was auch bedeutet, dass eine Implementierung typedef kann, uint32_tals uint_fast32_t ob sie bereitstellt uint32_t. Wenn dies nicht der Fall ist, uint32_tkann es uint_fast32_tsich um ein typedef eines beliebigen Typs handeln, der mindestens 32Bits enthält.

Nawaz
quelle
3
Aber was ist der Grund, der zum Beispiel uint_fast32_t schneller macht als uint32_t? Warum ist es schneller?
Zerstörer
2
@PravasiMeet: Nicht auf alle Ganzzahlen wird auf dieselbe Weise zugegriffen. Einige sind leichter zugänglich als andere. Einfacher bedeutet weniger Berechnung, direkter, was zu einem schnelleren Zugriff führt. Jetzt uint32_tist genau 32-Bit auf allen Systemen (falls vorhanden), was möglicherweise nicht schneller ist als das mit beispielsweise 64-Bit. uint_fast32_tAuf der anderen Seite könnten mindestens 32 Bit sogar 64 Bit sein.
Nawaz
10
@Destructor: Wenn auf einigen Prozessoren eine Variable in einem längeren Register gespeichert wird, muss der Compiler möglicherweise zusätzlichen Code hinzufügen, um zusätzliche Bits zu entfernen. Wenn beispielsweise uint16_t x;in einem 32-Bit-Register auf dem ARM7-TDMI gespeichert wird, muss der Code x++;möglicherweise als ausgewertet werden x=((x+1)<<16)>>16);. Auf Compilern für diese Plattform uint_fast16_twürde höchstwahrscheinlich als synonym mit definiert uint32_t, um dies zu vermeiden.
Supercat
warum sind [u]int_(fast|least)N_tnicht auch optional? Sicherlich werden vom Standard nicht alle Architekturen benötigt, um primitive Typen von mindestens 64 Bit zu unterstützen? Der Wortlaut für stdint.himpliziert jedoch, dass sie müssen. Es scheint mir seltsam, dass wir dies seit 1999 durchsetzen, einige Jahre bevor 64-Bit-Computing zum Mainstream wurde - ganz zu schweigen von der Verzögerung, die hinter der (in vielen Fällen immer noch aktuellen) eingebetteten Architektur zurückbleibt. Dies scheint mir ein großes Versehen zu sein.
underscore_d
1
@underscore_d: Es gibt beispielsweise keinen besonderen Grund dafür, dass der Standard nicht auf eine PIC12-Implementierung mit 16 Byte Daten-RAM und Platz für 256 Anweisungen anwendbar ist. Eine solche Implementierung müsste viele Programme ablehnen, aber das sollte nicht verhindern, dass sie sich für Programme, deren Bedürfnisse sie befriedigen könnte, definiert verhält.
Supercat
4

Wenn Sie #include inttypes.hin Ihrem Programm sind, erhalten Sie Zugriff auf eine Reihe verschiedener Möglichkeiten zur Darstellung von Ganzzahlen.

Der Typ uint_fast * _t definiert einfach den schnellsten Typ für die Darstellung einer bestimmten Anzahl von Bits.

Stellen Sie sich das so vor: Sie definieren eine Variable vom Typ shortund verwenden sie mehrmals im Programm, was völlig gültig ist. Das System, an dem Sie arbeiten, arbeitet jedoch möglicherweise schneller mit Werten vom Typ int. Durch Definieren einer Variablen als Typuint_fast*t wählt der Computer einfach die effizienteste Darstellung aus, mit der er arbeiten kann.

Wenn es keinen Unterschied zwischen diesen Darstellungen gibt, wählt das System die gewünschte aus und verwendet sie durchgehend konsistent.

Harley Sugarman
quelle
9
Warum inttypes.h und nicht stdint.h? Es scheint, dass inttypes.h nur verschiedene leicht nützliche Flusen sowie ein Include von stdint.h enthält.
Lundin
@underscore_d Ich kenne den Unterschied. Aber wer nutzt stdio.h in professionellen Programmen, egal in welchem ​​Anwendungsbereich?
Lundin
@Lundin Ich habe keine Ahnung wer sie sind oder ob sie existieren! Ich dachte nur, es könnte nützlich sein, einen Link bereitzustellen, der ausführlich beschreibt, was dieser "leicht nützliche Flaum" ist ;-) Vielleicht hilft es den Leuten zu erkennen, dass Sie Recht haben und sie ihn nicht brauchen.
underscore_d
-1

Beachten Sie, dass die schnelle Version größer als 32 Bit sein kann. Das schnelle int passt zwar gut in ein Register und wird ausgerichtet und dergleichen: aber es wird mehr Speicher verbrauchen. Wenn Sie große Arrays davon haben, wird Ihr Programm aufgrund von mehr Speicher-Cache-Treffern und Bandbreite langsamer.

Ich denke nicht, dass moderner CPUS von fast_int32 profitieren wird, da im Allgemeinen die Vorzeichenerweiterung von 32 auf 64 Bit während des Ladebefehls auftreten kann und die Idee, dass es ein "natives" Ganzzahlformat gibt, das schneller ist, altmodisch ist.

Gil Colgate
quelle