【问题标题】:Parallelizing a large dynamic program并行化大型动态程序
【发布时间】:2015-03-14 09:53:09
【问题描述】:

我有一个高性能的 C++ 动态程序,它的结果放在一个 M × N 表中,大约是 2000 行 × 30000 列。
每个条目(rc)都依赖于表中其他几列中的几行。

P个处理器并行计算行r的最明显方法是静态对数据进行分区:即,有处理器p 计算所有有效 k 的条目 (r, p + k P) .

但是,不同列的条目计算时间略有不同(例如,一个可能需要五倍于另一个),所以我想动态地对数据进行分区为了获得更好的性能,通过避免提前完成的 CPU 停顿并让它们从仍在追赶的 CPU 中窃取工作。

解决此问题的一种方法是保留一个原子全局计数器,该计数器指定已计算的列数,并在每次 CPU 需要更多工作时增加它。
但是,这会强制所有 CPU 在计算表中的 每个 条目后访问 same 全局计数器 - 即,它在一定程度上序列化程序。由于计算每个条目或多或少是一个快速的过程,这有点不可取。

所以,我的问题是:
有没有办法以更具可扩展性的方式执行这种动态分区(即在计算每个条目后不必访问单个全局计数器)?

【问题讨论】:

  • 你有没有想过使用 GPU。 CUDA 浮现在脑海中
  • @EdHeal:我有,但是 (1) 我并不真正了解 GPU 编程,并且 (2) 我的理解是 GPU 不适合这样的计算,其中计算量因其他因素而异(例如,依赖项的数量因行和列而异)。
  • "在计算 每个 条目之后" - 为什么不修复粒度?以更大的块分配任务。

标签: c++ parallel-processing dynamic-programming work-stealing


【解决方案1】:

我假设您正在为新值使用第二个数组。如果是这样,听起来 TBB 或 Cilk Plus 的循环结构都可以。两者都使用工作窃取来在可用处理器之间分配工作,当一个处理器耗尽工作时,它会从有可用工作的处理器那里窃取工作。这平衡了数据的“块状”。

要使用 Cilk,您需要一个支持 Cilk Plus 的编译器。 GCC 4.9 和 Intel 编译器都支持它。通常你会写这样的东西:

cilk_for (int x = 0; x < XMAX; x++) {
    for (int y = 0; y < YMAX; y++) {
        perform-the-calculation;
    }
}

TBB 的结构类似。

另一种方法是以不缓存缓存的方式“平铺”计算。也就是说,您实现自己的分而治之算法,该算法将计算分解为具有缓存效率的块。有关缓存遗忘算法的更多信息,请参阅http://www.1024cores.net/home/parallel-computing/cache-oblivious-algorithms/implementation

巴里

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-10
    • 2023-04-11
    • 2015-03-05
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多