IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Assembleur : Instructions SIMD (de MMX à SSE) sur des entiers
Un mémo réalisé par Philippe Guesset

Le , par Alcatîz

33PARTAGES

7  0 
Les "Single Instructions Multiple Data" sur des entiers
Un mémo indispensable pour débuter avec les SIMD

Les SIMD, acronyme de « Single Instructions Multiple Data » appliquent simultanément une même opération à plusieurs données. Ces jeux d’instructions concernent des entiers (signés ou non) ou des flottants. De l’antique MMX aux différentes versions de SSE, les SIMD ont progressé en richesse fonctionnelle et en registres. Le mémo téléchargeable qu'accompagne cet article de découverte vous permettra de débuter sans devoir vous plonger dans la très volumineuse documentation d'Intel ou AMD.

Lire l'article de présentation

Télécharger le mémo

Voici un aperçu du mémo :


Et vous ?
Que pensez-vous de ce mémo ?
Pour quels types de traitements utilisez-vous ce genre de jeu d'instructions ?

Retrouvez les meilleurs cours et tutoriels Assembleur

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de
https://www.developpez.com
Le 07/09/2019 à 16:33
J'aime beaucoup cette approche synthétique des instructions SIMD car il y a vraiment de quoi se perdre dans les documents d'Intel et d'AMD.
J'avais, un temps, envisagé une approche informatique de ce travail, histoire de faciliter le développement. Une sorte d'aide en ligne... Mais, comme souvent en ce qui me concerne, ce n'est qu'un caillou de plus dans le cimetière de mes bonnes intentions (R.I.P.).
En tout cas, merci beaucoup, Philippe, pour cette excellente synthèse !
1  0 
Avatar de BeanzMaster
Expert confirmé https://www.developpez.com
Le 19/10/2019 à 19:45
Bonjour Philippe, ayant utilisé les SIMD qu'avec des valeurs flottante majoritairement. Suite à notre petite discussion sur le forum de Lazarus et ton exemples, Je viens de découvrir et lire cet article, qui est une très bonne introduction sur l'utilisation des opérations sur les entiers. Je vais faire plus de recherche et pouvoir faire évoluer ma bibliothèque.

Merci

A Bientôt

Jérôme
0  0 
Avatar de Guesset
Expert confirmé https://www.developpez.com
Le 26/10/2019 à 18:36
Bonjour,

Merci Jérôme.

J'ai vu ta bibliothèque vectorielle. C'est du travail. Je pense que la charge de tests doit avoir au moins égalé l'écriture même.

Si tu trouves des erreurs ou omissions dans le texte sur les SIMD entiers, n'hésite pas à les signaler. Cela me sera utile et en retour utile à tous.

Philippe
0  0 
Avatar de BeanzMaster
Expert confirmé https://www.developpez.com
Le 28/10/2019 à 17:41
Citation Envoyé par Guesset  Voir le message
Bonjour,

Merci Jérôme.

J'ai vu ta bibliothèque vectorielle. C'est du travail. Je pense que la charge de tests doit avoir au moins égalé l'écriture même.

Si tu trouves des erreurs ou omissions dans le texte sur les SIMD entiers, n'hésite pas à les signaler. Cela me sera utile et en retour utile à tous.

Philippe

Bonjour, Philippe, merci, oui ce fût fastidieux au début. Et les tests unitaires ont été primordiales pour tester les résultats.
Mais j'ai eu l'aide de Peter, un ancien ingénieur en informatiques qui est bien plus doué que moi en maths Malheureusement je n'ai plus de nouvelle depuis un moment (il profite de sa retraite pour voyager )
Cette bibliothèque est loin d'être finalisée surtout justement en ce qui concerne la manipulation des valeurs de type byte, et Integer surtout. Il reste encore pas mal de méthode qui ne sont pas en assembleur

Je n'ai pas trouvé d'erreurs dans ton articles et comme je te l'ai dis je suis plus à l'aise avec les virgules-flottantes dans ce domaine. Par un contre un point important qu'il faudrait étoffer c'est l'alignement des données (surtout en 64bits) car l'utilisation d'un movaps au lieu d'un movups si les données ne sont pas alignées renverra obligatoirement des résultats erronés. (cf plus bas)

Ensuite il faut noter que les conventions d'appel ne sont pas les même suivant l'OS (Windows vs Unix)

