我正在尝试在大型有符号短图像(1000X1000)上实现定点 7X7 卷积。(float) 内核按比例放大(1<<14)以获得有效结果,最终结果按比例缩小。
我正在使用 SSE 实现它。
处理整数向量的主要问题是任何乘法函数都会给出部分结果(下/上)或立即缩小结果 mulhrs。
为了克服这个问题,我被迫将 16 位结果转换为 32 位:
kernelVec = _mm_set1_epi16(kernel); \
inputVec = _mm_srli_epi16(_mm_lddqu_si128(vInput),(shift)); \
mulLowVec = _mm_mullo_epi16(inputVec, kernelVec); \
mulHighVec = _mm_mulhi_epi16(inputVec, kernelVec);\
sumLeft = _mm_add_epi32(sumLeft, _mm_unpacklo_epi16(mulLowVec, mulHighVec));\
sumRight = _mm_add_epi32(sumRight, _mm_unpackhi_epi16(mulLowVec, mulHighVec)); \
所有这一切都是为了将 8 个元素乘以单个内核值。
因此 - 我尝试将输入数据转换为浮点数并使用 avx 函数实现它(256 没有对齐,所以我必须不断重新加载......):
kernelVec = _mm256_set1_ps(kernel); \
inputVec = _mm256_loadu_ps(fInput); \
sum = _mm256_fmadd_ps(inputVec,kernelVec,sum);\
然后将结果转换回 16 位短路。浮点数的实现被证明比整数快 2.3。
我知道 ipp 库有 ippsConv_16s_Sfs 应该做同样的事情。有人有什么建议吗?