1

我一直在看这个教程,标签部分让我很困惑。不是标记本身的行为,而是教程中显示过程的方式。

更具体地说,这些#pragma omp部分:

#pragma omp parallel for schedule(dynamic,3)
for(..loop a directory?..) {

   ...

   #pragma omp critical
   {
      if(classes_training_data.count(class_) == 0) { //not yet created...
         classes_training_data[class_].create(0,response_hist.cols,response_hist.type());
         classes_names.push_back(class_);
      }
      classes_training_data[class_].push_back(response_hist);
   }
   total_samples++;
}

以及它下面的以下代码。

谁能解释这里发生了什么?

4

1 回答 1

3

编译指示来自OpenMP一组编译器指令、库例程和环境变量的规范,可用于指定 Fortran 和 C/C++ 程序中的高级并行性。

The#pragma omp parallel for schedule(dynamic,3)是结合了其他几个 pragma 的简写。让我们看看它们:

#pragma omp parallel使用一组线程启动一个并行块,这些线程将并行执行下一个语句。

您还可以指定“并行循环”,例如for loop: #pragma omp parallel for。此编译指示将在并行块内的所有线程之间拆分 for 循环,并且每个线程将执行其循环部分。

例如:

 #pragma omp parallel
 {
  #pragma omp for
  for(int n(0); n < 5; ++n) {
     std::cout << "Hello\n";
 }

这将创建一个执行 for 循环的并行块。线程将打印到标准输出Hello五次,没有指定的顺序(我的意思是,线程#3 可以在线程#1 之前打印它的“Hello”,依此类推)。

现在,您还可以安排每个线程将接收哪些工作块。有几种策略:(static默认)和dynamic. 检查这个关于调度策略的真棒答案

现在,所有这些 pragma 都可以缩短为一个:

#pragma omp parallel for schedule(dynamic,3)

这将创建一个并行块,该块将执行一个具有动态调度的for循环,并且块中的每个线程将在向调度程序询问更多块之前执行循环的3次迭代。

pragma将critical一次将下一个块的执行限制为单个线程。在您的示例中,一次只有一个线程会执行此操作:

   {
      if(classes_training_data.count(class_) == 0) { //not yet created...
         classes_training_data[class_].create(0,response_hist.cols,response_hist.type());
         classes_names.push_back(class_);
      }
      classes_training_data[class_].push_back(response_hist);
   }

在这里你有一个介绍OpenMP 3.0

最后,您提到的变量在教程中指定,只需查看您发布的代码之前:

vector<KeyPoint> keypoints;
Mat response_hist;
Mat img;
string filepath;
map<string,Mat> classes_training_data;

Ptr<FeatureDetector > detector(new SurfFeatureDetector());
Ptr<DescriptorMatcher > matcher(new BruteForceMatcher<L2<float> >());
Ptr<DescriptorExtractor > extractor(new OpponentColorDescriptorExtractor(Ptr<DescriptorExtractor>(new SurfDescriptorExtractor())));
Ptr<BOWImgDescriptorExtractor> bowide(new BOWImgDescriptorExtractor(extractor,matcher));
bowide->setVocabulary(vocabulary);
于 2015-02-16T11:42:37.647 回答