gpt4 book ai didi

c++ - 装修排程系统

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:54:00 27 4
gpt4 key购买 nike

我想用多个处理器并行执行线性运算(将复杂的数学函数拟合到某些数据集)。

假设我的机器有 8 个内核,我想拟合 1000 个数据集。我期望的是某个系统将 1000 个数据集作为一个队列,并将它们发送到 8 个内核进行处理,因此它首先从 1000 个中取出前 8 个作为 FIFO。每个数据集的拟合时间通常不同于另一个数据集,因此 8 个数据集中的一些数据集可能比其他数据集花费更长的时间。我想从系统中得到的是保存拟合数据集的结果,然后为每个完成的线程继续从大队列(1000 个数据集)中获取新数据集。这必须恢复,直到处理完整个 1000 个数据集。然后我可以继续我的计划。

这样的系统叫什么?在 C++ 上有模型吗?

我与 OpenMP 并行化,并使用模板和多态性等高级 C++ 技术。

感谢您的努力。

最佳答案

您可以将 OpenMP 并行用于动态计划或 OpenMP 任务。两者都可用于并行处理每次迭代需要不同时间才能完成的情况。动态安排:

#pragma omp parallel
{
Fitter fitter;
fitter.init();
#pragma omp for schedule(dynamic,1)
for (int i = 0; i < numFits; i++)
fitter.fit(..., &results[i]);
}

schedule(dynamic,1) 使每个线程一次执行一个迭代,并且线程永远不会闲置,除非没有更多的迭代要处理。

有任务:

#pragma omp parallel
{
Fitter fitter;
fitter.init();
#pragma omp single
for (int i = 0; i < numFits; i++)
{
#pragma omp task
fitter.fit(..., &results[i]);
}
#pragma omp taskwait
// ^^^ only necessary if more code before the end of the parallel region
}

此处其中一个线程运行一个 for 循环,该循环生成 1000 个 OpenMP 任务。 OMP 任务保存在队列中并由空闲线程处理。它的工作方式有点类似于动态 for 循环,但允许在代码结构中有更大的自由度(例如,对于任务,您可以并行递归算法)。 taskwait 构造等待所有未完成的任务完成。它隐含在并行区域的末尾,因此只有在并行区域末尾之前有更多代码时才真正需要它。

在这两种情况下,对 fit() 的每次调用都将在不同的线程中完成。您必须确保拟合一组参数不会影响拟合其他参数集,例如fit() 是线程安全的方法/函数。这两种情况还要求执行 fit() 的时间远高于 OpenMP 构造的开销。

OpenMP 任务分配需要兼容 OpenMP 3.0 的编译器。这排除了所有版本的 MS VC++(甚至是 VS2012 中的那个),如果你碰巧在 Windows 上开发的话。

如果您希望每个线程只初始化一个 fitter 实例,那么您应该采取一些不同的方法,例如使 fitter 对象成为全局的并且 threadprivate:

#include <omp.h>

Fitter fitter;
#pragma omp threadprivate(fitter)

...

int main()
{
// Disable dynamic teams
omp_set_dynamic(0);

// Initialise all fitters once per thread
#pragma omp parallel
{
fitter.init();
}

...

#pragma omp parallel
{
#pragma omp for schedule(dynamic,1)
for (int i = 0; i < numFits; i++)
fitter.fit(..., &results[i]);
}

...

return 0;
}

这里的fitterFitter类的全局实例。 omp threadprivate 指令指示编译器将其放入线程本地存储中,例如使其成为每线程全局变量。这些在不同的平行区域之间持续存在。您还可以在 static 局部变量上使用 omp threadprivate。这些也在不同的并行区域之间存在(但仅在相同的功能中):

#include <omp.h>

int main()
{
// Disable dynamic teams
omp_set_dynamic(0);

static Fitter fitter; // must be static
#pragma omp threadprivate(fitter)

// Initialise all fitters once per thread
#pragma omp parallel
{
fitter.init();
}

...

#pragma omp parallel
{
#pragma omp for schedule(dynamic,1)
for (int i = 0; i < numFits; i++)
fitter.fit(..., &results[i]);
}

...

return 0;
}

omp_set_dynamic(0) 调用禁用动态团队,即每个并行区域将始终使用 OMP_NUM_THREADS 环境变量指定的线程数执行。

关于c++ - 装修排程系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12620183/

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