Bonjour
Je ne suis pas vraiment un pro des langages d'assemblage, mais récemment j'ai tenté d'optimiser un bout de code C++ critique se prétant visiblement bien à une certaine parallelisation.
Il s'agit de traiter des entiers dans une boucle 3 par 3, j'ai donc pensé que MMX me permettrait d'avoir une instruction pour 3 opérations.
Le code fonctionne très bien, cependant il est plus lent que l'original. Avez-vous une idée de ce qui peut clocher ?
Voici le code (j'utilise des fonctions intrinsèques pour le MMX, si vous voulez les instructions ASM équivalentes je peux les donner), le code original associé à chaque instruction MMX est donné en commentaire à côté. Etant donné que je ne traite que 3 entiers à la fois, le 4ème élément est simplement une copie du troisième pour garder des calculs cohérents.
Aussi, si vous voyez des erreurs ou des choses à optimiser, n'hésitez pas, je ne connais le MMX que depuis 2 jours
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 _mm_empty(); __m64 CYmm = _mm_set_pi16(CY[0], CY[1], CY[2], CY[3]); __m64 DXmm = _mm_set_pi16(DX[0], DX[1], DX[2], DX[3]); __m64 DYmm = _mm_set_pi16(DY[0], DY[1], DY[2], DY[3]); __m64 Zeromm = _mm_setzero_si64(); for (int y = MinY; y <= MaxY; ++y) { __m64 CXmm = CYmm; //int CX1 = CY1; //int CX2 = CY2; //int CX3 = CY3; for (int x = MinX; x <= MaxX; ++x) { //if ((CX1 >= 0) && (CX2 >= 0) && (CX3 >= 0)) if (_mm_movemask_pi8(_mm_cmpgt_pi16(Zeromm, CXmm)) == 0) { if (ZValue < ColorBuffer[x]) ColorBuffer[x] = ZValue; } CXmm = _mm_subs_pi16(CXmm, DYmm); //CX1 -= DY12; //CX2 -= DY23; //CX3 -= DY31; } CYmm = _mm_adds_pi16(CYmm, DXmm); //CY1 += DX12; //CY2 += DX23; //CY3 += DX31; ColorBuffer += m_Size; } _mm_empty();
Pour info, le code original en C++ est mesuré à 60 ms, le code MMX à 100 ms. La procédure de test n'est je pense pas en cause : le temps d'exécution est renvoyé par un profiler, la fonction tournant en temps réel dans un moteur 3D.
Si cela peut vous aider, je peux aussi donner le code assembleur généré par le compilo.
Merci d'avance à tous.
Partager