J'ai un algorithme de traitement d'image simple. En bref, une image (moyenne) dans le flotteur est soustrait par une image 8 bits le résultat est alors enregistrer une image flottante (dest)Optimisation d'une boucle avec peu d'instructions (SSE2, SSE4) avec TBB
cette fonction est principalement écrit par intrinsics.
J'ai essayé d'optimiser cette fonction avec TBB, parrallel_for, mais je n'ai reçu aucun gain de vitesse mais de pénalité.
Que dois-je faire? Devrais-je utiliser un schéma de niveau inférieur tel que la tâche TBB pour optimiser le code?
float *m, **m_data,
*o, **o_data;
unsigned char *p, **src_data;
register unsigned long len, i;
unsigned long nr,
nc;
src_data = src->UByteData; // 2d array
m_data = mean->FloatData; // 2d array
o_data = dest->FloatData; // 2d array
nr = src->Rows;
nc = src->Cols;
__m128i xmm0;
for(i=0; i<nr; i++)
{
m = m_data[i];
o = o_data[i];
p = src_data[i];
len = nc;
do
{
_mm_prefetch((const char *)(p + 16), _MM_HINT_NTA);
_mm_prefetch((const char *)(m + 16), _MM_HINT_NTA);
xmm0 = _mm_load_si128((__m128i *) (p));
_mm_stream_ps(
o,
_mm_sub_ps(
_mm_cvtepi32_ps(_mm_cvtepu8_epi32(_mm_srli_si128(xmm0, 0))),
_mm_load_ps(m + offset)
)
);
_mm_stream_ps(
o + 4,
_mm_sub_ps(
_mm_cvtepi32_ps(_mm_cvtepu8_epi32(_mm_srli_si128(xmm0, 4))),
_mm_load_ps(m + offset + 4)
)
);
_mm_stream_ps(
o + 8,
_mm_sub_ps(
_mm_cvtepi32_ps(_mm_cvtepu8_epi32(_mm_srli_si128(xmm0, 8))),
_mm_load_ps(m + offset + 8)
)
);
_mm_stream_ps(
o + 12,
_mm_sub_ps(
_mm_cvtepi32_ps(_mm_cvtepu8_epi32(_mm_srli_si128(xmm0, 12))),
_mm_load_ps(m + offset + 12)
)
);
p += 16;
m += 16;
o += 16;
len -= 16;
}
while(len);
}
Je ne serais pas surpris si IPP avait déjà une fonction pour cela. –
Si vous utilisez le compilateur Intel, pourquoi ne pas simplement écrire une version naïve de la fonction et voir si le compilateur peut la vectoriser elle-même? Je ne connais pas le CCG à cet égard. –