【问题标题】:Is it possible to parallelize with OpenMP a list that can get added new elements every iteration?是否可以与 OpenMP 并行化一个可以在每次迭代中添加新元素的列表?
【发布时间】:2019-11-06 16:32:38
【问题描述】:

有什么方法可以使用 openMP 将循环与列表并行化,每次迭代可能会添加更多元素?据我了解,openMP 可以通过将每个线程的范围分成块来并行化 for 循环,但在这种情况下,范围会发生变化,在一种情况下,循环可能有 10 次迭代,而另一种情况下可能有 100 次迭代,事情是在列表我通常会有大约 10-20 个元素。

这是我想要并行化的示例(请注意,插入 vectorOfResults 的顺序无关紧要)

while(!list.empty()) {
 vectorOfResults.push_back(performExpensiveFunction());
 if (conditions) {
   add new elements to the list;
 }
}

我一直在考虑做类似的事情,在 while 循环中,有一个 for 循环,其中包含列表中当前“批次”元素(将它们复制到临时列表中),然后下一次 while 迭代将使用新添加的元素,但我在想是否有办法使用其他 openmp 结构来做到这一点。 (我现在才稍微了解一下openmp)。

感谢您的帮助。

【问题讨论】:

  • 请检查this answer是否对您有帮助。虽然这是一个更具体的上下文,但我相信它也适用于您的更一般的情况。

标签: c++ loops parallel-processing openmp


【解决方案1】:

我认为一旦启动并行 for 循环,它就不可能增加它的大小。

您可以一个接一个地运行多个并行 for 循环,直到按照this answer 中的建议处理完所有数据。比如:

Data proccessInParallel(Data d) {
    Data newData
    #pragma omp parellel for
    for (int i = 0; i < d.size i++) {
        // Do some processing
        if (create_new) {
            #pragma omp critical
            {
                newData.push_back(data)
            }
        }
    }
    return newData;
}

int main() {
   Data data;
   // Process data in batches until no new data is created
   do {
       data = proccessInParallel(data);
   } while (!data.empty());

缺点是在处理“批次”之间时某些线程可能未使用。


您也可以尝试使用tasks 来分析新的列表项,而无需等待开始另一个 for 循环。

可能是这样的:


#pragma omp parallel for
for (int i = 0; i < N; i++) {
    process(data[i]);
    if (new_data) {
        #pragma omp task
        {
        process(new_data);
        }
    }
}

一旦有线程可用,任务就会执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-12
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多