【发布时间】:2011-07-20 12:27:59
【问题描述】:
我有一个计算代数任务需要编写代码。问题被分解为定义明确的个体任务,这些任务自然形成树——任务本质上是组合的,因此有一个主要任务需要少量的子计算来获得结果。那些子计算有子子计算等等。每个计算只取决于树中它下面的计算(假设根节点是顶部)。分支机构之间无需进行数据共享。在较低级别,子任务的数量可能非常大。
我之前以函数方式对其进行了编码,根据需要调用函数并将所有内容存储在 RAM 中。这是一种糟糕的方法,但我当时更关心的是理论。
出于各种原因,我打算用 C++ 重写代码。我有几个要求:
- Checkpointing:计算需要很长时间,所以我需要能够随时停止并稍后恢复。
- 将单个任务分离为对象:这有助于我很好地掌握我在计算中的位置,并提供了一种通过序列化进行检查点的简洁方法。
- 多线程:任务显然是令人尴尬的并行,所以利用它会很巧妙。我可能想为此使用 Boost 线程。
我想就如何实际实施这样的系统提出建议。我想到的方法:
- 以简单堆栈的形式实施任务。当您遇到需要完成子计算的任务时,它会检查它是否具有所需的所有子计算。如果没有,它会创建子任务并将它们扔到堆栈上。如果是,则计算其结果并将自己从堆栈中弹出。
- 将任务存储为树并执行类似于深度优先访问者模式的操作。这将在开始时创建所有任务,然后计算将遍历树。
这些似乎不太正确,因为较低级别的问题需要大量子任务。我想我可以在这个级别以迭代器的方式来处理它。
我觉得我想多了,而且已经有一种简单、成熟的方法来做这样的事情。有吗?
技术细节以防万一:
- 任务树有 5 个级别。
- 对于所有级别,树的分支因子都非常小(例如,在 2 和 5 之间),但最低的级别为几百万。
- 每个单独的任务只需要存储几十个字节的结果。我不介意尽可能多地使用磁盘,只要它不会影响性能。
- 为了调试,我必须能够调用/重新计算任何单个任务。
- 所有计算都是离散数学:整数、多项式和组的计算。根本没有浮点数。
【问题讨论】:
-
让它“可分发”有意义吗? IE。设计每个计算,以便它可以由主程序“就地”执行,可能在一个线程中,但也可以分布在更多节点上,有点像 SETI@home?
-
不是一个答案,只是一个想法,但这似乎让人想起像“make”这样的构建工具在跟踪目标之间的依赖关系时所做的事情。在这种情况下,检查点由文件系统自动处理。 Gnu make 当然可以选择使用多个线程。可能值得研究一下您是否可以从他们的做法中学到任何东西。
-
我想对于第二个从底部的任务分发它是有道理的(包括几百万个子任务)。所有其他任务都需要很少的时间,所以不值得。除了我自己的电脑之外,我也不希望能够访问更多的东西。
标签: c++ design-patterns architecture combinatorics