chapel icon indicating copy to clipboard operation
chapel copied to clipboard

Multidimensional zippered iteration (or promotion) kills performance

Open bradcray opened this issue 5 years ago • 14 comments

[This is a longstanding issue that I'm capturing on GitHub since I couldn't find it here]

When iterating over multiple multidimensional arrays using zippered iteration, performance currently falls off a steep cliff. For example:

var A, B: [1..n, 1..n] real;
forall (a, b) in zip(A, B) do
  a = 2*b;

This can also happen when calling a scalar function in a promoted manner with multidimensional arrays, since it is equivalent to a zippered iteration:

foo(A, B);
proc foo(x: real, y: real) { ... }

The reason for this is that the compiler currently doesn't know how to combine the parallel iterators for multidimensional arrays into a single compact loop nest, so it falls back to the catch-all implementation of creating an iterator object for each array and iterating over those objects in a zippered manner. While this result in a correct and very general-purpose implementation for very arbitrary array iterators, it is also very expensive.

Until this situation is improved, users can often work around the issue for cases that share the same domain (like above) by looping over the domain and indexing into the arrays to avoid the zippered iteration:

forall ind in A.domain do
  A[ind] = 2*B[ind];

or:

forall ind in A.domain do
  foo(A[ind], B[ind]);

bradcray avatar May 31 '19 22:05 bradcray