PureBasic
https://www.purebasic.fr/french/

Quelques idées pour aborder AVX2
https://www.purebasic.fr/french/viewtopic.php?f=12&t=16324
Page 1 sur 1

Auteur:  fweil [ Ven 14/Oct/2016 22:33 ]
Sujet du message:  Quelques idées pour aborder AVX2

Bonsoir à toutes et à tous.

AVX2 est un mode d'utilisation des processeurs x64 qui permet de faire du calcul numérique parallélisé. L'idée est de permettre d'injecter des données entrant dans des calculs en utilisant un jeu de registres élargi, à l'instar de ce que permet mmx, mais le mode AVX2 utilise une largeur de registres de 256 bits (registres ymm.). Ceci permet de faire passer autant de mots de différents formats que possibles, soit dans le cas d'une arithmétique 64 bits, 4 données en parallèle.

Travailler avec AVX2 nécessite de bien comprendre l'idée de parallélisme : on fait passer plusieurs données à la fois. Cela implique également de "négocier" de longues heures avec l'environnement interne d'un processeur x64 et de jongler avec tous les éléments utiles.

Pour envoyer des données au processeur, il faut les faire passer de la mémoire aux registres, et indiquer les instructions à effectuer, puis récupérer les résultats dans les registres pour les repasser en mémoire afin de les utiliser.

PureBasic ne dispose pas d'instructions spécifiques pour gérer AVX2, mais j'ai mis une petite méthode didactique en place pour y comprendre quelque chose et parvenir à faire réagir la bête à mon commandement. Je n'ai sans doute pas fait le tour du sujet, loin de là, c'est très poilu. Mais si cela peut susciter de l'intérêt tant mieux.

Il faut préciser qu'aucun langage de programmation ne dispose d'un vrai truc spécifique pour faire du parallélisme, quand on y regarde de près, le parallélisme en C ne vaut pas mieux, c'est imbitable malgré la disponibilité de bibliothèques idoines.

La présentation qui est montrée ici ne propose pas une large variété d'exemples, mais c'est un bout qui peut inspirer celles et ceux que ça intéressera pour aller plus loin. Dans une approche plus aboutie, on pourrait en déduire une bibliothèque assez riche, soit à base de macros, soit sous forme de procédures (ou les deux d'ailleurs).

Une petite mise en garde ... si t'aime pas l'assembleur, faut regarder ailleurs :)

Code:
Structure NOTHING
EndStructure

Define.NOTHING

Structure PACKED4D ; structure permettant de précharger / lire des Doubles
  d0.d             ; le format est 4 x 64 = 256 bits.
  d1.d             ; Ce format correspond à un registre ymm
  d2.d
  d3.d
EndStructure

Structure PACKED4Q ; structure permettant de précharger / lire des Quads
  q0.q             ; format 4 x 64 = 256 bits compatible registres ymm.
  q1.q
  q2.q
  q3.q
EndStructure

Structure PACKED4x64 ; Structure fusionnée pour adresser soit en Double soit en Quad (Integer)
  StructureUnion
    P4D.PACKED4D
    P4Q.PACKED4Q
  EndStructureUnion
EndStructure

Vector1.PACKED4x64
Vector2.PACKED4x64
Results.PACKED4x64

res.d

Debug "Somme horizontale d'un vecteur AVX2"

  Vector1\P4D\d0 = Random(10, 1)
  Vector1\P4D\d1 = Random(10, 1)
  Vector1\P4D\d2 = Random(10, 1)
  Vector1\P4D\d3 = Random(10, 1)
  !  lea        r9, qword [v_Vector1]
  !  vmovupd    ymm0, yword [r9]
  !  vhaddpd    ymm2, ymm0, ymm0 ; r0 = ymm0\0 + ymm0\1, r1 = ymm0\0 + ymm0\1, r2 = ymm0\2 + ymm0\3, r3 = ymm0\2 + ymm0\3
  !  lea        r9, qword [v_Results]
  !  vmovupd    yword [r9], ymm2
  !  lea        r9, qword [v_Results] ; r0 + r2 = ymm0\0 + ymm0\1 + ymm0\2 + ymm0\3
  !  fld        qword [r9]
  !  fadd       qword [r9+24]
  !  fstp       qword [v_res]
  Debug StrD(Vector1\P4D\d0, 1) + #TAB$ + StrD(Vector1\P4D\d1, 1) + #TAB$ + StrD(Vector1\P4D\d2, 1) + #TAB$ + StrD(Vector1\P4D\d3, 1) + #TAB$ + StrD(res, 1)
 
