【发布时间】:2015-08-28 03:14:59
【问题描述】:
我正在尝试为给定的 4D 输入向量网格上的所有点计算一些函数(实现为计算成本很高的迭代算法)(网格是笛卡尔坐标,每个维度上的点等距,由段 [a, b] 和数字指定此段上的点距离相等/恒定步长 - 对于每个维度(总共 4 个))。我们可以从“真实世界”值中抽象出来,并将网格视为具有给定尺寸的 4D 数组([5, 4, 3, 7] - 5x4x3x7 笛卡尔网格)并在它们上使用索引 - 用于引用一些切片/点。
我的计算算法将该向量(指定 4D 网格上的点)作为输入并计算(可能在相当长的时间内)一些结果(不管它们是什么)。
我需要并行化程序以加快对所有网格顶点的相当长的计算过程。所以我想将输入网格拆分为子网格,每个网格上的点数尽可能接近,以平衡不同线程/进程上的工作负载。
最简单的解决方案是在 1 个选定维度上划分网格 - 但问题是,这个隔离维度上的切片数量可能少于“虚拟计算设备”的数量(使用不同的线程/进程 - 我会参考它们作为VCD)。使用的 VCD 数量是非恒定的,等于我们需要的子网格数量。所以我需要使用更多的维度来“分割”——我认为使用 2-3 维度(由于特定的输入——我们可以假设某些维度大于某个值)产生足够的切片来在 VCD 之间进行分割。
为了更好地解释,这里有例子。我们在每个维度上都有[2, 2, 10, 7] 4D 网格大小的向量。子网格数为20。所以我们不能把一个维度分成20个部分,我们必须以某种方式组合它们。在这种情况下,我们很幸运地注意到 2,3 维度正好给出 2x10 点 = 20 个 VCD。所以我们只是将网格分成20[2, 1, 1, 7]子网格(在2,3维上退化)并将它们传递给VCD。
当没有一个维度的产品除以 VCD 的数量而没有余数时,它变得更加困难,所以我们需要以某种方式分配它/我们需要使用更多的维度一起进行拆分。例如,[2, 3, 4, 5] 表示 VCD 计数 = 11。
所以,问题是 - 如何将给定的笛卡尔 4D 网格分成 N 个子网格(网格上的点数大于 N),可能同时使用多个维度(可以假设某些维度(3至少)产生比 N 更多的切片 - dim[1] x dim[2] x dim[3] > N)
我接受任何语言的答案,但最好使用 C 样式的伪代码。
编辑:我意识到我根本不需要拆分网格,正如 Nico Schertler 指出的那样。我知道序列化索引的技巧(感谢矩阵和堆实现),但我被我的“多维”思维方式误导了。另外,我忘了指定网格上的计算是完全独立的。我最初必须解决的问题是“如何划分 4D 网格以进行并行处理” - 在处理器之间构建序列化索引并基于它将点序列划分为段是明亮而简单的解决方案(但对于我)。此外,这个答案也适合 N 维网格。 所以我学到的教训是 - 迭代(甚至并行)只需要一个维度,所以尝试序列化。
【问题讨论】:
-
如果您可以选择 .NET,您可能会喜欢 Load Balancing Partitioners。
标签: c++ algorithm matlab parallel-processing combinatorics