该程序无法扩展的主要原因可能是计算从未使用除初始语言环境之外的任何语言环境。具体来说,forall 在范围内循环,就像代码中的范围一样:
forall i in 1..size do
始终使用在当前语言环境上执行的任务来运行所有迭代。这是因为范围不是 Chapel 中的分布式值,因此它们的并行迭代器不会跨区域设置分配工作。结果,循环体的所有 size**3 次执行:
grid3[i,j] += grid[i,k] * grid2[k,j];
将在区域设置 0 上运行,并且它们都不会在区域设置 1 上运行。您可以通过将以下内容放入最内层循环的主体中来看到这种情况:
writeln("locale ", here.id, " running ", (i,j,k));
(where here.id
打印出当前任务正在运行的区域设置的 ID)。这将显示区域设置 0 正在运行所有迭代:
0 running (9, 1, 1)
0 running (1, 1, 1)
0 running (1, 1, 2)
0 running (9, 1, 2)
0 running (1, 1, 3)
0 running (9, 1, 3)
0 running (1, 1, 4)
0 running (1, 1, 5)
0 running (1, 1, 6)
0 running (1, 1, 7)
0 running (1, 1, 8)
0 running (1, 1, 9)
0 running (6, 1, 1)
...
将此与在分布式域上运行 forall 循环进行对比,例如gridSpace
:
forall (i,j) in gridSpace do
writeln("locale ", here.id, " running ", (i,j));
其中迭代将分布在语言环境之间:
locale 0 running (1, 1)
locale 0 running (9, 1)
locale 0 running (1, 2)
locale 0 running (9, 2)
locale 0 running (1, 3)
locale 0 running (9, 3)
locale 0 running (1, 4)
locale 1 running (8, 1)
locale 1 running (10, 1)
locale 1 running (8, 2)
locale 1 running (2, 1)
locale 1 running (8, 3)
locale 1 running (10, 2)
...
由于所有计算都在语言环境 0 上运行,但一半数据位于语言环境 1 上(由于数组是分布式的),因此会生成大量通信以从语言环境 1 的内存获取远程值到语言环境 0 的内存,以便进行计算它。