`forall`表达式:并行或串行计算?

时间:2017-05-04 17:58:06

标签: chapel

我对forall语句的理解是它们是并行执行的,而for语句是串行执行的。实际上,下面的代码似乎证实了这种期望(即,因为线程而仅针对forall的随机序列):

for i in 1..5 do writeln( i * 10 );
10
20
30
40
50

forall i in 1..5 do writeln( i * 10 );
10
50
20
30
40

另一方面,如果我在右侧使用forall(或equivalent [...])作为表达式

var A = ( forall i in 1..5 do i * 10 );
var B = [ i in 1..5 ] i * 10;

var X = ( forall a in A do a );
var Y = [ a in A ] a;

var P = ( for i in 1..5 do i * 10 );  // for comparison

writeln( "A = ", A );
writeln( "B = ", B );
writeln( "X = ", X );
writeln( "Y = ", Y );
writeln( "P = ", P );

所有结果都相同(即从10到50排序):

A = 10 20 30 40 50
B = 10 20 30 40 50
X = 10 20 30 40 50
Y = 10 20 30 40 50
P = 10 20 30 40 50

这是否意味着赋值右侧的forall表达式总是以串行方式执行?如果是这样,相应的[...]也相当于此上下文中的for表达式吗?

1 个答案:

答案 0 :(得分:3)

好问题。您可以使用 forall 表达式(显式或[] - "括号")以这种方式生成确定性结果,但{{{ 1}}表达式确实仍会导致并行执行。

像你这样的表达式有效地导致了拉链迭代,这种迭代被定义为相应的迭代将匹配。例如,在中,似乎"整数阵列"操作如:

forall

等同于(提升)执行zippered var A, B, C: [1..10] real; A = B + C; 循环:

forall

这两个表达式:
(a)指定并行执行,
(b)确保 var A, B, C: [1..10] real; forall (a, b, c) in zip(A, B, C) do a = b + c; 的相应元素,AB数组用在循环体的每个实例中(否则语言不会非常有用)。

举一个例子,

C

相当于:

...B = [ i in 1..5 ] i * 10...

或:

forall (b, v) in zip(B, [i in 1..5] i * 10) do
  b = v;

和您提供的其他变体类似。

这是通过使用称为 leader-follower iterators 的概念在Chapel中完成的。这些最初是在PGAS 2011上发表的一篇名为User-Defined Parallel Zippered Iterators in Chapel slides are here的论文中描述的。它们也在教堂primer on parallel iterators中描述。