C++ OpenMP STL集容器迭代器

C++ OpenMP STL集容器迭代器,c++,multithreading,stl,openmp,C++,Multithreading,Stl,Openmp,我有一个和这里的问题相似的问题-。我希望将涉及std::set迭代器的for循环并行化。因此,我试图研究@Hristo lliev提供的答案。有些事我不太确定 如果一个线程没有选择一个任务,那么它的“最坏的q”应该是它进入临界区时的原始数字。但是,如果一个线程拾取一个任务,并且“t_最差_q”将在任务内部更改,那么当该线程进入关键部分时,“t_最差_q”将与任务构造中的相同,对吗?然而,我用了一个例子,它不是这样出现的,也许我仍然缺少一些东西 是的,你解释它的方式是“赫里斯托·伊利耶夫”希望它如

我有一个和这里的问题相似的问题-。我希望将涉及std::set迭代器的for循环并行化。因此,我试图研究@Hristo lliev提供的答案。有些事我不太确定


如果一个线程没有选择一个任务,那么它的“最坏的q”应该是它进入临界区时的原始数字。但是,如果一个线程拾取一个任务,并且“t_最差_q”将在任务内部更改,那么当该线程进入关键部分时,“t_最差_q”将与任务构造中的相同,对吗?然而,我用了一个例子,它不是这样出现的,也许我仍然缺少一些东西

是的,你解释它的方式是“赫里斯托·伊利耶夫”希望它如何运作。不幸的是,他在任务方面有几点错误:

他使用
taskwait
的所谓“屏障”只适用于创建任务的线程。所有其他线程都通过它运行。因此,最终他的整个缩减是无用的,因为大多数线程在实际执行任何工作之前执行它。“taskwait”旨在帮助解释数据依赖关系(非常有用!),这就是它的工作方式

程序有时工作的唯一原因,即使最后没有函数缩减,是他的第一个错误被第二个错误部分抵消了:任务中的变量
t\u best\u q
引用了生成任务的线程中的变量,因此充当全局变量。但是,当然,我们在
std::min
中有一个争用条件,这仍然会让代码有时失败

因此,他的代码实际上相当于以下代码:

#pragma omp parallel
{
   // Create tasks
   #pragma omp single nowait
   {
      for(std::set<size_t>::const_iterator it=mesh->NEList[vid].begin();
          it!=mesh->NEList[vid].end(); ++it) {
         size_t elem = *it;
         #pragma omp task shared(worst_q)
         worst_q = std::min(worst_q, mesh->element_quality(elem));
      }
   }
}
#pragma omp并行
{
//创建任务
#pragma-omp-single-nowait
{
对于(std::set::const_迭代器it=mesh->NEList[vid].begin();
it!=mesh->NEList[vid].end();++it){
大小元素=*它;
#pragma omp任务共享(最差)
最差_q=std::min(最差_q,网格->元素质量(elem));
}
}
}

如前所述,在执行
std::min
时,在访问
best_q
时存在争用条件问题。如果与
std::min
函数相比,函数
mesh->element_quality
在计算上比较昂贵,那么一个简单的解决方案是围绕
std::min
部分的关键部分(在关键部分之外执行
mesh->element_quality
之后)。另一方面,如果
mesh->element\u quality
的成本不高于
std::min
,那么关键部分将破坏并行性。但是在这种情况下,函数
mesh->element\u-quality
非常便宜,以至于管理任务的开销会消耗掉所有潜在的加速。

这个答案是非常错误的。我刚把它修好。