Beschleunigen Sie die ADD-Schleife des x64-Assemblers

Ich arbeite an der Arithmetik zur Multiplikation sehr langer Ganzzahlen (ca. 100.000 Dezimalstellen). Als Teil meiner Bibliothek möchte ich zwei lange Nummern hinzufügen.

Das Profiling zeigt, dass mein Code bis zu 25% seiner Zeit in den Routinen add () und sub () ausgeführt wird. Es ist daher wichtig, dass sie so schnell wie möglich sind. Ich sehe aber noch nicht viel Potenzial. Vielleicht kannst du mir etwas Hilfe, Rat, Einsicht oder Ideen geben. Ich werde sie testen und mich bei Ihnen melden.

Bisher führt meine Add-Routine einige Einstellungen durch und verwendet dann eine 8-fach entrollte Schleife:

mov rax, QWORD PTR [rdx+r11*8-64]
mov r10, QWORD PTR [r8+r11*8-64]
adc rax, r10
mov QWORD PTR [rcx+r11*8-64], rax

Es folgen 7 weitere Blöcke mit unterschiedlichen Offsets und dann werden Schleifen ausgeführt.

Ich habe früher versucht, die Werte aus dem Speicher zu laden, aber das hat nicht geholfen. Das liegt wohl am guten Prefetching. Ich benutze eine Intel i7-3770 Ivy Bridge 4-Core-CPU. Aber ich möchte Code schreiben, der auf jeder modernen CPU gut funktioniert.

Bearbeiten: Ich habe einige Timings durchgeführt: Es werden 1k Wörter in ungefähr 2,25 Zyklen / Wort hinzugefügt. Wenn ich den ADC entferne, so dass nur die MOVs übrig bleiben, dauert es noch ca. 1,95 Zyklen / Wort. Der Hauptengpass scheint also der Speicherzugriff zu sein. Eine Bibliothekmemcpy() Arbeitet in ca. 0,65 Zyklen / Wort, hat aber nur einen Eingang, nicht zwei. Trotzdem ist es aufgrund der Verwendung von SSE-Registern viel schneller, denke ich.

Einige Fragen:

Ist es sinnvoll, die Struktur "Laden, Laden, Hinzufügen, Speichern" zu verwenden, oder würde eine Funktion "Laden, Hinzufügen zum Speicher" helfen? Bisher zeigten meine Tests keine Vorteile.Gibt es wie immer keine Hilfe von SSE (2,3,4) zu erwarten?Hat die Adressierung (skalierter Index plus Basis plus Offset) starke Auswirkungen? ich könnte benutzenADD r11, 8 stattdessen.Was ist mit der Schleife Abrollen? Ich habe gelesen, dass das Abrollen für die Architektur von Sandy Bridge (Agner Fog) schlecht warhttp://www.agner.org/optimize/). Soll es bevorzugt oder vermieden werden?(Bearbeiten) Kann ich SSE-Register verwenden, um Wörter in größeren Teilen aus dem Speicher zu laden und zu speichern und Wörter effizient mit Allzweckregistern und SSE-Registern auszutauschen?

Ich freue mich über Kommentare.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage