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 ?
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 ?

Poser une question


(dans dans fr.comp.lang.c++) :
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
(dans dans fr.comp.lang.c++) :
[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
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 :)
(dans dans fr.comp.lang.c++) :
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 !