In ISO / IEC 9899: 2018 (C18) ist dies unter 7.20.1.3 angegeben:
7.20.1.3 Schnellste Ganzzahltypen mit minimaler Breite
1 Jeder der folgenden Typen bezeichnet einen Integer-Typ, der normalerweise am schnellsten ist 268), um mit allen Integer-Typen zu arbeiten, die mindestens die angegebene Breite haben.
2 Der typedef-Name
int_fastN_t
bezeichnet den am schnellsten vorzeichenbehafteten Integer-Typ mit einer Breite von mindestens N. Der typedef-Nameuint_fastN_t
bezeichnet den schnellsten vorzeichenlosen Integer-Typ mit einer Breite von mindestens N.3 Folgende Typen sind erforderlich:
int_fast8_t
,int_fast16_t
,int_fast32_t
,int_fast64_t
,uint_fast8_t
,uint_fast16_t
,uint_fast32_t
,uint_fast64_t
Alle anderen Arten dieses Formulars sind optional.
268) Es ist nicht garantiert, dass der angegebene Typ für alle Zwecke am schnellsten ist. Wenn die Implementierung keine eindeutigen Gründe für die Auswahl eines Typs gegenüber einem anderen hat, wählt sie einfach einen ganzzahligen Typ aus, der die Anforderungen an Signatur und Breite erfüllt.
Es wird jedoch nicht angegeben, warum diese "schnellen" Ganzzahltypen schneller sind.
- Warum sind diese schnellen Ganzzahltypen schneller als die anderen Ganzzahltypen?
Ich habe die Frage mit C ++ markiert, da die schnellen Ganzzahltypen auch in C ++ 17 in der Header-Datei von verfügbar sind cstdint
. Leider gibt es in ISO / IEC 14882: 2017 (C ++ 17) keinen solchen Abschnitt über ihre Erklärung; Ich hatte diesen Abschnitt ansonsten im Textkörper der Frage implementiert.
Information: In C werden sie in der Header-Datei von deklariert stdint.h
.
typedef
Aussagen. In der Regel erfolgt dies auf der Ebene der Standardbibliothek. Natürlich sind die C - Standard legt keine wirkliche Beschränkung auf das, was sietypedef
zu - so zum Beispiel eine typische Implementierung ist , umint_fast32_t
einetypedef
vonint
auf einem 32-Bit - System, sondern eine hypothetische Compiler könnte zum Beispiel eine Implementierung__int_fast
intrinsischen Typ und versprechen etwas Phantasie zu tun Optimierungen, um von Fall zu Fall den schnellsten Maschinentyp für Variablen dieses Typs auszuwählen, und dann könnte die Bibliothek genautypedef
das tun.Antworten:
Stellen Sie sich eine CPU vor, die nur 64-Bit-Arithmetikoperationen ausführt. Stellen Sie sich nun vor, wie Sie eine vorzeichenlose 8-Bit-Addition auf einer solchen CPU implementieren würden. Es würde notwendigerweise mehr als eine Operation erfordern, um das richtige Ergebnis zu erzielen. Auf einer solchen CPU sind 64-Bit-Operationen schneller als Operationen auf anderen ganzzahligen Breiten. In dieser Situation
Xint_fastY_t
könnte alles vermutlich ein Alias vom 64-Bit-Typ sein.Wenn eine CPU schnelle Operationen für schmale Ganzzahltypen unterstützt und daher ein breiterer Typ nicht schneller als ein schmalerer Typ ist, ist dies kein
Xint_fastY_t
Alias des breiteren Typs, der zur Darstellung aller Y-Bits erforderlich ist.Aus Neugier habe ich die Größe einer bestimmten Implementierung (GNU, Linux) auf einigen Architekturen überprüft. Diese sind nicht für alle Implementierungen auf derselben Architektur gleich:
Beachten Sie, dass Operationen an größeren Typen zwar schneller sein können, diese Typen jedoch auch mehr Speicherplatz im Cache beanspruchen und ihre Verwendung daher nicht unbedingt zu einer besseren Leistung führt. Darüber hinaus kann man nicht immer darauf vertrauen, dass die Implementierung überhaupt die richtige Wahl getroffen hat. Wie immer ist eine Messung erforderlich, um optimale Ergebnisse zu erzielen.
Screenshot der Tabelle für Android-Benutzer:
(Android hat keine Box-Zeichen in der Mono-Schriftart - ref )
quelle
Sie sind es nicht, zumindest nicht zuverlässig.
Die schnellen Typen sind einfach typedefs für reguläre Typen, es liegt jedoch an der Implementierung, wie sie definiert werden. Sie müssen mindestens die gewünschte Größe haben, können aber auch größer sein.
Es ist richtig, dass auf einigen Architekturen einige Ganzzahltypen eine bessere Leistung aufweisen als andere. Beispielsweise hatten frühe ARM- Implementierungen Speicherzugriffsanweisungen für 32-Bit-Wörter und für vorzeichenlose Bytes, aber sie hatten keine Anweisungen für Halbwörter oder vorzeichenbehaftete Bytes. Die Anweisungen für Halbwörter und vorzeichenbehaftete Bytes wurden später hinzugefügt, bieten jedoch immer noch weniger flexible Adressierungsoptionen, da sie in den freien Codierungsbereich eingefügt werden mussten. Darüber hinaus arbeiten alle tatsächlichen Datenverarbeitungsanweisungen in ARM mit Wörtern. In einigen Fällen kann es daher erforderlich sein, kleinere Werte nach der Berechnung auszublenden, um korrekte Ergebnisse zu erzielen.
Es gibt jedoch auch das konkurrierende Problem des Cache-Drucks, selbst wenn mehr Anweisungen zum Laden / Speichern / Verarbeiten eines kleineren Werts erforderlich sind. Der kleinere Wert kann immer noch eine bessere Leistung erzielen, wenn er die Anzahl der Cache-Fehler verringert.
Die Definitionen der Typen auf vielen gängigen Plattformen scheinen nicht durchdacht worden zu sein. Insbesondere moderne 64-Bit-Plattformen unterstützen 32-Bit-Ganzzahlen in der Regel gut, doch die "schnellen" Typen sind auf diesen Plattformen häufig unnötig 64-Bit.
Darüber hinaus werden C-Typen Teil des ABI der Plattform. Selbst wenn ein Plattformanbieter feststellt, dass er dumme Entscheidungen getroffen hat, ist es schwierig, diese dummen Entscheidungen später zu ändern.
Ignorieren Sie die "schnellen" Typen. Wenn Sie sich wirklich Gedanken über die Leistung von Ganzzahlen machen, vergleichen Sie Ihren Code mit allen verfügbaren Größen.
quelle
Die schnellen Typen sind nicht schneller als alle anderen Integer-Typen - sie sind tatsächlich identisch mit einem "normalen" Integer-Typ (sie sind nur ein Alias für diesen Typ) - welcher Typ auch immer der schnellste ist, um einen Wert von zu halten mindestens so viele Bits.
Es ist nur plattformabhängig, für welchen Integer-Typ jeder schnelle Typ ein Alias ist.
quelle