Avec la version 3.1.x et sup de FPC on a accès à un nouveau mot-clef (sous Windows uniquement pour respecter la convention d'appel de celui-ci) VectorCall. Ce qui permet de placer directement les paramètres d'une méthode dans les registres SIMD, ce qui évite donc l'appel a des movXXX pour initialiser les registres.

Ex :

Code delphi : Sélectionner tout
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
  
{$MODESWITCH ADVANCEDRECORDS}  
  
Type 
  TBZVector4fType = packed array[0..3] of Single;  //< Tableau aligné pour les vecteur 4D Single       
  TBZVector4f =  record   
  public      
     class operator +(constref A, B: TBZVector4f): TBZVector4f; {$ifdef USE_VECTORCALL} vectorcall; {$endif}overload;    
  
  case Byte of 
      0: (V: TBZVector4fType);                        //< Array access 
      1: (X, Y, Z, W: Single);                          //< Legacy access²  
      2: (Red, Green, Blue, Alpha: Single);      //< As Color components in RGBA order 
      3: (AsVector3f : TBZVector3f);               //< As TBZVector3f 
      4: (ST, UV : TBZVector2f);                     //< As Texture Coordinates 
      5: (Left, Top, Right, Bottom: Single);      //< As Legacy Rect 
      6: (TopLeft,BottomRight : TBZVector2f); //< As Bounding Rect 
  
  end; 
  
Implementation 
  
class operator TBZVector4f.+(constref A, B: TBZVector4f): TBZVector4f; assembler; nostackframe; register; {$ifdef USE_VECTORCALL} vectorcall; {$endif} 
asm 
  {$ifdef USE_VECTORCALL}  
     Addps xmm0, xmm1 
  {$else} 
  movaps xmm0, XMMWORD PTR [A] 
  addps  xmm0, XMMWORD PTR [B] 
  {$endif} 
  movaps [RESULT], xmm0 // Ici il faut que je vérifie mais il me semble que du coup ce n'est plus obligatoire aussi avec VECTORCALL. Le registre XMM0 est automatiquement retourné 
end;


Comme je le notifie plus haut, pour l'alignement des données (en 64 bits uniquement. En 32 bits les données sont par défaut non-alignées quoi qu'il arrive) pour utiliser les instructions SIMD, avec FPC il est recommandé de rajouter les directives suivantes en début d'unité :

Code delphi : Sélectionner tout
1
2
3
4
5
6
  
// Même pour un code compiler en 32bits ça ne mange pas de pain de rajouter ces quelques directives 
{$ALIGN 16} 
{$CODEALIGN CONSTMIN=16} 
{$CODEALIGN LOCALMIN=16} 
{$CODEALIGN VARMIN=16}

puis en fonction de ou on se trouve dans le code il faut faire ainsi (surtout si on se trouve dans une autre unité que celle qui contient nos méthodes):

Code delphi : Sélectionner tout
1
2
3
4
5
6
7
8
Const 
  {$IFDEF CPU64} 
    {$CODEALIGN CONSTMIN=16} 
     cOneMinusVector4f    : TBZVector4f = (x:-1;y:-1;z:-1;w:-1);    
    {$CODEALIGN CONSTMIN=4} 
  {$ELSE} 
    cOneMinusVector4f    : TBZVector4f = (x:-1;y:-1;z:-1;w:-1);    
  {$ENDIF}
Code delphi : Sélectionner tout
1
2
3
4
5
6
7
8
Var 
  {$IFDEF CPU64} 
    {$CODEALIGN VARMIN=16} 
     V1 : TBZVector4f; 
    {$CODEALIGN VARMIN=4} 
  {$ELSE} 
     V1 : TBZVector4f; 
  {$ENDIF}
Code delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
Type 
   AClass = Class 
  protected 
    {$IFDEF CPU64} 
      {$CODEALIGN RECORDMIN=16} 
      FVector : TBZVector4f; 
      {$CODEALIGN RECORDMIN=4} 
    {$ELSE} 
      FVector : TBZVector4f; 
  {$ENDIF} 
  end;


Voilà, sinon pour infos, j'ai effectué quelques changements dans ma bibliothèques mais non présents dans le dépôt que tu cite. Je me répète encore mais, dès que j'aurais un peu plus de temps pour harmoniser mon autre projet tout ce "beanz" sera en ligne

Merci

A bientôt

Jérôme
0  0 
Avatar de Guesset
Expert confirmé https://www.developpez.com
Le 31/10/2019 à 18:07
Bonjour Jérôme,

Citation Envoyé par BeanzMaster Voir le message

Avec la version 3.1.x et sup de FPC on a accès à un nouveau mot-clef (sous Windows uniquement pour respecter la convention d'appel de celui-ci) VectorCall. Ce qui permet de placer directement les paramètres d'une méthode dans les registres SIMD, ce qui évite donc l'appel a des movXXX pour initialiser les registres.
C'est très intéressant. Et si ça a en plus le bon goût de fonctionner avec des entiers (mais je ne vois pas pourquoi cela ne passerait pas car je présume que ce type d'appel se moque du contenu)...

Merci.

A bientôt
Philippe
0  0