【问题标题】:Using OpenMP to for optimizing BiLinear Interpolation使用 OpenMP 优化双线性插值
【发布时间】:2013-03-15 10:40:56
【问题描述】:

我正在使用 ARM,我正在尝试优化对图像的下采样,我使用了 OpenCV cv::resize 并且它对于 1280*960 到 400*300 的速度慢约 3ms,我正在尝试使用 OpenMP为了加快它的速度,但是在放置并行 for 语句时,图像已被扭曲。我知道这与线程之间的私有变量和共享数据有关,但我找不到问题。

void  resizeBilinearGray(uint8_t *pixels, uint8_t *temp, int w, int h, int w2, int h2) {

    int A, B, C, D, x, y, index, gray ;
    float x_ratio = ((float)(w-1))/w2 ;
    float y_ratio = ((float)(h-1))/h2 ;
    float x_diff, y_diff;
    int offset = 0 ;


#pragma omp parallel for
    for (int i=0;i<h2;i++) {
        for (int j=0;j<w2;j++) {
            x = (int)(x_ratio * j) ;
            y = (int)(y_ratio * i) ;
            x_diff = (x_ratio * j) - x ;
            y_diff = (y_ratio * i) - y ;
            index = y*w+x ;

            // range is 0 to 255 thus bitwise AND with 0xff
            A = pixels[index] & 0xff ;
            B = pixels[index+1] & 0xff ;
            C = pixels[index+w] & 0xff ;
            D = pixels[index+w+1] & 0xff ;

            // Y = A(1-w)(1-h) + B(w)(1-h) + C(h)(1-w) + Dwh
            gray = (int)(
                        A*(1-x_diff)*(1-y_diff) +  B*(x_diff)*(1-y_diff) +
                        C*(y_diff)*(1-x_diff)   +  D*(x_diff*y_diff)
                        ) ;

            temp[offset++] = gray ;
        }
    }

}

【问题讨论】:

    标签: c++ opencv parallel-processing openmp hpc


    【解决方案1】:

    为什么不尝试用 temp[i*w2 + j] 替换 temp[offset++]?

    您的偏移量存在多个问题。一方面,它有一个竞争条件。但更糟糕的是,OpenMP 为每个线程分配了非常不同的 i 和 j 值,因此它们正在读取内存的非相邻部分。这就是您的图像失真的原因。

    除了 OpenMP 之外,您还可以尝试其他几种方法来加速您的代码。我不了解 ARM,但在 Intel 上,您可以通过 SSE 大大加快速度。此外,您可以尝试固定浮点数。我在双线性插值中发现了两者的加速。 fastcpp.blogspot.no/2011/06/bilinear-pixel-interpolation-using-sse.html

    【讨论】:

    • 所以你认为 i, k 应该是私有变量?另一个嵌套循环呢?试过之后,我要试试 ARM Neon
    • i 和 j 已经是私有变量,因为它们是在 openmp pragma 之后定义的。你试过我的建议了吗?
    • 如果您想了解有关循环嵌套的更多信息,请参阅此链接。但这不会解决您的图像失真问题。那是由于您如何使用偏移量。您需要将 temp[offset++] 替换为 temp[i*w2 + j] bisqwit.iki.fi/story/howto/openmp/#ReductionClause
    • 我只是好奇,你为什么建议他使用 SSE over OpenMP,它涵盖了 Intel 和 Arm 平台上的矢量化? SSE + AVX 正是 OpenMP 用来完成工作的!
    【解决方案2】:

    我认为您的问题是 offset 变量。由于许多线程可以同时工作,所以你永远不知道哪个线程会先更新偏移量。这就是生成的图像失真的原因。

    更好的策略是迭代生成的图像像素。对于每个结果像素,您可以找到源图像像素的坐标,执行插值并写入结果。这样,您可以确定每个线程都在不同的像素上工作,并且在正确的像素上工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多