Von Agner Fog's "Optimizing Assembly" guide, Abschnitt 12.7: eine Schleife Beispiel. Einer der Absätze den Beispielcode zu diskutieren:Abhängigkeitskettenanalyse
[...] Analyse für Pentium M: ... 13 Uops bei 3 pro Takt = eine Iteration pro 4.33c Ruhestand Zeit.
Es gibt eine Abhängigkeitskette in der Schleife. Die Latenzen sind: 2 für Speicher lesen, 5 für Multiplikation, 3 für Subtraktion und 3 für Speicher schreiben, was insgesamt 13 Taktzyklen ergibt. Dies ist dreimal so viel wie die Ruhestandszeit, aber es ist keine Loop-getragene Abhängigkeit, weil die Ergebnisse von jeder Iteration im Speicher gespeichert und nicht in die nächste Iteration wiederverwendet werden. Der Out-of-Order-Ausführungsmechanismus und Pipelining ermöglichen, dass jede Berechnung starten kann, bevor die vorhergehende Berechnung beendet ist. Die einzige schleifengeführte Abhängigkeitskette ist
add eax,16
die
## Example 12.6b. DAXPY algorithm, 32-bit mode
[...] ; not shown: initialize some regs before the loop
L1:
movapd xmm1, [esi+eax] ; X[i], X[i+1]
mulpd xmm1, xmm2 ; X[i] * DA, X[i+1] * DA
movapd xmm0, [edi+eax] ; Y[i], Y[i+1]
subpd xmm0, xmm1 ; Y[i]-X[i]*DA, Y[i+1]-X[i+1]*DA
movapd [edi+eax], xmm0 ; Store result
add eax, 16 ; Add size of two elements to index
cmp eax, ecx ; Compare with n*8
jl L1 ; Loop back
Ich kann nicht verstehen, eine Latenzzeit von nur 1
hat warum die Abhängigkeitskette nicht eine ganze Durchsatz erhöhen. Ich weiß, dass es nur wichtig ist, den schlimmsten Engpass zu finden. Der größte Engpass, der vor der Betrachtung von Abhängigkeitsketten identifiziert wurde, war der Durchsatz von Fused-Domain-Uploads mit 4,33 Zyklen pro Iteration. Ich kann nicht verstehen, warum die Abhängigkeitskette kein größerer Engpass ist.Ich sehe, dass der Autor erklärt, dass es mit Out-of-Order-Ausführung und Pipelining verbunden ist, aber ich kann es nicht sehen. Ich meine jedoch, nur Multiplikation verursacht Latenz 5 Zyklen, so dass nur dieser Wert größer als 4 Zyklen ist.
Ich kann auch nicht verstehen, warum der Autor nicht über die Abhängigkeit hier schert:
add eax, 16 -> cmp eax, ecx -> jl L1
Schließlich muss zusätzlich ausgeführt werden, bevorcmp
undcmp
muss vorjl
ausgeführt werden.
PS: späteren Absätzen identifizieren die größte Engpass für Pentium M als dekodieren, um es zu einer Iteration pro 6c zu begrenzen, weil 128b Vektor ops zu zwei Uops je dekodieren. Für den Rest der Analyse und Analyse + Tuning für Core2, FMA4 Bulldozer und Sandybridge siehe den Agner Fog-Leitfaden.
Das Vergleich/Zweig-Paar würde vorhergesagt werden, so dass es nicht wirklich zählt. Abgesehen davon bin ich nicht sicher, was Sie fragen – harold
Können Sie bitte Agners Dokument verknüpfen und angeben, auf welchen Abschnitt und auf welches Beispiel Sie verweisen? –