简体   繁体   English

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

[英]OpenCV: parallel for loop. What's wrong with my code?

For the purpose of testing the parallel for loop in OpenCV, I created the following code, which just takes a matrix and does some manipulations and outputs another matrix. 为了在OpenCV中测试并行for循环,我创建了以下代码,它只需要一个矩阵并进行一些操作并输出另一个矩阵。 The parallel code is supposed to give the same results as given by the serial code. 并行代码应该给出与串行代码给出的相同的结果。 However, it is not the case. 但事实并非如此。

Before compiling the code, make sure that you have already had TBB properly enabled and installed in OpenCV . 在编译代码之前,请确保已经在OpenCV中正确启用并安装了TBB (Otherwise the parallelization will not be taken into account and will be treated as serial code, thus you'll obviously obtain the same results.) (否则将不考虑并行化并将其视为序列代码,因此您显然会获得相同的结果。)

#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;
}

By executing the obtained binary, I got very random results (even with the same binary, ie compiled once but executed several times). 通过执行获得的二进制文件,我得到了非常随机的结果(即使使用相同的二进制文件,即编译一次但执行了几次)。

Hope somebody can help to figure it out. 希望有人可以帮助解决这个问题。 Thanks in advance. 提前致谢。

在此输入图像描述

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM