128-Bit-Werte - Von XMM-Registern zum allgemeinen Zweck

8

Ich habe ein paar Fragen bezüglich der Verschiebung von XMM-Werten in allgemeine Register. Alle auf SO gefundenen Fragen konzentrieren sich auf das Gegenteil, nämlich die Übertragung von Werten in GP-Registern nach XMM.

  1. Wie kann ich einen XMM-Registerwert (128-Bit) in zwei 64-Bit-Allzweckregister verschieben?

    %Vor%
  2. Wie kann ich einen XMM-Registerwert (128 Bit) in vier 32-Bit-Mehrzweckregister verschieben?

    %Vor%
Goaler444 17.05.2017, 07:44
quelle

3 Antworten

8

Sie können die oberen Bits eines XMM-Registers nicht direkt in ein Mehrzweckregister verschieben.
Sie müssen einem zweistufigen Prozess folgen, der einen Umlauf in den Speicher oder die Zerstörung eines Registers beinhalten kann oder auch nicht.

in Registern

%Vor%

über den Speicher

%Vor%

langsam, aber zerstört nicht xmm register

%Vor%

Für 32 Bits ist der Code ähnlich:

in Registern

%Vor%

über den Speicher

%Vor%

langsam, aber zerstört nicht xmm register

%Vor%

Die 64-Bit-Schaltvariante kann in 2 Zyklen ausgeführt werden. Die pextrq Version benötigt mindestens 4. Für 32-Bit sind die Zahlen 4 bzw. 10.

    
Johan 17.05.2017, 07:52
quelle
1

Bei der Intel SnB-Familie (einschließlich Skylake) hat shuffle + movq oder movd die gleiche Leistung wie pextrq / d . Es dekodiert zu einem Shuffle-Up und einem movd up, also ist das nicht überraschend.

Bei AMD Ryzen hat pextrq anscheinend eine um 1 Zyklus niedrigere Latenz als shuffle + movq . pextrd/q ist 3c Latenz, und so ist movd/q , nach Agner Fogs Tabellen . Dies ist ein netter Trick (wenn es genau ist), da pextrd/q auf 2 Ups dekodiert (gegenüber 1 für movq ).

Da Shuffle eine Latenz ungleich Null haben, ist shuffle + movq immer streng schlechter als pextrq auf Ryzen (mit Ausnahme möglicher Front-End-Decodier- / Uop-Cache-Effekte).

Der größte Nachteil einer reinen ALU-Strategie zum Extrahieren aller Elemente ist der Durchsatz: Es benötigt eine Menge von ALU-Ups, und die meisten CPUs haben nur eine Ausführungseinheit / einen Port, die Daten von XMM in Integer verschieben können. Store / Reload hat eine höhere Latenz für das erste Element, aber einen besseren Durchsatz (weil moderne CPUs 2 Ladevorgänge pro Zyklus ausführen können). Wenn der Umgebungscode durch den ALU-Durchsatz eingeschränkt wird, könnte eine Store / Reload-Strategie gut sein. Vielleicht kann das Low-Element mit einem movd oder movq so ausgeführt werden, dass die Out-of-Order-Ausführung von dem, was es verwendet, gestartet wird, während der Rest der Vektordaten die Speicherweiterleitung durchläuft.

Eine weitere denkbare Option (neben dem, was Johan erwähnt hat) zum Extrahieren von 32-Bit-Elementen in Integer-Register ist das "Mischen" mit ganzzahligen Verschiebungen:

%Vor%

shr kann in Intel Haswell / Skylake auf p0 oder p6 laufen. p6 hat keine Vektor-ALUs, daher ist diese Sequenz ziemlich gut, wenn Sie eine niedrige Latenz, aber auch einen niedrigen Druck auf Vektor-ALUs wünschen.

Oder wenn Sie sie behalten möchten:

%Vor%     
Peter Cordes 07.08.2017 04:13
quelle
-1

Das Folgende behandelt sowohl get und set und scheint zu funktionieren (ich denke es ist AT & amp; T Syntax):

%Vor%     
Abdul Ahad 15.01.2018 13:41
quelle

Tags und Links