【问题标题】:SIMD performance on rewriting OpenCV dilate重写 OpenCV 扩张的 SIMD 性能
【发布时间】:2015-05-18 03:19:39
【问题描述】:

我正在尝试重写 OpenCV dilate 函数来练习 SIMD 编程。为简单起见,仅考虑不可分离的情况。大部分代码看起来像 OpenCV 版本。然而,结果表明 OpenCV 的速度要快 10 倍以上。

** Input **
-- Image size: [5472 x 3648]
-- Dilate structuring element:
[1, 1, 1, 1, 1, 1, 1;
 1, 1, 1, 1, 1, 1, 1;
 1, 1, 1, 1, 1, 1, 1;
 1, 1, 1, 0, 1, 1, 1;
 1, 1, 1, 1, 1, 1, 1;
 1, 1, 1, 1, 1, 1, 1;
 1, 1, 1, 1, 1, 1, 1]

** Result **
OpenCV: 0.043147 sec
My Function: 0.49147 sec

代码:

Mat mydilate(const Mat& src, const Mat& de)
{
    int xb = de.cols / 2;
    int yb = de.rows / 2;
    Mat img_whole = Mat::zeros(src.rows + 2 * yb, src.cols + 2 * xb, CV_8U);
    src.copyTo(img_whole(Rect(xb, yb, src.cols, src.rows)));

    vector<Point> coords;
    vector<const uchar*> sptr;
    for (int i = 0; i < de.rows; i++) {
        for (int j = 0; j < de.cols; j++) {
            if (de.ptr(i)[j] == 1) {
                coords.push_back(Point(j, i));
            }
        }
    }

    Mat result(src.rows, src.cols, CV_8U);
    int width = result.cols;
    vector<uchar> pts;
    int nz = coords.size();
    pts.resize(nz);

    sptr.resize(nz);
    for (int y = 0; y < result.rows; y++) {

        uchar *pdst = result.ptr(y);
        for (int k = 0; k < nz; k++)
            sptr[k] = img_whole.ptr(y + coords[k].y) + coords[k].x;

        uchar **ssptr = (uchar **)&sptr[0];

        for (int x = 0; x < width - 16; x += 16) 
        {
            __m128i s0 = _mm_loadu_si128((const __m128i *)(ssptr[0] + x));
            for (int i = 1; i < nz; i++) 
            {
                __m128i x0 = _mm_loadu_si128((const __m128i *)(ssptr[i] + x));
                s0 = _mm_max_epu8(s0, x0);
            }
            _mm_storeu_si128((__m128i*)(pdst + x), s0);
        }

    }

    return result;
}

这个功能的瓶颈是什么?我还尝试将源指针对齐为 16 的倍数,但没有提高性能。

【问题讨论】:

  • 为什么不分析您的代码并查看热点在哪里?

标签: c++ opencv optimization simd sse2


【解决方案1】:

原来和编译器有关。添加编译器标志-O2 后,mydilate 的运行速度与 OpenCV 版本一样快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-01
    • 2018-12-15
    • 1970-01-01
    • 2020-07-22
    • 2018-11-13
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多