У меня короткая беззнаковая матрица 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;
}
Вам необходимо распаковать ваш вектор из 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;
}
Других решений пока нет …