Как мне преобразовать _m128i в неподписанное int с SSE? - PullRequest
4 голосов
/ 22 декабря 2011

Я сделал функцию для постеризации изображений.

// =(
#define ARGB_COLOR(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))

inline UINT PosterizeColor(const UINT &color, const float &nColors)
{
    __m128 clr = _mm_cvtepi32_ps(  _mm_cvtepu8_epi32((__m128i&)color)  );

    clr = _mm_mul_ps(clr,  _mm_set_ps1(nColors / 255.0f)  );
    clr = _mm_round_ps(clr, _MM_FROUND_TO_NEAREST_INT);
    clr = _mm_mul_ps(clr, _mm_set_ps1(255.0f / nColors)  );

    __m128i iClr = _mm_cvttps_epi32(clr);

    return ARGB_COLOR(iClr.m128i_u8[12],
                      iClr.m128i_u8[8],
                      iClr.m128i_u8[4],
                      iClr.m128i_u8[0]);
}

в первой строке я распаковываю цвет в 4 поплавка, но не могу найти правильный способ сделать обратное.

Я искал документы SSE и не смог найти обратную сторону _mm_cvtepu8_epi32

существует ли один?

Ответы [ 2 ]

8 голосов
/ 29 декабря 2011

Комбинация _mm_shuffle_epi8 и _mm_cvtsi128_si32 - это то, что вам нужно:

static const __m128i shuffleMask = _mm_setr_epi8(0,  4,  8, 12, -1, -1, -1, -1,
                                               -1, -1, -1, -1, -1, -1, -1, -1);
UINT color = _mm_cvtsi128_si32(_mm_shuffle_epi8(iClr, shuffleMask));
5 голосов
/ 22 декабря 2011

К сожалению, нет инструкции сделать это даже в AVX (ни одной, о которой я знаю). Так что вам придется делать это вручную, как сейчас.

Однако ваш текущий метод очень неоптимален, и вы полагаетесь на .m128i_u8, который является расширением MSVC. Исходя из моего опыта работы с MSVC, он будет использовать выровненный буфер для доступа к отдельным элементам. Это имеет очень большое наказание из-за частичного доступа к словам.

Вместо .m128i_u8 используйте _mm_extract_epi32(). Это в SSE4.1. Но вы уже полагаетесь на SSE4.1 с _mm_cvtepu8_epi32().

Эта ситуация особенно плоха, поскольку вы работаете с 1-байтовой гранулярностью. Если вы вместо этого работали с гранулярностью 2 байта (16-битное целое), есть эффективное решение, использующее shuffle intrinsics .

...