【发布时间】:2017-10-23 02:43:07
【问题描述】:
我有这个用 OpenMp 编写的并行区域:
std::vector<T> sharedResult;
#pragma omp parallel
{
std::vector<T> result;
#pragma omp for nowait
for(int i=0; i<n; i++){
//fill result
}
#pragma omp critical{
sharedResult.insert(sharedResult.end(), result.begin(), result.end());
}
#pramga omp barrier
#pragma omp for nowait
for(size_t i=0; i<sharedResult.size(); i++){
foo(sharedResult[i]);
}
...
}
恐怕#pragma omp barrier 是必要的。我认为的原因是,否则当一个线程碰到最后一个#pragma omp for,sharedResult.size() 在那一刻仍然不是他的最终状态(在前一个并行完成时获得)。请注意,不幸的是,sharedResult 的大小以前是未知的。
不幸的是,我注意到这个障碍会产生很大的开销,即一个特定的迭代比所有其他迭代都更昂贵,因此所有线程都必须等待执行该迭代的线程。这可以认为是负载不平衡,但我没有找到任何解决方案。
所以我的问题是:有什么方法可以在不等待前一个完成的情况下启动最后一个并行,或者没有办法改进它?
【问题讨论】:
-
什么是典型的
sharedResult.size()和n? -
@Zulan 感谢您的评论。这是计算机视觉算法的一部分,两者都高度依赖于输入图像,但在这两种情况下我们都在谈论数千个元素。
-
祖蓝的第二种方案是我想到的。虽然我只是想给出一个想法,但它似乎比我想象的要复杂。现在让我们删除我们的 cmets,并请删除“可能的解决方案”部分,因为它不正确,也不是您问题的一部分 :)
-
@Shadow 我觉得你是对的,我删除了我以前的 cmets
标签: multithreading parallel-processing synchronization openmp barrier