我有一个无符号短dst [16] [16]矩阵和一个更大的无符号char src [m] [n]矩阵。
现在我必须使用SSE2或SSE3在src矩阵中访问并向dst添加一个16x16子矩阵。
在较早的实现中,我确信我的求和值永远不会超过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;
}
答案 0 :(得分: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;
}