编译指示来自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);