排班系统 [英] Scheduling system for fitting

查看:214
本文介绍了排班系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to parallelise a linear operation (fitting a complicated mathematical function to some dataset) with multiple processors.

假设我的计算机中有8个核心,并且我想容纳1000个数据集.我期望的是某个将1000个数据集作为队列并将其发送到8个核心进行处理的系统,因此它首先将1000个数据集中的前8个作为FIFO.每个数据集的拟合时间通常彼此不同,因此要拟合的8个数据集中的某些数据集可能比其他数据集花费更长的时间.我要从系统中获得的是保存已拟合数据集的结果,然后针对完成的每个线程继续从大队列(1000个数据集)中获取新数据集.必须恢复到处理完整个1000个数据集为止.然后我可以继续我的程序.

Assume I have 8 cores in my machine, and I want to fit 1000 datasets. What I expect is some system that takes the 1000 datasets as a queue, and sends them to the 8 cores for processing, so it starts by taking the first 8 from the 1000 as FIFO. The fitting times of each dataset is in general different than the other, so some of the 8 datasets being fitted could take longer than the others. What I want from the system is to save the results of the fitted data sets, and then resume taking new datasets from the big queue (1000 datasets) for each thread that is done. This has to resume till the whole 1000 datasets is processed. And then I could move on with my program.

这种系统叫什么?在C ++上有针对该模型的模型吗?

What is such a system called? and are there models for that on C++?

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

I parallelise with OpenMP, and use advanced C++ techniques like templates and polymorphism.

谢谢您的努力.

推荐答案

您可以将OpenMP并行用于动态计划或OpenMP任务.两者都可以用于并行化每次迭代花费不同时间来完成的情况.具有动态预定时间:

You can either use OpenMP parallel for with dynamic schedule or OpenMP tasks. Both could be used to parallelise cases where each iteration takes different amount of time to complete. With dynamically scheduled for:

#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)使每个线程一次执行一个迭代,并且除非再没有其他迭代要处理,否则线程永远不会保持空闲状态.

schedule(dynamic,1) makes each thread execute one iteration at a time and threads are never left idle unless there are no more iterations to process.

有任务:

#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构造等待所有未完成的任务完成.它隐含在并行区域的末尾,因此只有在并行区域的末尾有更多代码之后,才真正有必要.

Here one of the threads runs a for-loop which produces 1000 OpenMP tasks. OMP tasks are kept in a queue and processed by idle threads. It works somewhat similar to dynamic for-loops but allows for greater freedom in the code constructs (e.g. with tasks you can parallelise recursive algorithms). The taskwait construct waits for all pending tasks to be done. It is implied at the end of the parallel region so it is really necessary only if more code follows before the end of the parallel region.

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

In both cases each invocation to fit() will be done in a different thread. You have to make sure that fitting one set of parameters does not affect fitting other sets, e.g. that fit() is a thread-safe method/function. Both cases also require that the time to execute fit() is much higher than the overhead of the OpenMP constructs.

OpenMP任务处理需要兼容OpenMP 3.0的编译器.如果您碰巧在Windows上进行开发,则这将排除所有版本的MS VC ++(甚至是VS2012中的版本).

OpenMP tasking requires OpenMP 3.0 compliant compiler. This rules out all versions of MS VC++ (even the one in VS2012), should you happen to develop on Windows.

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

If you'd like to have only one instance of fitter ever initialised per thread, then you should take somewhat different approach, e.g. make the fitter object global and 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.这些也可以在不同的并行区域之间保留(但仅在相同的功能中):

Here fitter is a global instance of the Fitter class. The omp threadprivate directive instructs the compiler to put it in the Thread-Local Storage, e.g. to make it per-thread global variable. These persists between the different parallel regions. You can also use omp threadprivate on static local variables. These too persist between the different parallel regions (but only in the same function):

#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环境变量指定的线程数相同的线程.

The omp_set_dynamic(0) call disables dynamic teams, i.e. each parallel region will always execute with as many threads as specified by the OMP_NUM_THREADS environment variable.

这篇关于排班系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