使用x86 / x64流式SIMD扩展进行块匹配优化

ased 发布于 2019-03-09 c 最后更新 2019-03-09 14:35 0 浏览

这将是我发布的第一个SO问题!

    std::cout << "Hello mighty StackOverflow!" << std::endl;
我正在尝试使用英特尔的SSE4.2和/或AVX内在函数为立体视觉应用优化“块匹配”实现。我使用“绝对差异总和”来找到最佳匹配块。在我的情况blockSize将是一个奇怪的数字,例如3或5.这是我的C代码片段:
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            minS = INT_MAX;
            for (int k = 0; k <= beta; ++k) {
                S = 0;
                for (int l = i; l < i + blockSize; ++l) {
                    for (int m = j; m <= j + blockSize ; ++m) {
                        // adiff(a,b) === abs(a-b)
                        S += adiff(rImage.at<uchar>(l, m), lImage.at<uchar>(l, m + k));
                    }
                }
                if (S < minS) {
                    minS = S;
                    kStar = k;
                }
            }
            disparity.at<uchar>(i, j) = kStar;
        }
    }
我知道流式SIMD扩展包含许多指令来促进使用SAD的块匹配,例如_mm_mpsadbw_epu8_mm_sad_epu8,但它们都将接缝定位为4,16或32的blockSizes。e.g. this code from Intel。我的问题是,在我的应用程序blockSize是一个奇数,大多数是3或5。 我已经考虑了以下的出发点:
            r0 = _mm_lddqu_si128 ((__m128i*)&rImage.at<uchar>(i, j));
            l0 = _mm_lddqu_si128 ((__m128i*)&lImage.at<uchar>(i, j));
            s0 = _mm_abs_epi8 (_mm_sub_epi8 (r0 , l0) );
但从这里,我不知道从s0总结3或5个连续字节的方法! 我将不胜感激任何想法。
已邀请:

dut

赞同来自:

我怀疑如果blockize小到3-5个字节x 3-5个字节,那么使用SSE或类似指令你会得到相当少的好处,因为你将花费太多的“收益”来快速做数学运算在“swizzling”(将数据从一个地方移动到另一个地方)。 但是,看看代码,看起来你多次处理相同的rImage[i, j],我觉得这没有意义。