Leistung der C-Code-Schleife [Fortsetzung]


83

Diese Frage setzt sich auf meiner Frage hier fort (auf Anraten von Mystical):

Leistung der C-Code-Schleife


Wenn ich meine Frage fortsetze, würde der Code, der Intrinsics verwendet, sehr ähnlich aussehen, wenn ich gepackte Anweisungen anstelle von skalaren Anweisungen verwende:

for(int i=0; i<size; i+=16) {
    y1 = _mm_load_ps(output[i]);
    
    y4 = _mm_load_ps(output[i+12]);

    for(k=0; k<ksize; k++){
        for(l=0; l<ksize; l++){
            w  = _mm_set_ps1(weight[i+k+l]);

            x1 = _mm_load_ps(input[i+k+l]);
            y1 = _mm_add_ps(y1,_mm_mul_ps(w,x1));
            
            x4 = _mm_load_ps(input[i+k+l+12]);
            y4 = _mm_add_ps(y4,_mm_mul_ps(w,x4));
        }
    }
    _mm_store_ps(&output[i],y1);
    
    _mm_store_ps(&output[i+12],y4);
    }

Die gemessene Leistung dieses Kernels beträgt ungefähr 5,6 FP-Operationen pro Zyklus, obwohl ich erwarten würde, dass sie genau viermal so hoch ist wie die Leistung der skalaren Version, dh 4,1,6 = 6,4 FP-Operationen pro Zyklus.

Unter Berücksichtigung der Verschiebung des Gewichtsfaktors (danke für den Hinweis) sieht der Zeitplan folgendermaßen aus:

Zeitplan

Es sieht so aus, als würde sich der Zeitplan nicht ändern, obwohl es nach der movssOperation eine zusätzliche Anweisung gibt , die den Skalargewichtswert in das XMM-Register verschiebt und dann shufpszum Kopieren dieses Skalarwerts in den gesamten Vektor verwendet. Es scheint, dass der Gewichtsvektor bereit ist, für die mulpsZeit unter Berücksichtigung der Umschaltlatenz von der Last in die Gleitkommadomäne verwendet zu werden, sodass dies keine zusätzliche Latenz verursachen sollte.

Die movaps(ausgerichtet, verpackt bewegen), addpsund mulpsAnweisungen , die in diesem Kernel (mit Assembler - Code überprüft) verwendet werden , haben die gleiche Latenz & Durchsatz als ihre skalare Versionen, so dass dies keine zusätzliche Latenz entweder entstehen sollte.

Hat jemand eine Idee, wo dieser zusätzliche Zyklus pro 8 Zyklen ausgegeben wird, vorausgesetzt, die maximale Leistung, die dieser Kernel erzielen kann, beträgt 6,4 FP-Operationen pro Zyklus und er läuft mit 5,6 FP-Operationen pro Zyklus?


Übrigens, hier ist, wie die eigentliche Baugruppe aussieht:


Block x: 
  movapsx  (%rax,%rcx,4), %xmm0
  movapsx  0x10(%rax,%rcx,4), %xmm1
  movapsx  0x20(%rax,%rcx,4), %xmm2
  movapsx  0x30(%rax,%rcx,4), %xmm3
  movssl  (%rdx,%rcx,4), %xmm4
  inc %rcx
  shufps $0x0, %xmm4, %xmm4               {fill weight vector}
  cmp $0x32, %rcx 
  mulps %xmm4, %xmm0 
  mulps %xmm4, %xmm1
  mulps %xmm4, %xmm2 
  mulps %xmm3, %xmm4
  addps %xmm0, %xmm5 
  addps %xmm1, %xmm6 
  addps %xmm2, %xmm7 
  addps %xmm4, %xmm8 
  jl 0x401ad6 <Block x> 

Die Frage lautet nun wohl: "Warum fügt der shufpsBefehl alle 1,6 Iterationen 1 Zyklus hinzu?" Das ist eine schwierige
Frage

