【问题标题】:OpenMP STL set container iteratorOpenMP STL 设置容器迭代器
【发布时间】:2015-04-07 04:11:04
【问题描述】:

我有一个与这里提出的问题类似的问题 -OpenMP parallel thread。我希望并行化 for 循环涉及 std::set 迭代器。所以我正在尝试研究@Hristo lliev 提供的答案。我不太确定。

如果一个线程没有选择一个任务,那么它的“worst_q”应该是它进入临界区时的原始数字。但是如果一个线程拿起一个任务,并且“t_worst_q”将在任务内部发生变化,那么当这个线程进入临界区时,这个“t_worst_q”将保持与它在任务构造中的相同,我正确吗?但是,我用了一个例子,它看起来不像这样,也许我仍然遗漏了一些东西。

【问题讨论】:

  • 那个答案大错特错。我刚刚修好了。

标签: c++ multithreading stl openmp


【解决方案1】:

是的,您解释它的方式是“Hristo Iliev”希望它如何工作。不幸的是,他在任务方面搞错了几件事:

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

程序有时工作的唯一原因,即使最后没有减少功能,是他的第一个错误被第二个错误部分抵消:任务中的变量t_worst_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));
      }
   }
}

如前所述,这在执行std::min 时存在访问worst_q 的竞争条件的问题。如果函数mesh-&gt;element_qualitystd::min 函数相比计算量大,那么一个简单的解决方案是在std::min 部分周围设置一个临界区(在临界区外执行mesh-&gt;element_quality 之后)。另一方面,如果mesh-&gt;element_quality 不比std::min 贵,那么临界区将扼杀并行性。但在这种情况下,mesh-&gt;element_quality 函数非常便宜,以至于管理任务的开销无论如何都会消耗掉所有潜在的加速。

【讨论】:

    猜你喜欢
    • 2012-03-16
    • 2013-04-16
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 2011-01-15
    相关资源
    最近更新 更多