Wird __int128_t arithmetisch von GCC emuliert, selbst mit SSE?

7

Ich habe gehört, dass die von GCC bereitgestellten 128-Bit-Ganzzahl-Datentypen wie __int128_t emuliert und daher langsam sind. Ich verstehe jedoch, dass die verschiedenen SSE-Befehlssätze (SSE, SSE2, ..., AVX) zumindest einige Anweisungen für 128-Bit-Register eingeführt haben. Ich weiß nicht viel über SSE oder Assembler- / Maschinencode, also habe ich mich gefragt, ob mir jemand erklären könnte, ob die Arithmetik mit __int128_t emuliert wird oder keine modernen Versionen von GCC verwendet.

Der Grund, warum ich das frage, ist, weil ich mich frage, ob es sinnvoll ist, große Unterschiede in __int128_t Leistung zwischen verschiedenen Versionen von GCC zu erwarten, abhängig davon, welche SSE-Anweisungen genutzt werden.

Also, welche Teile von __int128_t arithmetic werden von GCC emuliert und welche Teile werden mit SSE-Anweisungen implementiert (falls vorhanden)?

    
Douglas B. Staple 15.05.2013, 13:31
quelle

3 Antworten

11

Ich habe zwei verschiedene Dinge in meiner Frage verwechselt.

Erstens, wie PaulR in den Kommentaren erklärt: "Es gibt keine 128-Bit-Rechenoperationen in SSE oder AVX (abgesehen von bitweisen Operationen)". In Anbetracht dessen muss eine 128-Bit-Arithmetik auf modernen x86-64-basierten Prozessoren (z. B. AMD Family 10 oder Intel Core-Architektur) emuliert werden. Das hat nichts mit GCC zu tun.

Der zweite Teil der Frage ist, ob die 128-Bit-Arithmetik-Emulation in GCC von SSE / AVX-Befehlen oder -Registern profitiert. Wie in den Kommentaren von PaulR impliziert, gibt es in SSE / AVX nicht viel, was es einfacher macht, 128-Bit-Arithmetik auszuführen; höchstwahrscheinlich werden hierfür x86-64-Anweisungen verwendet. Der Code, an dem ich interessiert bin, kann nicht mit -mno-sse kompiliert werden, aber er kompiliert sich gut mit -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4 -mno-sse4.1 -mno-sse4.2 -mno-avx -mno-avx2 und die Leistung ist nicht betroffen. Mein Code profitiert also nicht von modernen SSE-Anweisungen.

    
Douglas B. Staple 15.05.2013, 17:18
quelle
5

SSE2-AVX-Befehle sind für 8,16,32,64-Bit-Integer-Datentypen verfügbar. Sie sind hauptsächlich dazu gedacht, gepackte Daten zusammen zu behandeln, zum Beispiel kann das 128-Bit-Register vier 32-Bit-Ganzzahlen enthalten und so weiter.

    
MBo 15.05.2013 13:48
quelle
5

Obwohl SSE / AVX / AVX512 / etc. haben keinen 128bit-Modus (ihre Vektorelemente sind streng 64bit max, und Operationen werden einfach überlaufen), wie Paul R hat angedeutet , die Haupt-CPU unterstützt begrenzte 128-Bit-Operationen, indem er ein Paar Register verwendet.

  • Beim Multiplizieren von zwei regulären 64-Bit-Zahlen kann MUL / IMUL sein 128-Bit-Ergebnis im RAX / RDX-Registerpaar ausgeben.
  • Umgekehrt kann, wenn DIV / IDIV geteilt wird, seine Eingabe von dem RAX / RDX-Paar genommen werden, um eine 128-Nummer durch einen 64-Bit-Divisor zu teilen (und 64 Bits Quotient + 64 Bits Modulo ausgibt)

Natürlich ist die ALU der CPU 64 Bit, also - implizierte Intel-Dokumente - diese höheren zusätzlichen 64 Bit gehen auf Kosten von zusätzlichen Mikro-Ops im Mikrocode. Dies ist dramatischer für Divisionen (& gt; 3x mehr), die bereits viele Mikro-Ops benötigen, um verarbeitet zu werden.

Immer noch bedeutet das, dass unter bestimmten Umständen (wie zum Beispiel die Verwendung einer -Regel von drei zur Skalierung eines Wertes) ein Compiler normale CPU-Anweisungen ausgeben kann und keine 128-Bit-Emulation selbst ausführen kann .

Dies ist seit langer Zeit verfügbar:

  • seit 80386, 32Bits CPU könnte 64Bits Multiplikation / Division mit EAX: EDX-Paar
  • tun
  • seit 8086/88, 16Bits CPU könnte 32Bits Multiplikation / Division mit AX: DX-Paar
  • tun

(Was Additionen und Subtraktion angeht: Dank der Unterstützung von carry ist es ganz einfach, Additionen / Subtraktionen von Zahlen beliebiger Länge zu machen, die Ihren Speicher füllen können).

    
DrYak 26.03.2015 18:16
quelle

Tags und Links