Ich würde erwarten, dass es keinen Overhead hat, da die Ausgabe von shufpsdirekt für die multpsOperation verfügbar sein sollte, da es sich um eine FP-Domäne handelt
Ricky

Leicht herauszufinden. Stellen Sie sicher, dass der Gewichtsvektor keine denormalisierten Werte enthält. Probieren Sie die Schleife ohne die Shuffle-Anweisung aus. Es wird keine nützlichen Ergebnisse liefern, aber vielleicht finden Sie heraus, welche Anweisung Sie zusätzliche Zyklen kostet (ich vermute natürlich das Mischen).
Gunther Piez

@Mystical: Ich sehe 0,75 Zyklen pro Schleifeniteration hinzugefügt. (War es nicht mein Kommentar über die Verwendung von 5 Zyklen anstelle von 4, der Sie zu Ihrer Antwort dort führte ... :-))
Gunther Piez

3
Zum einen fordern Sie jetzt das Vierfache der Cache-Bandbreite. Wie groß sind die Datengrößen? Passen sie in den L1-Cache?
Mysticial

Antworten:


3

Versuchen Sie es mit der EMON-Profilerstellung in Vtune oder einem gleichwertigen Tool wie oprof

EMON-Profilerstellung (Event Monitoring) => ähnelt einem zeitbasierten Tool, kann Ihnen jedoch mitteilen, welches Leistungsereignis das Problem verursacht. Sie sollten jedoch zuerst mit einem zeitbasierten Profil beginnen, um festzustellen, ob eine bestimmte Anweisung herausspringt. (Und möglicherweise die damit verbundenen Ereignisse, die Ihnen sagen, wie oft es an diesem IP einen Ruhestandsstand gab.)

Um die EMON-Profilerstellung verwenden zu können, müssen Sie eine Liste von Ereignissen durchlaufen, die von "den üblichen Verdächtigen" bis zu ...

Hier würde ich mit Cache-Fehlern und Ausrichtung beginnen. Ich weiß nicht, ob der von Ihnen verwendete Prozessor einen Zähler für Einschränkungen des HF-Anschlusses hat - das sollte es auch -, aber ich habe vor langer Zeit die EMON-Profilerstellung hinzugefügt, und ich weiß nicht, wie gut sie mit dem Hinzufügen von Ereignissen Schritt halten, die für die Mikroarchitektur geeignet sind.

Es kann auch möglich sein, dass es sich um ein Front-End, einen Befehlsabruf oder einen Stall handelt. Wie viele Bytes enthält diese Anweisung überhaupt? Auch dafür gibt es EMON-Events.


Antwort auf den Kommentar, dass Nehalem VTune keine L3-Ereignisse sehen kann: nicht wahr. Hier sind Dinge, die ich zum Kommentar hinzugefügt habe, die aber nicht passten:

Tatsächlich gibt es Leistungsindikatoren für den sogenannten Uncore LL3 / L3 $ /. Ich wäre sehr überrascht, wenn VTune sie nicht unterstützt. Sehen http://software.intel.com/sites/products/collateral/hpc/vtune/performance_analysis_guide.pdfverweist auf VTune und andere Tools wie PTU. Selbst ohne LL3-Ereignisse, wie David Levinthal sagt: "Der Intel® Core ™ i7-Prozessor hat ein" Latenzereignis ", das dem Daten-EAR-Ereignis der Itanium®-Prozessorfamilie sehr ähnlich ist. Dieses Ereignis erfasst Lasten und zeichnet die Anzahl der Ereignisse auf Zyklen zwischen der Ausführung des Befehls und der tatsächlichen Übermittlung der Daten. Wenn die gemessene Latenz größer ist als die in MSR 0x3f6, Bit 15: 0 programmierte minimale Latenz, wird der Zähler inkrementiert. Der Zählerüberlauf aktiviert den PEBS-Mechanismus und den nächsten Ereignisse, die den Latenzschwellenwert erfüllen, die gemessene Latenz, die virtuelle oder lineare Adresse und die Datenquelle werden in 3 zusätzliche Register im PEBS-Puffer kopiert. Da die virtuelle Adresse an einem bekannten Ort erfasst wird, Der Abtasttreiber könnte auch eine virtuelle zu physikalische Übersetzung ausführen und die physikalische Adresse erfassen. Die physische Adresse identifiziert den NUMA-Heimatort und ermöglicht im Prinzip eine Analyse der Details der Cache-Belegung. "Auf Seite 35 verweist er auch auf VTune-Ereignisse wie L3 CACHE_HIT_UNCORE_HIT und L3 CACHE_MISS_REMOTE_DRAM. Manchmal müssen Sie die Zahlen nachschlagen Codes und programmieren sie in die untere Ebene von VTune, aber ich denke in diesem Fall ist es in der hübschen Benutzeroberfläche sichtbar.


