2

这在我的笔记本电脑上运行良好,但我想知道这是否会导致大规模问题。假设我想填充一个非常大的数组,但每个条目都需要对一个大的、稀疏的分布式矩阵进行密集的矩阵运算。我应该期望以下设计能够坚持吗?

var x: [1..N] real;

forall i in [1..N] {
  x[i] = reallyHeavyMatrixComputation(i);
}

有保持这种理智的提示吗?我应该使用 admapped的域x还是什么?

4

1 回答 1

3

Chapel 的 forall 循环可以扩展到多个语言环境,但它们是否会这样做取决于它们迭代的内容以及循环的主体。

更详细地说,关键的并行循环策略,例如“应该使用多少个任务?” 和“这些任务应该在哪里运行?” 由循环的迭代控制。例如,在以下循环中:

var x: [1..N] real;                        // declare a local array

forall i in 1..N do                        // iterate over its indices in parallel
  x[i] = reallyHeavyMatrixComputation(i);

循环的 iterand 是 range 1..N。默认情况下,范围的迭代器将创建与当前语言环境中的处理器单元/内核数相等的本地任务数。因此,上面的循环不会随着使用更多语言环境而变得更快,除非reallyHeavyMatrixComputation()它本身包含以智能方式在语言环境中分布计算的 on 子句。如果它根本不包含任何 on 子句,则计算将永远不会离开 locale #0,并且只会是共享内存。

相反,如果使用 forall 循环在分布式域或数组上进行迭代,默认策略通常是在每个目标区域设置上运行的任务数量等于以“所有者计算”方式在该区域设置上的处理器内核数量. 也就是说,每个语言环境将执行它所拥有的迭代子集,由分布确定。例如,给定循环:

use CyclicDist;                            // make use of the cyclic distribution module

var D = {1..N} dmapped Cyclic(startIdx=1); // declare a cyclically distributed domain
var x: [D] real;                           // declare an array over that domain

forall i in D do                           // iterate over the domain in parallel
  x[i] = reallyHeavyMatrixComputation();

D 的索引将在区域设置中循环分布,因此并行循环将在每个区域设置上创建任务,这些任务将执行区域设置的索引。因此,即使reallyHeavyMatrixComputation()是完全本地计算,该循环也应该跨多个区域进行扩展。

在 Chapel 中编写可扩展并行循环的另一种方法是调用显式并行迭代器,该迭代器将跨语言环境本身分配工作。例如,Chapel 1.16 版添加了一个分布式迭代器包模块,该模块提供了为您分发工作的迭代器。回到第一个例子,如果它被重写为:

use DistributedIters;                  // make use of the distributed iterator module                                                                          

var x: [1..N] real;                    // declare a local array

forall i in distributedDynamic(1..N) do    // distribute iterations across locales
  x[i] = reallyHeavyMatrixComputation(i);

那么迭代器的调用distributedDynamic将成为循环的迭代,而不是范围1..N和控制任务的创建。此迭代器使用指定的块大小(默认为 1)动态地将迭代处理到区域设置,因此可用于以可扩展的方式使用多个区域设置。有关更多详细信息,请参阅其文档

于 2017-12-20T04:56:12.940 回答