gpt4 book ai didi

c++ - OpenMP 按需嵌套并行

转载 作者:搜寻专家 更新时间:2023-10-31 01:26:28 27 4
gpt4 key购买 nike

我有一个作业列表,我正在与 OpenMP 并行处理:

void processAllJobs()
{
#pragma omp parallel for
for(int i = 0; i < n; ++i)
processJob(i);
}

所有作业都有一些顺序部分和单独调用时可以并行化的部分:

void processJob(int i)
{
for(int iteration = 0; iteration < iterationCount; ++iteration)
{
doSomePreparation(i);
std::vector<Subtask> subtasks = getSubtasks(i);
#pragma omp parallel for
for(int j = 0; j < substasks.size(); ++j)
subtasks[j].Process();
doSomePostProcessing(i)
}
}

当我运行 processAllJobs() 时,会为外循环(针对每个作业)创建线程,而内循环(针对子任务)在线程内按顺序完成。这一切都很好并且是有意的。

有时会有非常大的作业需要花费大量时间来处理。足够长,这样外循环中的所有其他线程已经在最后一个线程之前完成,并且不做任何事情。有没有办法重新利用未使用的线程,以便在它们完成后立即并行化内部循环?我想象每次进入内部并行区域时检查未使用线程数的东西。

我无法预测作业运行多长时间。它可能不仅是一份持久的工作 - 也可能有两份或三份。

最佳答案

您对问题的描述听起来更像是 OpenMP 任务处理将是一个更好的选择。您的代码将如下所示:

void processAllJobs()
{
#pragma omp parallel master
for(int i = 0; i < n; ++i)
#pragma omp task
processJob(i);
}

那么作业的处理过程是这样的:

void processJob(int i)
{
for(int iteration = 0; iteration < iterationCount; ++iteration)
{
doSomePreparation(i);
std::vector<Subtask> subtasks = getSubtasks(i);
#pragma omp taskloop // add grainsize() clause, if Process() is very short
for(int j = 0; j < substasks.size(); ++j)
subtasks[j].Process();
doSomePostProcessing(i)
}
}

这样您就可以自然地实现负载平衡(假设您有足够多的任务),而不必依赖嵌套并行性。

关于c++ - OpenMP 按需嵌套并行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55366920/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com