OK, in http://software.intel.com/en-us/forums/showthread.php?t=77700&o=d&s=lr "erklärt" ein VTune-Programmierer in Russland (glaube ich), dass Sie nicht auf Uncore testen können Veranstaltungen.

Er liegt falsch - Sie könnten zum Beispiel nur eine CPU aktivieren und sinnvoll probieren. Ich glaube auch, dass es die Möglichkeit gibt, fehlende L3-Daten zu markieren, wenn sie zur CPU zurückkehren. Insgesamt weiß der L3, an welche CPU er Daten zurückgibt, sodass Sie definitiv eine Stichprobe erstellen können. Möglicherweise wissen Sie nicht, welcher Hyperthread verwendet wird, aber Sie können ihn erneut deaktivieren und in den Single-Thread-Modus wechseln.

Aber es sieht so aus, als müssten Sie, wie üblich, AROUND VTune arbeiten, nicht damit, um dies zu tun.

Versuchen Sie zuerst das Latenzprofil. Das befindet sich vollständig in der CPU, und es ist unwahrscheinlich, dass die VTune-Leute es zu sehr vermasselt haben.

Und ich sage noch einmal, es ist wahrscheinlich, dass Ihr Problem im Kern liegt, nicht in L3. VTune sollte also in der Lage sein, damit umzugehen.


Versuchen Sie "Cycle Accounting" per Levinthal.


Danke für deine Reaktion. Ich verwende VTune, um meine Anwendung zu analysieren. Das Problem mit der Nehalem-Architektur besteht jedoch darin, dass der L3-Cache zum off-coreTeil des Kerns gehört, sodass für diesen Teil keine Leistungsereigniszähler verfügbar sind. Daher ist es schwierig, Cache-Fehler usw. abzuschätzen.
Ricky

Tatsächlich gibt es Leistungsindikatoren für den sogenannten Uncore LL3 / L3 $ /. Ich wäre sehr überrascht, wenn VTune sie nicht unterstützt. Siehe software.intel.com/sites/products/collateral/hpc/vtune/…
Krazy Glew

Ich habe mehr geschrieben, als in einen Kommentar passen würde, habe versucht, ihn in die Antwort zu verschieben und den ursprünglichen Kommentar zu bereinigen, aber Kommentare können nur 5 Minuten lang bearbeitet werden. Kurzversion: Mit VTune können Sie L3-Cache-Fehler sehen. Auch ohne Uncore-Unterstützung mit Latenzprofilierung - und mit Uncore-Unterstützung.
Krazy Glew

Und insgesamt vermute ich, dass Ihr Problem nicht L3-Cache-Fehler ist. Eher ein Frontend-Event.
Krazy Glew

@ KrazyGlew: Ihre Vermutung ist richtig, er ist ein Russe aus der Russischen Föderation. Hier ist sein Profil auf LinkedIn - linkedin.com/in/vtsymbal
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.