OpenCV:并行for循环。我的代码出了什么问题?

时间:2014-09-19 04:01:03

标签: c++ opencv parallel-processing tbb

为了在OpenCV中测试并行for循环,我创建了以下代码,它只需要一个矩阵并进行一些操作并输出另一个矩阵。并行代码应该给出与串行代码给出的相同的结果。但事实并非如此。

在编译代码之前,确保您已经在OpenCV中正确启用并安装了TBB 。 (否则将不考虑并行化并将其视为序列代码,因此您显然会获得相同的结果。)

#include <opencv2/core/core.hpp>
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>    

using namespace cv;
using namespace std;    

class Parallel_process : public cv::ParallelLoopBody
{

private:
    const Mat& im;
    Mat& out;
    int r;

public:
    Parallel_process(const Mat& inputIm, int radius, Mat& outputIm)
        : im(inputIm), out(outputIm), r(radius){}

    virtual void operator()(const cv::Range& range) const
    {
        //cout << "start=" << range.start<< " end=" << range.end<<endl;
        //cout << endl;
        for(int y = range.start; y < range.end; y++)
        {
            //cout << " " << y;
            for(int x=0; x< im.cols - r; x++)
            {
                out(Rect(x,y,r,r)) = im(Rect(x,y,r,r))*im(Rect(x,y,r,r));
                //cout<<im(Rect(x,y,r,r))<<endl;
            } 
        }
    }
};


int main(int , char** )
{

    double start, timeSec;

    int n = 5, r = 2;

    /// Define a matrix
    Mat M = Mat(n, n, CV_32F);
    //randu(M, 0, 1);
    for(int y=0; y< M.rows; y++)
    {
        for(int x=0; x< M.cols; x++)
        {
            M.at<float>(x,y) = abs(x-y);    
        } 
    } 

    //cout<<M<<endl;

    Mat M1 = M.clone();
    Mat M2 = M.clone();    


    /// Serial loop
    start = (double)getTickCount();
    for(int y=0; y< M1.rows - r; y++)
    {
        for(int x=0; x< M1.cols - r; x++)
        {
            M1(Rect(x,y,r,r)) = M(Rect(x,y,r,r))*M(Rect(x,y,r,r));  
        } 
    } 
    timeSec = (getTickCount() - start) / getTickFrequency();
    cout << "Non parallel time: " << timeSec << "s" << endl;
    //cout<<M1<<endl;        


    /// Parallel loop
    start = (double)getTickCount();
    parallel_for_(Range(0,(int)M2.rows-r), Parallel_process(M,r,M2));
    timeSec = (getTickCount() - start) / getTickFrequency();
    cout << "Parallel time: " << timeSec << "s" << endl;    
    //cout<<M2<<endl;    

    /// Check the results
    cout << "Check: norm(M1-M2)=" << norm(M1-M2) << endl;
    return 0;
}

通过执行获得的二进制文件,我获得了非常随机的结果(即使使用相同的二进制文件,即编译一次但执行了几次)。

希望有人可以帮忙解决这个问题。提前谢谢。

enter image description here

1 个答案:

答案 0 :(得分:3)

我猜计算结果时out矩阵有重叠: out(Rect(x,y,r,r))重叠(Rect(x +,y + 1,r,r)),对于r> 1。 1.因此在顺序执行中,在顺序扫描图像之后的最后计算结果总是存储在输出矩阵中,而在并行计算中,图像的扫描不再是连续的,因此线程可能会覆盖其他线程结果