Was ist der Unterschied zwischen intXX_t und int_fastXX_t?

Lesezeit: 6 Minuten

Benutzeravatar von Coren
Coren

Ich habe kürzlich entdeckt, dass es einen Standard gibt am schnellsten Art, hauptsächlich int_fast32_t und int_fast64_t.

Mir wurde immer gesagt, dass man für den normalen Gebrauch in der Mainstream-Architektur besser auf Klassik zurückgreifen sollte int & lang die immer zur standardmäßigen Lesekapazität des Prozessors passen sollten und so unnötige numerische Konvertierungen vermeiden.

Im C99-Standard heißt es in §7.18.1.3p2:

“Der Typedef-Name int_fastN_t bezeichnet den schnellsten Integer-Typ mit Vorzeichen und einer Breite von mindestens N. Der Typedef-Name uint_fastN_t bezeichnet den schnellsten Integer-Typ ohne Vorzeichen mit einer Breite von mindestens N.”

Und es gibt auch ein Zitat darüber in §7.18.1.3p1 :

“Es ist nicht garantiert, dass der angegebene Typ für alle Zwecke am schnellsten ist; wenn die Implementierung keinen klaren Grund hat, einen Typ einem anderen vorzuziehen, wird einfach ein ganzzahliger Typ ausgewählt, der die Anforderungen an Vorzeichen und Breite erfüllt.”

Mir ist unklar was am schnellsten wirklich bedeutet. Ich verstehe nicht, wann ich diesen Typ verwenden soll und wann nicht.

Ich habe ein wenig darüber gegoogelt und das einige gefunden offen Quelle Projekte haben einige ihrer Funktionen darauf geändert, aber nicht alle. Sie haben nicht wirklich erklärt, warum sie ein Teil geändert haben, und nur ein Teil ihres Codes dazu.

Wissen Sie, was die speziellen Fälle/Verwendungen sind, wenn int_fastXX_t sind Ja wirklich schneller als die klassischen ?

  • +1. Ich frage mich das schon seit geraumer Zeit und das C Begründung schweigt zu dem Thema.

    – Fred Foo

    11. Februar 2012 um 11:18 Uhr

Benutzeravatar von ouah
ouah

Im C99-Standard 7.18.1.3 Schnellste Ganzzahltypen mit minimaler Breite.

(7.18.1.3p1) “Jeder der folgenden Typen bestimmt einen Integer-Typ, der normalerweise am schnellsten225) unter allen Integer-Typen arbeitet, die mindestens die angegebene Breite haben.”

225) “Es ist nicht garantiert, dass der designierte Typ für alle Zwecke der schnellste ist; wenn die Implementierung keinen klaren Grund hat, einen Typ einem anderen vorzuziehen, wird sie einfach einen ganzzahligen Typ auswählen, der die Vorzeichen- und Breitenanforderungen erfüllt.”

und

(7.18.1.3p2) “Der Typedef-Name int_fastN_t bezeichnet den schnellsten Integer-Typ mit Vorzeichen und einer Breite von mindestens N. Der Typedef-Name uint_fastN_t bezeichnet den schnellsten Integer-Typ ohne Vorzeichen mit einer Breite von mindestens N.”

Die Typen int_fastN_t und uint_fastN_t sind Gegenstücke zu den Integer-Typen mit exakter Breite intN_t und uintN_t. Die Umsetzung garantiert, dass sie mindestens dauern N Bits, aber die Implementierung kann mehr Bits aufnehmen, wenn sie eine Optimierung mit größeren Typen durchführen kann; es garantiert nur, dass sie mindestens nehmen N Bits.

Auf einem 32-Bit-Rechner beispielsweise uint_fast16_t könnte als definiert werden unsigned int eher als als unsigned short weil es effizienter wäre, mit Typen von Maschinenwortgrößen zu arbeiten.

