Meine CPU ist IvyBridge. Betrachten wir ein Beispiel von Agners Fog optimizing_assembly, meine ich. 12.6 Kapitel und das 12.10a Beispiel:Zwei Loop-getragene Abhängigkeitskette. Welcher ist wichtig?
movsd xmm2, [x]
movsd xmm1, [one]
xorps xmm0, xmm0
mov eax, coeff
L1:
movsd xmm3, [eax] ; c[i]
mulsd xmm3, xmm1 ; c[i]*x^i
mulsd xmm1, xmm2 ; x^(i+1)
addsd xmm0, xmm3 ; sum += c[i]*x^i
add eax, 8
cmp eax, coeff_end
jb L1
Und das Frontend kein Engpass ist (es ist offensichtlich wegen der Latenz der Multiplikation).
Wir haben zwei schleifengeführte Abhängigkeiten (I übersprungenen add eax, 8
): 1. mulsd xmm1, xmm2
Latenz von 5 Zyklen 2. addsd xmm0, xmm3
Latenzzeit von 3 Zyklen
BTW, ich habe einen proble entscheiden: Soll ich zusammenzufassen (5 + 3 = 8) oder um den größten, dh 5 Zyklus zu bekommen?
Ich habe es für 10000000 Elemente Array getestet. Und es dauert 6,7 Zyklen pro Iteration (nach perf) und 5,9 Zyklen pro Iteration nach Agner-Tool.
Bitte erklären Sie, warum es statt nur 5 Zyklen 6/7 Zyklen dauert?
Sie können die Kosten für das Laden der Daten aus dem RAM nicht ignorieren. –
Können Sie versuchen, nützlichere Fragetitel zu schreiben? "Loop zu langsam" sagt nichts weiter, außer dass Sie die Tags [optimization] oder [performance] hätten verwenden sollen. Einige deiner vorherigen Fragen hatten auch wirklich schreckliche Titel wie "Zu viele Zyklen". –
Sieht so aus, als wäre die längste schleifenverschleppte dep-Kette die 'mulsd xmm1, xmm2'. Der 'mul' der nächsten Iteration kann beginnen, bevor 'addsd' dieser Iteration beendet ist, weil sie nicht von' xmm0' abhängt. Die anderen Instruktionen hängen von dieser Schleifen-getragenen Mul-Kette ab, aber sie verzweigen für jede Iteration eine separate Dep-Kette (mit Ausnahme des "addsd", das ebenfalls eine Schleife trägt, aber eine niedrigere Latenz hat). –