使用 OpenMP 进行并行 IplImage 转换

Posted

技术标签:

【中文标题】使用 OpenMP 进行并行 IplImage 转换【英文标题】:Parallel IplImage transformation using OpenMP 【发布时间】:2012-01-17 18:12:07 【问题描述】:

我想使用 OpenMP 对 IplImage 进行一些转换。这是一种简单的变换,可以将图像颠倒过来。使用 OpenMP 的代码与没有运行的代码相同。这并不重要。

void UpsideDownFilter::filter(IplImage* dstImage) 
uchar temp;
int j;
int i;
#pragma omp parallel shared(dstImage) private(j, i, temp)

    //        std::cout << omp_get_thread_num() << std::endl;
#pragma omp for schedule(static, 30) nowait
    for(j = 0; j < dstImage->height / 2; ++j) 

        for(i = 0; i < dstImage->widthStep; ++i) 
            temp = dstImage->imageData[i + j * dstImage->widthStep];

            dstImage->imageData[i + j * dstImage->widthStep] =
                dstImage->imageData[i + (dstImage->height - 1 - j) * 
                                    dstImage->widthStep];

            dstImage->imageData[i + (dstImage->height - 1 - j) * 
                                dstImage->widthStep] = temp;
        
    


我已经将#pragma omp for 推送到内部循环。当我不知道出了什么问题时,我已经完成了我通常会做的所有其他神奇的事情(删除这个,添加那个)。这就是我从代码中调用该方法的方式:

for (vector<filter_ptr>::iterator it = filters.begin();
     it != filters.end(); ++it) 

    (*it)->filter(dstImage);

谁能告诉我我做错了什么?

【问题讨论】:

您是否使用-openmp 进行编译?为什么要使用 nowait? 您可以拥有多个 CPU 内核,但您仍然只有一个内存总线。这是这里的限制,你只是在移动字节。 如果您不相信,请添加有关您正在运行的进程数量的检查,请参阅int omp_get_num_threads() @Tudor 是的,我正在传递 -fopenmp 标志。 @HansPassant 鲍伊也是这么说的 【参考方案1】:

由于我无法编译您的代码,我自己编写了我认为非常相似的代码。您已经展平了您的 2D 矩阵,我不会被打扰,但我认为这不会影响我认为您的问题所在。

#include <vector>

typedef std::vector<std::vector<double> > matrix_t;

void flip(matrix_t& A, int const m, int n)

    int m_2 = m / 2;
    #pragma omp parallel for
    for (int i = 0; i < m_2; ++i) 
        for (int j = 0; j < n; ++j) 
            std::swap(A[i][j], A[m - (i + 1)][j]);
        
    


int
main()

    int n = 20000;
    matrix_t A (n, std::vector<double>(n, 1.0));
    flip(A, n, n);
    return 0;

在四核机器上我也没有得到加速。

> g++ -O2 s18.cc && /usr/bin/time ./a.out && g++ -fopenmp -O2 s18.cc && /usr/bin/time ./a.out 
2.61user 2.18system 0:04.79elapsed 99%CPU (0avgtext+0avgdata 12805936maxresident)k
0inputs+0outputs (0major+800428minor)pagefaults 0swaps
7.67user 2.23system 0:04.71elapsed 210%CPU (0avgtext+0avgdata 12806512maxresident)k
0inputs+0outputs (0major+800481minor)pagefaults 0swaps

我认为没有加速的原因是程序受内存限制。也就是说,程序的速度由向内存发送数据和从内存发送数据的速度控制。因此,无论您拥有多少核心,您都无法更快,因为它们不是限制因素。

【讨论】:

以上是关于使用 OpenMP 进行并行 IplImage 转换的主要内容,如果未能解决你的问题,请参考以下文章

使用 OpenMP 进行并行加速

使用 OPENMP 进行并行归并排序

使用 openmp 并行化矩阵乘法并使用 avx2 进行矢量化

如何使用带有串行内循环的openMP并行化外循环以进行数组添加

使用openmp进行合并排序

OpenMP并行编程应用—加速OpenCV图像拼接算法