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)?
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.
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.
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:
(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).