Convertion de __m128i en bool (SSE)

Le
tmblues
Bonjour.

Je cherche à optimiser mon programme via l'utilisation des instructions SSE2 du microprocesseur intel.

Dans mon programme j'aimerais effectuer une boucle while avec pour condition la non nullité du vecteur row de type __m128i.
J'ai utilisé la syntaxe suivante :

__m128i zero = _mm_setzero_si128();
while(!_mm_cmpeq_epi8(zero, row))
{
.
}

mais le compilateur signal la double erreur suivante :
- l'expression à l'intérieur d'un while ne peut être de type __m128i.
- l'opérateur ! ne peut s'appliquer à un objet de type __m128i.

pour information, si row est un vecteur nul, _mm_cmpeq_epi8(zero, row) renvoie un vecteur de taille 128 bits où chaque bits est égale à 1.

Quelqu'un aurait-il une solution ?
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Serge Paccalin
Le #21660171
Le Fri, 30 Apr 2010 03:46:14 -0500, tmblues a écrit
(dans  dans fr.comp.lang.c++) :

Bonjour.

Je cherche à optimiser mon programme via l'utilisation des instructions SSE2 du
microprocesseur intel.

Dans mon programme j'aimerais effectuer une boucle while avec pour condition la
non nullité du vecteur row de type __m128i.
J'ai utilisé la syntaxe suivante :

__m128i zero = _mm_setzero_si128();
while(!_mm_cmpeq_epi8(zero, row))
{
...
}

mais le compilateur signal la double erreur suivante :
- l'expression à l'intérieur d'un while ne peut être de type __m128i.
- l'opérateur ! ne peut s'appliquer à un objet de type __m128i.

pour information, si row est un vecteur nul, _mm_cmpeq_epi8(zero, row) renvoie
un vecteur de taille 128 bits où chaque bits est égale à 1.

Quelqu'un aurait-il une solution ?



Apparemment, il faut rajouter un appel à _mm_movemask_epi8() pour passer
de 16 octets à 16 bits, et là, on pourra passer à un booléen.

__m128i zero = _mm_setzero_si128();
while (_mm_movemask_epi8(_mm_cmpeq_epi8(zero,row)) == 0)
{
...
}


--
___________
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763
Serge Paccalin
Le #21660161
Le Fri, 30 Apr 2010 03:46:14 -0500, tmblues a écrit
(dans  dans fr.comp.lang.c++) :

Bonjour.

Je cherche à optimiser mon programme via l'utilisation des instructions SSE2 du
microprocesseur intel.

Dans mon programme j'aimerais effectuer une boucle while avec pour condition la
non nullité du vecteur row de type __m128i.
J'ai utilisé la syntaxe suivante :

__m128i zero = _mm_setzero_si128();
while(!_mm_cmpeq_epi8(zero, row))
{
...
}

mais le compilateur signal la double erreur suivante :
- l'expression à l'intérieur d'un while ne peut être de type __m128i.
- l'opérateur ! ne peut s'appliquer à un objet de type __m128i.

pour information, si row est un vecteur nul, _mm_cmpeq_epi8(zero, row) renvoie
un vecteur de taille 128 bits où chaque bits est égale à 1.

Quelqu'un aurait-il une solution ?



[Supersedes pour corriger le test d'arrêt]

Apparemment, il faut rajouter un appel à _mm_movemask_epi8() pour passer
de 16 octets à 16 bits, et là, on pourra passer à un booléen.

__m128i zero = _mm_setzero_si128();
while (_mm_movemask_epi8(_mm_cmpeq_epi8(zero,row)) != 0xffff)
{
...
}


--
___________
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763
tmblues
Le #21667281
tmblues a écrit le 30/04/2010 à 10h46 :
Bonjour.

Je cherche à optimiser mon programme via l'utilisation des instructions
SSE2 du microprocesseur intel.

Dans mon programme j'aimerais effectuer une boucle while avec pour condition la
non nullité du vecteur row de type __m128i.
J'ai utilisé la syntaxe suivante :

__m128i zero = _mm_setzero_si128();
while(!_mm_cmpeq_epi8(zero, row))
{
....
}

mais le compilateur signal la double erreur suivante :
- l'expression à l'intérieur d'un while ne peut être de
type __m128i.
- l'opérateur ! ne peut s'appliquer à un objet de type __m128i.

pour information, si row est un vecteur nul, _mm_cmpeq_epi8(zero, row) renvoie
un vecteur de taille 128 bits où chaque bits est égale à
1.

Quelqu'un aurait-il une solution ?


Merci pour cette réponse si rapide, mais je pense qu'elle n'est pas tout à fait correcte. En fait, la fonction _mm_movemask_epi8(__m128i a) renvoie un int composé du premier bit de chaque byte. Par exemple si a = 1000 0000 0000 1010 1010 0100 1001 0110 .....
on aura _mm_movemask_epi8(a) = 1011 ..... ...... ......

Une solution est donc de faire un switch du bytes array a et à chaque fois d'appliquer la fonction _mm_movemask_epi8 afin de tester tout les bytes de l'array.

bool arrayEqualZero = true;

while(!arrayEqualZero)
{
for(int i = 0; i < 8, i++)
{
if(_mm_movemask_epi8(a) == 0)
{
arrayEqualZero = false;
break;
}
a = _mm_sli_epi32(a);
}
}

Par contre, on perd en optimisation.
Merci pour tout :)
Serge Paccalin
Le #21667371
Le Sat, 01 May 2010 13:11:55 -0500, tmblues a écrit
(dans  dans fr.comp.lang.c++) :

Merci pour cette réponse si rapide, mais je pense qu'elle n'est pas tout à fait
correcte. En fait, la fonction _mm_movemask_epi8(__m128i a) renvoie un int
composé du premier bit de chaque byte. Par exemple si a = 1000 0000 0000
1010 1010 0100 1001 0110 .....
on aura _mm_movemask_epi8(a) = 1011 ..... ...... ......



Oui, mais a ne contient que des 0x00 et des 0xff puisqu'il résulte d'une
comparaison par _mm_cmpeq_epi8().

--
___________
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763
tmblues
Le #21670331
Serge Paccalin a écrit le 01/05/2010 à 20h25 :
Le Sat, 01 May 2010 13:11:55 -0500, tmblues a écrit
(dans <news:, posté
dans fr.comp.lang.c++) :

Merci pour cette réponse si rapide, mais je pense qu'elle n'est pas
tout à fait
correcte. En fait, la fonction _mm_movemask_epi8(__m128i a) renvoie un int
composé du premier bit de chaque byte. Par exemple si a = 1000 0000
0000
1010 1010 0100 1001 0110 .....
on aura _mm_movemask_epi8(a) = 1011 ..... ...... ......




Oui, mais a ne contient que des 0x00 et des 0xff puisqu'il résulte d'une
comparaison par _mm_cmpeq_epi8().

--
___________
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763


Tu as tout à fait raison, merci beaucoup !
Publicité
Poster une réponse
Anonyme