我尝试使用openMP V.2.0编写并行for循环。在并行区域的中间,我构造了一个Object,我希望每个线程构造一次。
#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 :(得分:2)
考虑未经测试的代码:
#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中完成所有这些操作,并且您不会引入不必要的静态变量。
答案 1 :(得分: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