2016-11-14 132 views
0

我尝试使用openMP V.2.0编写并行for循环。在平行区域的中间,我构造了一个Object,我希望每个线程都构造一个Object。在OpenMP中每个线程执行一次代码而没有默认构造函数

#pragma omp parallel for 
    for (long i = 0; i < static_cast<long>(general_triangles.size()); ++i) 
    { 
     TrianglePointer tri = general_triangles[i]; 
     if (tri.GetClassification() == TO_CLASSIFY) 
     { 
      bool tri_has_correct_normal = true; 
      // --- Construct tree once per thread --- 
      Tree tree(*(gp_boolean_operator->mp_group_manager)); 
      if (tree.IsTriangleExternal(tri, tri_has_correct_normal)) 
      { 
       tri.SetClassification(IS_EXTERNAL); 
      } 
     } 
    } 

是否有每个线程构建一次树中的任意关键字?

您是否建议使用bood_thread_ptr?

+0

为什么你会把'i'变成'long'而不是仅仅使用'std :: size_t'? – erip

+1

@erip,因为openMP v.2.0不支持size_t –

+0

非常明智的响应。 :) TIL - 看起来很傻,但唉。 – erip

回答

0

这应该工作

gcc: static __thread 

MSVC: static __declspec(thread) 

但是,出于性能原因,可能会更好手动处理。使用大小与线程数相对应的矢量,并使用线程数来索引矢量。如果元素为NULL,则线程必须构造它。

还可以阅读:How to define thread-local local static variables?

像这样(请注意,是未经检验的,我从来没有使用OMP自己,因为它不提供控制的,我更喜欢有超过实际发生的程度)。

std::vector<Tree *> trees; 
trees.resize(omp_get_thread_limit()); 

#pragma omp parallel for 
    for (long i = 0; i < static_cast<long>(general_triangles.size()); ++i) 
    { 
     TrianglePointer tri = general_triangles[i]; 
     if (tri.GetClassification() == TO_CLASSIFY) 
     { 
      bool tri_has_correct_normal = true; 
      // --- Construct tree once per thread --- 
      Tree *& tree = trees[omp_get_thread_num()]; 
      if (tree == NULL) 
       tree = new Tree(*(gp_boolean_operator->mp_group_manager)); 
      if (tree->IsTriangleExternal(tri, tri_has_correct_normal)) 
      { 
       tri.SetClassification(IS_EXTERNAL); 
      } 
     } 
    } 

    // delete trees afterwards 
+0

无需跳出OpenMP。 –

+0

是(或可能)需要,因为“静态”关键字会导致编译器插入一个互斥,这将极大地降低处理速度。 –

+0

树&*树?你确定吗? –

1

考虑未测试的代码是这样的:

#pragma omp parallel 
{ 
// --- Construct one tree in each per thread --- 
    Tree tree(*(gp_boolean_operator->mp_group_manager)); 

#pragma omp for 
    for (long i = 0; i < static_cast<long>(general_triangles.size()); ++i) 
    { 
     TrianglePointer tri = general_triangles[i]; 
     if (tri.GetClassification() == TO_CLASSIFY) 
     { 
      bool tri_has_correct_normal = true; 

      if (tree.IsTriangleExternal(tri, tri_has_correct_normal)) 
      { 
       tri.SetClassification(IS_EXTERNAL); 
      } 
     } 
    } 
} 

这表明,你可以做所有这里面随身携带,独立于操作系统,OpenMP的,而且你不引入不必要的静态变量。

相关问题