Ein weiterer Grund für ihre Existenz ist, dass die Integer-Typen mit exakter Breite in C optional sind, aber die schnellsten Integer-Typen mit minimaler Breite und die Integer-Typen mit minimaler Breite (int_leastN_t und uint_leastN_t) sind erforderlich.

  • Das erklärt nicht viel. “Auf einem 32-Bit-Rechner uint_fast16_t könnte als definiert werden unsigned int“– ja, aber du könntest einfach alt nehmen unsigned int direkt, da es sich um die native Integer-Breite handelt und der Standard garantiert, dass sie mindestens 16 Bit breit ist. Ähnlich, long trifft ungefähr die gleichen Einschränkungen wie int_fast32_t.

    – Fred Foo

    11. Februar 2012 um 11:15 Uhr

  • Ich habe die Begründung gelesen, aber das sagt es nicht Wenn es ist schneller, für welche Art von spezifischer Verwendung? Wenn das ist Ja wirklich immer schneller, warum verwenden wir sie nicht standardmäßig?

    – Corin

    11. Februar 2012 um 11:23 Uhr

  • @larsmann uint_fast16_t könnte ein Alias ​​für sein unsigned int in einer 32-Bit-Maschine und für unsigned long in einem 64-Bit-Rechner. Verwenden unsigned int Anstatt von uint_fast16_t in Ihrem Programm werden nicht gleich sein, wenn Sie beabsichtigen, Ihr Programm auf verschiedenen Maschinen zu kompilieren.

    – au

    11. Februar 2012 um 11:24 Uhr

  • @ouah das ist meine Hauptfrage: Wann sollte ich es verwenden? Haben Sie eine Beispielanwendung für eine Hauptarchitektur?

    – Corin

    11. Februar 2012 um 11:34 Uhr

  • @Coren Ich gebe bereits ein Beispiel, das Problem, das Sie erwähnt haben, ist die Definition von schnell. Die Implementierung kann sich dafür entscheiden, schnelle arithmetische Operationen gegenüber einem schnellen Array-Zugriff oder das Gegenteil zu bevorzugen. Aus diesem Grund verwende ich diese Typen nicht persönlich, ich ziehe es vor, einen Exact-with-Integer-Typ zu wählen, der meinen Anforderungen entspricht.

    – au

    11. Februar 2012 um 11:43 Uhr

Benutzeravatar von Pr0methean
Pr0methean

Gnu-libc definiert {int,uint}_fast{16,32}_t als 64-Bit beim Kompilieren für 64-Bit-CPUs und andernfalls als 32-Bit. Operationen mit 64-Bit-Integern sind auf Intel- und AMD-64-Bit-x86-CPUs schneller als die gleichen Operationen mit 32-Bit-Integern.

  • Ja, sollte aber nicht int 64-Bit auf einer solchen Maschine sein?

    – potrzebie

    13. Oktober 2014 um 10:03 Uhr


  • Nein, int kann so klein wie 16 Bit sein, und seine Größe hängt normalerweise vom Compiler, aber nicht von der Plattform ab. Dies ist wahrscheinlich ein Artefakt des 16- auf 32-Bit-Übergangs.

    – Pr0methean

    3. November 2014 um 8:50 Uhr


  • Ihr Link für “schneller” vergleicht 32-Bit- und 64-Bit-CPU-Modi für die Ausführung einiger komplexer Aufgaben. Er vergleicht nicht die Leistung von 32-Bit- und 64-Bit-Ganzzahlen im selben CPU-Modus.

    – Plugwash

    3. Februar 2016 um 19:54 Uhr

Außer auf exotischer Hardware wird es wohl keinen Unterschied geben int32_t und int16_t existieren gar nicht.

In diesem Fall könnten Sie verwenden int_least16_t um den kleinsten Typ zu erhalten, der 16 Bit enthalten kann. Könnte wichtig sein, wenn Sie Platz sparen möchten.

Auf der anderen Seite verwenden int_fast16_t Vielleicht bekommen Sie einen anderen Typ, größer als int_least16_t aber möglicherweise schneller für “typische” ganzzahlige Verwendung. Bei der Implementierung muss berücksichtigt werden, was schneller und was typisch ist. Vielleicht ist dies für einige spezielle Hardware offensichtlich?

Auf den meisten gängigen Computern sind diese 16-Bit-Typen alle eine Typdefinition für shortund Sie müssen sich nicht darum kümmern.

Benutzeravatar von Plugwash
Plugwash

IMO sind sie ziemlich sinnlos.

Dem Compiler ist es egal, wie Sie einen Typ nennen, sondern nur, welche Größe er hat und welche Regeln für ihn gelten. Wenn also int, in32_t und int_fast32_t alle 32-Bit auf Ihrer Plattform sind, werden sie mit ziemlicher Sicherheit alle die gleiche Leistung erbringen.

Die Theorie besagt, dass Implementierer der Sprache basierend darauf wählen sollten, was auf ihrer Hardware am schnellsten ist, aber die Standardautoren haben nie eine klare Definition des Schnellsten festgelegt. Fügen Sie dies der Tatsache hinzu, dass Plattformbetreuer die Definition solcher Typen nur ungern ändern (weil dies ein ABI-Bruch wäre) und die Definitionen zu Beginn des Lebens einer Plattform willkürlich ausgewählt werden (oder von anderen Plattformen geerbt wurden, die die C-Bibliothek war portiert von) und nie wieder berührt.

Wenn Sie sich auf dem Niveau der Mikrooptimierung befinden, von dem Sie glauben, dass die variable Größe einen signifikanten Unterschied machen kann, vergleichen Sie die verschiedenen Optionen mit einem Benchmark dein Code an dein Prozessor. Ansonsten mach dir keine Sorgen. Die “schnellen” Typen fügen meiner Meinung nach nichts Nützliches hinzu.

1411340cookie-checkWas ist der Unterschied zwischen intXX_t und int_fastXX_t?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy