J'ai exécuté le code d'assemblage suivant: (qui itère 1000 fois dans un tableau de 10 000 000 éléments de 4 octets chacun) sur un processeur Intel Core i7 (avec cache de données 32 Ko L1 et 64B L1 taille de ligne de cache)Comportement du processeur et du cache Intel Core i7
main:
.LFB0:
.cfi_startproc
mov edx, 1000
jmp .L2
.L3:
mov ecx, DWORD PTR v[0+eax*4]
add eax, 1
cmp eax, 10000000
jl .L3
sub edx, 1
je .L4
.L2:
mov eax, 0
jmp .L3
.L4:
mov eax, 0
ret
.cfi_endproc
Perf donne les statistiques suivantes:
10,135,716,950 L1-dcache-loads
601,544,266 L1-dcache-load-misses # 5.93% of all L1-dcache hits
4.747253821 seconds time elapsed
Cela rend tout à fait sens parce que j'accède 1 000 * 10 000 000 = 10 000 000 000 éléments en mémoire, et ligne de cache étant 64B (avec un élément dans le vecteur de 4 B) cela signifie un cache cache L1 à e très 16 éléments (donc environ 625 000 000 cache manquants).
Maintenant, j'ai "déroula" une partie de la boucle et le code est:
.cfi_startproc
mov edx, 1000
jmp .L2
.L3:
mov ecx, DWORD PTR v[0+eax*4]
mov ecx, DWORD PTR v[0+eax*4 + 4]
mov ecx, DWORD PTR v[0+eax*4 + 8]
mov ecx, DWORD PTR v[0+eax*4 + 12]
add eax, 4
cmp eax, 2500000
jl .L3
sub edx, 1
je .L4
.L2:
mov eax, 0
jmp .L3
.L4:
mov eax, 0
ret
.cfi_endproc
comment Perf donne les statistiques suivantes:
2,503,436,639 L1-dcache-loads
123,835,666 L1-dcache-load-misses # 4.95% of all L1-dcache hits
0.629926637 seconds time elapsed
Je ne peux pas comprendre pourquoi?
1) Il y a moins de charges de cache L1, puisque j'accède à la même quantité de données?
2) Le code est 6 fois plus rapide que la première version? Je sais qu'il a à faire avec l'exécution hors de l'ordre et l'exécution superscalaire, mais je ne peux pas expliquer cela en détail (je veux comprendre exactement ce qui provoque cette accélération).
Ok :(Je fixe ce maintenant les coups de cache et les charges sont ok Mais il y a encore exécuté plus rapidement..? 2.617806762 secondes pourquoi il est seulement parce qu'il doit faire moins d'instructions de saut – SebiSebi
déroulage apporte généralement des gains Second?. Vérifiez également ce qui se passe si vous ne chargez pas toujours sur ecx mais sur des registres différents (les 3 premières charges sont "non efficaces" car la dernière écrase toujours ecx pour que CPU puisse voir cela et fasse un peu de magie ici) .Vérifiez également ce qui se passe si vous vous déroulez 8 ou 16 fois. – Anty