Debug "Comparaison de deux vecteurs AVX2"
 
  Vector1\P4D\d0 = Random(10, 1)
  Vector1\P4D\d1 = Random(10, 1)
  Vector1\P4D\d2 = Random(10, 1)
  Vector1\P4D\d3 = Random(10, 1)
  Vector2\P4D\d0 = Random(10, 1)
  Vector2\P4D\d1 = Random(10, 1)
  Vector2\P4D\d2 = Random(10, 1)
  Vector2\P4D\d3 = Random(10, 1)
  !  lea        r9, qword [v_Vector1]
  !  vmovupd    ymm0, yword [r9]
  !  lea        r9, qword [v_Vector2]
  !  vmovupd    ymm1, yword [r9]
  !  vcmpeqpd   ymm2, ymm1, ymm0 ; eq. vcmppd ymm2, ymm1, ymm0, $0
  !  vmovupd    yword [v_Results], ymm2
  Debug #TAB$ + StrD(Vector1\P4D\d0, 1) + #TAB$ + StrD(Vector1\P4D\d1, 1) + #TAB$ + StrD(Vector1\P4D\d2, 1) + #TAB$ + StrD(Vector1\P4D\d3, 1) + #CRLF$ +
        #TAB$ + StrD(Vector2\P4D\d0, 1) + #TAB$ + StrD(Vector2\P4D\d1, 1) + #TAB$ + StrD(Vector2\P4D\d2, 1) + #TAB$ + StrD(Vector2\P4D\d3, 1) + #CRLF$ +
        "eq" + #TAB$ + Str(Results\P4Q\q0) + #TAB$ + Str(Results\P4Q\q1) + #TAB$ + Str(Results\P4Q\q2) + #TAB$ + Str(Results\P4Q\q3)
  !  vcmpltpd   ymm2, ymm1, ymm0 ; eq. vcmppd ymm2, ymm1, ymm0, $0
  !  vmovupd    yword [v_Results], ymm2
  Debug "lt" + #TAB$ + Str(Results\P4Q\q0) + #TAB$ + Str(Results\P4Q\q1) + #TAB$ + Str(Results\P4Q\q2) + #TAB$ + Str(Results\P4Q\q3)
 
  Debug "Distance entre deux points placés dans un vecteur AVX2"
 
  Vector1\P4D\d0 = Random(10, 1) ; x1
  Vector1\P4D\d1 = Random(10, 1) ; x2     la distance est sqr((x1 - x2)² + (y1 - y2)²)
  Vector1\P4D\d2 = Random(10, 1) ; y1
  Vector1\P4D\d3 = Random(10, 1) ; y2
  !  lea        r9, qword [v_Vector1]
  !  vmovupd    ymm0, yword [r9]
  !  vhsubpd    ymm1, ymm0, ymm0 ; r0 = ymm0\0 - ymm0\1, r1 = ymm0\0 - ymm0\1, r2 = ymm0\2 - ymm0\3, r3 = ymm0\2 - ymm0\3
  !  vmulpd     ymm2, ymm1, ymm1
  !  lea        r9, qword [v_Results]
  !  vmovupd    yword [r9], ymm2
  !  lea        r9, qword [v_Results] ; r0 + r2 = (ymm0\0 - ymm0\1)² + (ymm0\2 - ymm0\3)²
  !  fld        qword [r9]
  !  fadd       qword [r9+24]
  !  fsqrt
  !  fstp       qword [v_res]
  Debug StrD(Vector1\P4D\d0, 1) + #TAB$ + StrD(Vector1\P4D\d1, 1) + #TAB$ + StrD(Vector1\P4D\d2, 1) + #TAB$ + StrD(Vector1\P4D\d3, 1) + #TAB$ + StrD(res, 1) + #TAB$ + StrD(res * res, 1)
  Debug StrD(Results\P4D\d0, 1) + #TAB$ + StrD(Results\P4D\d1, 1) + #TAB$ + StrD(Results\P4D\d2, 1) + #TAB$ + StrD(Results\P4D\d3, 1)

CallDebugger
End

Auteur:  Ar-S [ Sam 15/Oct/2016 0:43 ]
Sujet du message:  Re: Quelques idées pour aborder AVX2

Citation:
Une petite mise en garde ... si t'aime pas l'assembleur, faut regarder ailleurs :)

On va aller voir ailleurs ensemble alors, dans la sections ASM par exemple :wink:

Auteur:  Ollivier [ Sam 15/Oct/2016 8:20 ]
Sujet du message:  Re: Quelques idées pour aborder AVX2

@fweil

Ne pouvant récupérer ce source à l'instant, j'ai juste testé l'une des instructions au pif.
Code:
End
! vmovupd ymm0, [eax] ; oui "eax" :.je suis encore en 32 bits
Conclusion : Eh ben, ça marche ! Il y a quelque chose! Tu pousses au vice !

Auteur:  djes [ Sam 15/Oct/2016 9:17 ]
Sujet du message:  Re: Quelques idées pour aborder AVX2

C'est clair, il va nous pousser à faire des jeux dreamcast s'il continue :twisted:

Je plaisante, c'est passionnant, merci du partage :)

Auteur:  Ollivier [ Sam 15/Oct/2016 11:09 ]
Sujet du message:  Re: Quelques idées pour aborder AVX2

Quelqu'un avait évoqué les alignements mémoire pour que ce type d'instruction fonctionne correctement (instruction de transfert). Est-ce natif, ou bien faut-il le préciser en tête de "gondole"?

Auteur:  fweil [ Sam 15/Oct/2016 11:35 ]
Sujet du message:  Re: Quelques idées pour aborder AVX2

J'ai pas d'info fiable au sujet de l'alignement, mais les spécifications de codage indiquent (docs Intel) que certaines données doivent être alignées, et de quelle manière (bocs d'adresses alignés sur 8, 16, 32 octets).

Lorsque cela est imposé dans la programmation, on peut utiliser une instruction simple :

! align xx

où xx représente le nombre d'octets.

Les données en movupd, par exemple sont normalement non alignées (le u de movupd indique unaligned data). Si aux tests d'une séquence de code on constate que ça embrouille entre les données qu'on propose et celles qui sont dans les registres ou en mémoire après un mov, il y a potentiellement un problème d'alignement.

Si les déclarations de tableaux sont faites depuis PureBasic, ou les datas, je pense que le compilateur PB effectue les alignements nécessaires pour un bon partitionnement des données. Mais ça reste un point à vérifier.

Page 1 sur 1 Heures au format UTC + 1 heure
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/