2016-12-19 7 views
-2

Ich bin sehr neu in der Montage und ich möchte alle pythagoreischen Tripel in einem Bereich von 1 bis 100 finden. Ich erzeuge alle Zahlen in C und alle anderen Berechnungen sollten in Assembly SSE erfolgen. Ich habe versucht, dies mit dem Befehl sqrt (ich habe alle versucht), aber ich konnte es nicht funktionieren .. Kann mir jemand sagen, wie es gemacht werden soll?Wie findet man Pythagoras-Tripel mit Hilfe der SSE-Montageanleitung?

Das ist, was ich bisher habe:

int main(){ 
      for (int i = 1; i <= 100; i++) 
      { 
       a++; 
       if (a > 100) 
        a = 0; 
       for (int j = 1; j <= 100; j++) 
       { 
        b++; 
        if (b > 100) 
         b = a; 
        _asm //tricky part begins here: 
        { 
         movups xmm0, a 
         movups xmm1, b 
         pmuludq xmm0, xmm0 
         pmuludq xmm1, xmm1 
         //movups xmm2, 0 
         //paddd xmm2, xmm0 
         //paddd xmm2, xmm1 
         movups z, xmm0 
        } 
        printf("%d\n", z); 
       } 
      } 
    } 
+7

"Ich möchte dies in der Montage tun, weil ich weiß, dass es schneller ist als C." Wie kannst du das Wissen? Weil es wahrscheinlich nicht sein wird. –

+6

Ich würde nicht davon ausgehen, dass Ihre handschriftliche asm schneller als eine C-Compiler-Ausgabe sein wird. Compiler sind intelligente, moderne CPUs sind komplex. – Blorgbeard

+0

Notieren Sie zuerst Ihren Algorithmus in C oder Pseudocode. – Jester

Antwort

2

Das grundlegende Problem mit Ihrem Ansatz ist, dass Sie bei 4 b Werten parallel suchen werden müssen, so dass Sie nicht nur aus einem C laden skalare Variable. Sie müssen Sachen in Vektorregistern über Schleifeniterationen hinweg behalten, da Sie nicht nur Vektoren aus dem Speicher oder etwas laden. Sie sollten die gesamte Schleife in asm schreiben, weil MSVC inline asm wegen des unvermeidlichen Aufwands, Ergebnisse in/out zu erhalten, kurze Sequenzen umschließt.

Natürlich wäre der beste Weg, diese Schleife zu vektorisieren, mit C-Intrinsic, nicht mit Inline-Asm. Dann können Sie den Compiler in die Hand nehmen, um bei Bedarf (und wenn möglich) einen besseren Asm zu erstellen, indem Sie seine asm-Ausgabe auf Ineffizienzen überprüfen. (Siehe Why is this C++ code faster than my hand-written assembly for testing the Collatz conjecture?)


Natürlich, wenn Sie wirklich nur effizienten Code erstellen wollen zur Erzeugung Pythagoreische Dreier-, Ihr Algorithmus Humbug ist, auch:

Wikipedia-Artikel hat einen generating a triple Abschnitt, die Formel Euklids beschreibt . Das Iterieren wäre ein anderes Problem als das Suchen nach Treffern in einer Brute-Force-Suche im gesamten Suchbereich a=[1..100] b=[1..100], da die Überprüfung, ob eine Zahl ein perfektes Quadrat ist, ziemlich langsam ist.

Auch zu erkennen, welche Vektorelemente einer Bedingung entsprechen, ist schwerfällig. Eine Packed-Compare-Anweisung und dann PMOVMSKB (oder MOVMSKPS) geben Ihnen eine Bitmap, aber dies funktioniert am besten, wenn Treffer selten sind, z. Implementierung memchr wo Ihre Schleife nach dem ersten Treffer stoppt.

+0

Beachten Sie, dass die Überprüfung des gesamten 'a = [1..100] b = [1..100]' Suchbereichs weniger als 0,005 Sekunden auf einem durchschnittlichen Desktop-Computer dauert, so dass die ganze Prämisse der Frage absurd ist. – user3386109

+0

@ user3386109: Das sind immer noch ein oder zwei Kerntaktzyklen, die lang genug sind, um mit den Leistungszählern genau zu messen. Aber offensichtlich gilt der Punkt eher für größere Suchbereiche. Und 'printf' in der Mitte der Suche bei jedem Treffer zu nennen ist lächerlich, vs. Speichern in einem Array oder etwas. –

Verwandte Themen