组织基于任务的科学计算

时间:2011-07-20 12:28:00

标签: c++ design-patterns architecture combinatorics

我有一个需要编码的计算代数任务。问题被分解为明确定义的个人任务,这些任务自然形成一棵树 - 任务本质上是组合的,因此有一项主要任务需要少量的子计算才能得到结果。这些子计算具有子子计算等。每个计算仅取决于树中它下面的计算(假设根节点是顶部)。分支机构之间不需要进行数据共享。在较低级别,子任务的数量可能非常大。

我之前已经以功能方式对其进行编码,根据需要调用函数并将所有内容存储在RAM中。这是一种可怕的方法,但我当时更关注这个理论。

我打算用各种原因用C ++重写代码。我有一些要求:

  • 检查点:计算需要很长时间,因此我需要能够在任何时候停止并稍后恢复。
  • 将各个任务分隔为对象:这有助于我很好地处理计算中的位置,并提供一种通过序列化进行检查点的简洁方法。
  • 多线程:这项任务显然是令人尴尬的并行,因此利用它是很好的。我可能想为此使用Boost线程。

我想了解如何实际实施这样一个系统。我想过这样做的方式:

  1. 将任务实现为一个简单的堆栈。当您点击需要完成子计算的任务时,它会检查它是否具有所需的所有子计算。如果没有,它会创建子任务并将它们抛到堆栈上。如果是,则计算其结果并从堆栈中弹出。
  2. 将任务存储为树,并执行类似深度优先访问者模式的操作。这将在开始时创建所有任务,然后计算将只遍历树。
  3. 这些似乎不太正确,因为较低级别的问题需要大量的子任务。我想,我可以在这个级别以迭代器方式处理它。

    我觉得我过度思考它并且已经有一种简单,完善的方式来做这样的事情。有吗?


    重要的技术细节:

    • 任务树有5个级别。
    • 树的分支因子对于所有级别来说都很小(例如,在2到5之间),除了最低的几百万之外。
    • 每个单独的任务只需要存储大数十字节的结果。我不介意尽可能多地使用磁盘,只要它不会影响性能。
    • 为了调试,我必须能够重新计算/重新计算任何单个任务。
    • 所有计算都是离散数学:用整数,多项式和群计算。根本没有浮点。

2 个答案:

答案 0 :(得分:2)

  

主要任务需要少量子计算才能得到结果。这些子计算具有子子计算等。每个计算仅取决于树中它下面的计算(假设根节点是顶部)。分支机构之间不需要进行数据共享。在较低级别,子任务的数量可能非常大......等等,恢复,多线程等等。

如果我错了,请纠正我,但在我看来,你正在描述一个map-reduce算法。

请阅读维基百科关于map-reduce的内容:

  

“映射”步骤:主节点获取输入,将其分区为较小的子问题,并将这些子问题分发给工作节点。工作节点可以依次再次执行此操作,从而导致多级树结构。工作节点处理较小的问题,并将答案传递回其主节点。

     

“减少”步骤:然后主节点接受所有子问题的答案,并以某种方式将它们组合起来得到输出 - 它最初试图解决的问题的答案。

使用现有的mapreduce框架可以节省大量时间。

我只是谷歌“map reduce C ++”,我开始得到结果,特别是在提升http://www.craighenderson.co.uk/mapreduce/

答案 1 :(得分:0)

  

由于需要大量子任务的较低级别的问题,这些似乎不太正确。我想,我可以在这个级别以迭代器方式处理它。

你绝对不需要数以百万计的CPU绑定线程。您最多需要N个CPU绑定线程,其中N是计算机上CPU数量和每个CPU核心数的乘积。超过N一点点,你正在减慢一些事情。经常超过N而且你正在放慢速度。该机器将花费几乎所有的时间来交换上下文中的线程,花费很少的时间自己执行线程。超过N很多,你很可能会崩溃你的机器(或线程上的一些限制)。如果您想同时批量生产很多(并且很多)并行任务,您需要使用多台机器或使用您的图形卡。