Добавьте значения uchar в массив ushort с SSE или SSE3

У меня короткая беззнаковая матрица dst [16] [16] и более крупная беззнаковая матрица src [m] [n].

Теперь я должен получить доступ в матрице src и добавить подматрицу 16×16 в dst, используя SSE2 или же SSE3.

В более старой реализации я был уверен, что мои суммарные значения никогда не превышали 256, поэтому я мог сделать это:

for (int row = 0; row < 16; ++row)
{
__m128i subMat = _mm_lddqu_si128(reinterpret_cast<const __m128i*>(src));
dst[row] = _mm_add_epi8(dst[row], subMat);
src += W; // Step to the next row I need to add
}

где W — смещение для достижения желаемых строк. Этот код работает, но теперь мои значения в src больше и сумма может быть больше 256, поэтому мне нужно хранить их как ushort.

Я попробовал следующее, но это не работает.

for (int row = 0; row < 16; ++row)
{
__m128i subMat = _mm_lddqu_si128(reinterpret_cast<const __m128i*>(src));
dst[row] = _mm_add_epi16(dst[row], subMat);
src += W; // Step to the next row I need to add
}

Как я могу решить эту проблему?

РЕДАКТИРОВАТЬ

Спасибо, Пол, но я думаю, что ваши смещения неверны. Я попробовал ваше решение, и кажется, что строки подматрицы добавляются к ошибочным строкам dst. Я надеюсь, что правильное решение заключается в следующем:

for (int row = 0; row < 32; row += 2)
{
__m128i subMat = _mm_lddqu_si128(reinterpret_cast<const __m128i*>(src));
__m128i subMatLo = _mm_unpacklo_epi8(subMat, _mm_set1_epi8(0));
__m128i subMatHi = _mm_unpackhi_epi8(subMat, _mm_set1_epi8(0));
dst[row] = _mm_add_epi16(dst[row], subMatLo);
dst[row + 1] = _mm_add_epi16(dst[row + 1], subMatHi);
src += W;
}

3

Решение

Вам необходимо распаковать ваш вектор из 16 x 8 битных значений в два вектора 8 x 16 битных значений, а затем добавить оба этих вектора к месту назначения:

for (int row = 0; row < 16; ++row)
{
__m128i subMat = _mm_lddqu_si128(reinterpret_cast<const __m128i*>(src));
__m128i subMatLo = _mm_unpacklo_epi8(subMat, _mm_set1_epi8(0));
__m128i subMatHi = _mm_unpackhi_epi8(subMat, _mm_set1_epi8(0));
dst[row] = _mm_add_epi16(dst[row], subMatLo);
dst[row + 1] = _mm_add_epi16(dst[row + 1], subMatHi);
src += W;
}
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]