使用SSE或SSE3添加UCHAR阵列中的UCHAR值

Add uchar values in ushort array with SSE or SSE3

本文关键字:UCHAR 阵列 添加 SSE SSE3 使用      更新时间:2023-10-16

i有一个无符号的短dst [16] [16]矩阵和较大的无符号char src [m] [n]矩阵。

现在,我必须在SRC矩阵中访问,然后使用SSE2或SSE3添加16x16 subpatrix。

在较旧的实施中,我确定我的总价值从未大于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,因此我需要将它们存储为吸管。

我已经尝试了以下操作,但它不起作用。

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
}

我该如何解决这个问题?

编辑

谢谢保罗,但我认为您的偏移是错误的。我已经尝试了您的解决方案,并且似乎将subsatrix的行添加到错误的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;
}