Latenz der CPU-Anweisungen auf x86- und x64-Prozessoren


13

Ich suche nach einer Tabelle oder ähnlichem, die mir helfen könnte, die Effizienz des Assembler-Codes zu berechnen.

Wie ich weiß, benötigt die Bitverschiebung 1 CPU-Takt, aber ich schaue wirklich, wie viel Addition (Subtraktion sollte gleich sein), Multiplikation und wie man vermutlich die Teilungszeit berechnet, wenn ich Werte kenne, die sich teilen.

Ich brauche wirklich Informationen über ganzzahlige Werte, aber Float-Ausführungszeiten sind auch willkommen.


Antworten:


9

Im Allgemeinen benötigt jede dieser Operationen auch einen einzelnen Taktzyklus, um ausgeführt zu werden, wenn sich die Argumente in Registern in den verschiedenen Phasen der Pipeline befinden.

Was meinst du mit Latenz? Wie viele Zyklen verbringt eine Operation in der ALU?

Diese Tabelle ist möglicherweise hilfreich: http://www.agner.org/optimize/instruction_tables.pdf

Da moderne Prozessoren superskalar sind und nicht in der richtigen Reihenfolge ausgeführt werden können, erhalten Sie häufig Gesamtbefehle pro Zyklus, die 1 überschreiten. Die Argumente für den Makrobefehl sind am wichtigsten, aber die Operation ist auch wichtig, da Teilungen länger dauern als XOR (<1) Zykluslatenz).

Viele x86-Anweisungen können mehrere Zyklen benötigen, um einige Phasen abzuschließen, wenn sie komplex sind (z. B. REP-Befehle oder schlechteres MWAIT).


3
Die Ganzzahlmultiplikation beträgt bei allen neueren x86-CPUs mindestens 3c Latenz (bei einigen älteren CPUs höher). Bei vielen CPUs ist die Pipeline vollständig, sodass der Durchsatz 1 pro Takt beträgt. Dies können Sie jedoch nur erreichen, wenn Sie drei unabhängige Multiplikationen im Flug haben. (FP-Multiplikation auf Haswell ist 5c Latenz, 0,5c Durchsatz, also benötigen Sie 10 im Flug, um den Durchsatz zu sättigen). Division ( divund idiv) ist noch schlimmer: Es ist mikrocodiert und hat eine viel höhere Latenz als addoder shrund ist auf keiner CPU vollständig Pipeline-fähig. All dies stammt direkt aus den Anweisungstabellen von Agner Fog. Es ist also gut, dass Sie das verlinkt haben.
Peter Cordes


7

Die Berechnung der Effizienz von Baugruppencode ist in diesen Tagen von Super Scalar-Pipelines mit nicht ordnungsgemäßer Ausführung nicht der beste Weg. Dies hängt vom Prozessortyp ab. Die Anweisungen variieren sowohl vorher als auch nachher (Sie können zusätzlichen Code hinzufügen und ihn manchmal schneller ausführen lassen!). Einige Operationen (insbesondere Division) können eine Reihe von Ausführungszeiten haben, selbst auf älteren, besser vorhersehbaren Chips. Tatsächlich ist das Timing vieler Iterationen der einzige Weg.


Ich weiß das, aber ich brauche das nicht in einem echten Projekt, sondern in einer Art einem lustigen Programmierprojekt.
ST3

Ob Sie es wirklich oder zum Spaß brauchen, ändert nichts an der Antwort für diese Prozessorlinie. Haben Sie darüber nachgedacht, stattdessen auf einen deterministischeren Prozessor wie einen Propeller-Chip umzusteigen?
Brian Knoblauch

3
Selbst bei einem Skalar können Fehlvorhersagen und Cache-Fehler in der Reihenfolge der Implementierung zu Abweichungen in der Laufzeit führen.
Paul A. Clayton

Bei rein CPU-gebundenen Dingen (keine Cache-Fehler, keine Verzweigungsfehler) wird das CPU-Verhalten so detailliert verstanden, dass die statische Analyse häufig fast genau vorhersagen kann, wie viele Zyklen pro Iteration eine Schleife auf einer bestimmten CPU (z. B. Intel Haswell) benötigt. Beispiel: Sehen Sie sich diese SO-Antwort an, in der ich anhand des vom Compiler generierten ASM erkläre, warum die Branchy-Version fast genau 1,5-mal schneller lief als die CMOV-Version auf der Sandybridge-CPU des OP, aber auf meinem Skylake viel näher.
Peter Cordes

Wenn Sie aus Leistungsgründen asm von Hand schreiben, ist es tatsächlich nützlich, nach Latenz- und Durchsatzengpässen bei Intel- und AMD-CPUs zu suchen. Es ist jedoch schwierig, und manchmal ist das, was für AMD optimal ist, nicht das, was für Intel optimal ist.
Peter Cordes

4

Informationen zu Intel CPU finden Sie in den Handbüchern für Intel Software-Entwickler . Beispielsweise beträgt die Latenz 1 Zyklus für eine Ganzzahladdition und 3 Zyklen für eine Ganzzahlmultiplikation.

Ich weiß nichts über Multiplikation, aber ich erwarte, dass die Addition immer einen Zyklus dauert.


Ein Zyklus, außer wenn er "frei" ist (parallel, wenn die Pipelines korrekt ausgerichtet sind) oder aufgrund eines Cache-Fehlers länger dauert. :-)
Brian Knoblauch

2
Derzeit (2018) sind diese Informationen in Anhang C mit dem Titel "Anweisungslatenz und -durchsatz" des Dokuments 248966 "Referenzhandbuch zur Optimierung von Intel® 64- und IA-32-Architekturen" verfügbar, das auch auf der in der Antwort verlinkten Seite verfügbar ist
stefanct
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.