计算公式结果的最佳方法是什么?

时间:2009-02-11 08:49:38

标签: parallel-processing formula rpn

我目前有一个可以包含100个用户定义公式的应用程序。目前,我使用反向抛光表示法来执行计算(将值和变量推送到堆栈,然后将它们从堆栈中弹出并进行评估)。什么是开始并行化这个过程的最佳方法?我应该看一种功能语言吗?

计算是在数字数组上进行的,例如简单的A + B实际上可能意味着100次加法。我目前正在使用Delphi,但这不是一个要求。我将使用最适合这项工作的工具。公式也可以相互依赖。因此,我们可以有一个公式C = A + B,第二个公式例如D = C + A.

2 个答案:

答案 0 :(得分:1)

如果可能的话,我会建议采用SIMD风格的方法。也就是说,创建线程来计算单个数据集的所有公式。试图划分公式的计算以使它们并行化将不会产生很大的速度提升,因为能够将计算分解为适合于线程的离散单元所需的逻辑将难以编写并且更难以正确,开销将取消任何速度增益。它也会因收益递减而迅速受损。

现在,如果您有一组应用于多组数据的公式,那么并行化变得更容易并且可以更好地扩展。每个线程对一组数据进行所有计算。为每个CPU核心创建一个线程,并为每个核心设置其亲和性。每个线程都实例化公式评估代码的一个实例。创建一个加载单个数据集的管理程序,并将其传递给空闲线程。如果没有线程空闲,则等待第一个线程完成其数据的处理。处理完所有数据集并完成所有线程后,退出。使用这种方法,拥有比CPU上的内核更多的线程没有任何优势,因为线程切换速度很慢并且会对整体速度产生负面影响。

如果您只有一个数据集,那么这不是一项简单的任务。它需要解析分支的评估树而不依赖于其他分支,并将这些分支种植到每个核心上运行的单独线程并等待结果。然后,您会在同步数据和确保数据一致性方面遇到问题。

答案 1 :(得分:1)

让我们假设你的公式(方程式)不是循环的,否则你不能“只”评估它们。如果你有像A = B + C这样的矢量化方程式,其中A,B和C是数组,那么让我们在概念上将它们分解为组件上的方程式,这样如果数组大小为5,则该方程式被分成

a1 = b1 + c1
a2 = b2 + c2
...
a5 = b5 + c5

现在假设这个,你有一组关于简单量的方程(无论是整数,有理数还是别的)。

如果你有两个方程式E和F,假设F的右侧提到E的左侧,则说F依赖于E,例如

E: a = b + c
F: q = 2*a + y

现在,为了解决这个问题,你可以随时使用随机迭代来解决这个问题(这只是解释中的一个中间步骤),遵循这个算法:

1 while (there is at least one equation which has not been computed yet)
2   select one such pending equation E so that:
3     for every equation D such that E depends_on D:
4       D has been already computed
5   calculate the left-hand side of E

无论您如何在线选择,这个过程都以正确的答案结束。现在,很酷的事情是它也很容易并行化。你可以在任意数量的线程中运行它!你需要的是一个并发安全队列,它保存那些先决条件(方程所依赖的)已被计算但尚未自己计算的方程式。每个线程一次从该队列中弹出(线程安全地)一个等式,计算答案,然后检查是否存在新的等式,以便计算所有先决条件,然后添加这些等式(线程安全)到工作队列。完成。

相关问题