c++ - सीपी:: मेट या सीवी:: वैट के वेक्टर पर ओएमपी कमी सामान्य में



opencv parallel-processing (1)

//In other words, this equilavent to cv::Mat1f mat(5,n)
//i.e. a matrix 5xn
std::vector<cv::Mat1f> mat(5,cv::Mat1f::zeros(1,n));
std::vector<float> indexes(m);
// fill indexes
// m >> nThreads (from hundreds to thousands)
for(size_t i=0; i<m; i++){
  mat[indexes[m]] += 1;
}

अपेक्षित परिणाम प्रत्येक पंक्ति के प्रत्येक तत्व को एक करके बढ़ाया जाता है। यह एक खिलौना उदाहरण है, वास्तविक राशि कहीं ज्यादा जटिल है। मैंने इसके साथ समानांतर करने की कोशिश की:

#pragma omp declare reduction(vec_float_plus : std::vector<cv::Mat1f> : \
            std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<cv::Mat1f>())) \
            initializer(omp_priv=omp_orig);

#pragma omp parallel for reduction(vec_float_plus : mat)
for(size_t i=0; i<m; i++){
    mat[indexes[m]] += 1;
}       

लेकिन यह विफल हो जाता है क्योंकि प्रत्येक पंक्ति का प्रत्येक तत्व बेतरतीब ढंग से इनजिलाइज किया जाता है। इसे कैसे हल किया जा सकता है?

तो मुझे पता चला कि समस्या इस से संबंधित है। इसलिए मुझे mat साथ mat शुरू करनी चाहिए:

std::vector<cv::Mat1f> mat(5);
for(size_t i=0; i<mat.size(); i++)
  mat[i] = cv::Mat1f::zeros(1,n);

लेकिन तब यह omp_priv = omp_orig साथ समस्या पैदा करेगा, क्योंकि यह std::vector<cv::Mat1f> mat(5); विचार करेगा std::vector<cv::Mat1f> mat(5); और इसका मान अनिर्धारित है। इसे कैसे हल किया जा सकता है? मेरे दिमाग में एकमात्र उपाय आया है जो एक आवरण संरचना बनाना है, जैसे कुछ:

class vectMat{
public:
    vectMat(size_t rows, size_t j){
        for(size_t i=0; i<rows; i++)
            mats.push_back(cv::Mat1f::zeros(1,j));
    }
private:
    std::vector<cv::Mat1f> mats;
};

लेकिन फिर मुझे इसे बाकी कोड के साथ काम करने के लिए क्या लागू करना चाहिए?


cv::Mat1f जैसे प्रकार, जो कॉपी करने के बजाय संदर्भ का उपयोग करते हैं, वास्तव में इस संदर्भ में खतरनाक होते हैं। आप parallel क्षेत्र को विभाजित करके और लूप के for स्पष्ट स्पष्ट समाधान बनाते हैं।

#pragma omp declare reduction(vec_mat1f_plus : std::vector<cv::Mat1f> : \
            std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<cv::Mat1f>()));
// initializer not necessary if you initialize explicitly

std::vector<cv::Mat1f> mat;
#pragma omp parallel reduction(vec_mat1f_plus : mat)
{
  mat = std::vector<cv::Mat1f>(5);
  for (auto& elem : mat) {
    elem = cv:Mat1f::zeros(1, n);
  }
  #pragma omp for
  for(size_t i=0; i<m; i++){
    mat[indexes[m]] += 1;
  }
}

मैंने यह नहीं परीक्षण किया है कि क्या std::plus<cv::Mat1f> काम करता है, लेकिन यह अच्छा लगता है

vectMat साथ आपका दृष्टिकोण भी काम करेगा यदि आप operator= प्रदान करते हैं - clone() साथ अंतर्निहित Mat गहरी-प्रतियां और प्रारंभकर्ता को रखें।





reduction