Librairie pour optimisation
Librairie pour optimisation
Je viens de créer une petite librairie pour me faciliter l'optimisation de code. Elle permet de visualisé le nombre de cycles CPU employé par un code sous forme de diagramme. J'ai consacré une page sur mon site pour expliquer son fonctionnement. Il y a aussi un exemple. RX14 -> librairie ITest
tes diagrammes sont à l'échelle ? je dirais que non , si je regarde le premier diagramme avec les trois tests vide, les bandes vertes indiquent l'échelle du nombre de cycles.Moins on consomme de cycles moins on recouvre les bandes vertes ? c'est ça ?
Pourtant le dernier test qui est à 208 cycles en moyenne , c'est celui qui recouvre le plus les bandes vertes .
C'est encore plus flagrant dans le dernier diagramme, c'est le test le plus court qui recouvre le plus les bandes vertes. Et pourtant c'est pas le test le plus long qui recouvre le moins les bandes.
J'espère que tu arrives à comprendre ce que je veux raconter
Pourtant le dernier test qui est à 208 cycles en moyenne , c'est celui qui recouvre le plus les bandes vertes .
C'est encore plus flagrant dans le dernier diagramme, c'est le test le plus court qui recouvre le plus les bandes vertes. Et pourtant c'est pas le test le plus long qui recouvre le moins les bandes.
J'espère que tu arrives à comprendre ce que je veux raconter

Les diagrammes n'ont pas pour but d'être comparés entre eux, mais de montrer l'activité du CPU pendant le test. Les valeurs importantes sont les cycles minimums. Des fois le CPU part en vadrouille et ça fait des pics très importants, tous les diagrammes seraient pénalisés et on n’y verrait plus rien. D'ailleurs, je mettrais bien les pics du à des Page Default en rouge. Je ne pense pas que l'on puisse observer ça sur des petites boucles de code, mais bon... je vais creuser la question.
Je vous ai fait un petit code avec une optimisation SSE2 pour que vous puissiez tester la librairie
Le code permet de calculer la moyenne de 1000 float.
Avec SSE2 il n'y a pas photo... je vous laisse découvrir les résultats

Le code permet de calculer la moyenne de 1000 float.
Avec SSE2 il n'y a pas photo... je vous laisse découvrir les résultats

Code : Tout sélectionner
;/ Moyenne d'un tableau de 1000 floats
;{/ Test SSE et SSE2
!MOV Eax, 1
!cpuid
!SHR Edx, 26; on place le bit 25 dans CF
!JC SSE_ok
Debug "Pas de SSE"
End
!SSE_ok:
Debug "SSE ok"
!MOV Eax, 1
!cpuid
!SHR Edx, 27; on place le bit 26 dans CF
!JC SSE2_ok
Debug "Pas de SSE2"
End
!SSE2_ok:
Debug "SSE2 ok"
;}/
*Test.ITest = New_Test()
*Tab.Float = ?tab
*Moyenne.Float = ?moyenne
*Total.Float = ?total
*Tab2.Float = *Tab
For t=0 To 999 ; Je remplis le tableau avec des nombres aléatoires
*Tab2\f = Random(100000)/100
*Tab2 + 4
Next
For t=0 To #ITest ; Premier test avec SSE2
*Test\Start(1)
;/
!LEA Esi, dword [tab]
!movaps xmm0, [Esi] ; Transfère 128 ( 4 * 32 ) bits alignés
!addps xmm0, [Esi+16]
!addps xmm0, [Esi+32]
!addps xmm0, [Esi+48]
!addps xmm0, [Esi+64]
!ADD Esi,80
For I=0 To 48
!addps xmm0, [Esi]
!addps xmm0, [Esi+16]
!addps xmm0, [Esi+32]
!addps xmm0, [Esi+48]
!addps xmm0, [Esi+64]
!ADD Esi,80
Next
!xorps xmm1, xmm1 ; xmm1= 0.0, 0.0, 0.0, 0.0
!SHUFPS xmm1, xmm0, 0x40 ; xmm1 = 2, 1, 0, 0
!addps xmm0, xmm1 ; xmm0 = 4+2, 3+1, 2, 1
!SHUFPS xmm1, xmm0, 0x30 ; xmm1 = 1, 4+2, 0, 0
!addps xmm0, xmm1 ; xmm0 = 4+2+1, 3+1+4+2, 2, 1
!SHUFPS xmm0, xmm0, 0x02 ; xmm0 = 1, 1, 1, 3+1+4+2
!movss [moyenne], xmm0
!movss [total], xmm0
!emms
!FLD dword [moyenne]
!fidiv word [num1000]
!FSTP dword [moyenne]
;/
*Test\Stop(1)
Next
*Test\SetTitle(1, "Test avec SSE2 : moyenne = "+StrF(*Moyenne\f,2))
For t=0 To #ITest ; Deuxième test avec une programmation classique
*Test\Start(2)
;/
*Total\f = 0
*Tab2 = *Tab
For I=0 To 999
*Total\f + *Tab2\f
*Tab2 + 4
Next
*Moyenne\f = *Total\f / 1000
;/
*Test\Stop(2)
Next
*Test\SetTitle(2, "Test normal : moyenne = "+StrF(*Moyenne\f,2))
*Test\Display()
End
!section '.data' align 16
tab:
!tab:
!RB 1000*4
!num1000:
!DW 1000
total:
!total:
!DD 0
moyenne:
!moyenne:
!DD 0
Code : Tout sélectionner
Pas de SSE

moi il me dit pas de SSE2.
j'ai commenté de la ligne 2 à 18 et çà passe.
résultat 15x plus rapide.
Un truc qui serait pratique dans ta lib : afficher ce rapport ( 15x ) .
il suffirait d'écrire *Test\Display(0) où 0 est l'identifiant du test et devient le référent. Ainsi on aura, pour 3 tests effectués, sur chaque graphique :
pour *Test\Display(1)
Graphique Test 0 : Rapport = x10.25 (Cycle0 / Cycle1)
Graphique Test 1 : Rapport = x01.00 (Référent)
Graphique Test 2 : Rapport = x02.33 (Cycle2 / Cycle1)

j'ai commenté de la ligne 2 à 18 et çà passe.
résultat 15x plus rapide.
Un truc qui serait pratique dans ta lib : afficher ce rapport ( 15x ) .
il suffirait d'écrire *Test\Display(0) où 0 est l'identifiant du test et devient le référent. Ainsi on aura, pour 3 tests effectués, sur chaque graphique :
pour *Test\Display(1)
Graphique Test 0 : Rapport = x10.25 (Cycle0 / Cycle1)
Graphique Test 1 : Rapport = x01.00 (Référent)
Graphique Test 2 : Rapport = x02.33 (Cycle2 / Cycle1)
