我一直在看this tutorial,标签部分让我感到困惑。不是标记本身的行为,而是教程中显示过程的方式。
更具体地说,#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++;
}
以下代码以及以下代码。
有人能解释一下这里发生了什么吗?
答案 0 :(得分:3)
#pragma omp parallel for schedule(dynamic,3)
是一个结合了其他几个编译指示的简写。让我们看看他们:
#pragma omp parallel
启动一个带有一组线程的parellel块,这些线程将并行执行下一个步骤。
您还可以指定“并行循环”,例如for loop
:#pragma omp parallel for
。该pragma将拆分并行块内所有线程之间的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
。 Check this awesome answer in regards to scheduling policies
现在,所有这些pragma都可以缩短为一个:
#pragma omp parallel for schedule(dynamic,3)
将创建一个执行for循环的并行块,使用动态调度,块中的每个线程将在向调度程序提供更多块之前执行循环的3次迭代。
critical
pragma会将下一个块的执行限制为单个线程。在您的示例中,一次只有一个线程将执行此操作:
{
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);
}
Here您已对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);