Chapel:数组数组与内存中的 2-dim 数组

Chapel: Array of arrays vs 2-dim array on memory

在 Chapel 中,似乎可以使用符号 [][] 来声明数组。这看起来和其他语言的"array of arrays"非常相似,所以我想知道它是否是所谓的"jagged array",每个子数组在内存中独立分配?比如下面的代码中,a[0][..]a[1][..]在内存中不一定是连续的? (我在这里感兴趣的是,由于内存不连续,使用这种 [][] 是否比 [,] 效率低。)

proc test( D1, D2 )
{
    var a: [D1][D2] int;   // "jagged" array?
    var b: [D1, D2] int;   // I assume this is a rectanguar (contiguous) array

    for i in D1 do
    for j in D2 do
        a[i][j] = i * 100 + j;

    for (i, j) in b.domain do
        b[i, j] = i * 100 + j;

    var lo = D1.low, hi = D1.high;

    writeln( "a = ", a );
    writeln( "a[ lo ] = ", a[ lo ] );
    writeln( "a[ hi ] = ", a[ hi ] );
    writeln();
    writeln( "b = ", b );
    writeln( "b[ lo, .. ] = ", b[ lo, .. ] );
    writeln( "b[ hi, .. ] = ", b[ hi, .. ] );
}

test( 0..1, 1..3 );

$ chpl test.chpl
$ ./a.out

a = 1 2 3 101 102 103
a[ lo ] = 1 2 3
a[ hi ] = 101 102 103

b = 1 2 3
101 102 103
b[ lo, .. ] = 1 2 3
b[ hi, .. ] = 101 102 103

一个相关的问题是:有什么方法或命令可以知道给定变量或数组元素的内存位置(地址)(以获取有关内存分配的信息)?

你是正确的,对于 Chapel (var A: […][…] …) 中的数组,每个子数组将独立存储,因此在内存中可能不连续(尽管它们可能是连续的,具体取决于位置分配器放置它们)。无论它们是否连续,都需要额外的间接访问才能到达子数组。

多维数组 (var A: […, …] …) 的实现由其域映射控制,域映射控制元素在内存中的存储方式。默认域映射在内存中连续存储多维数组。

哪种数组形式更有效可能取决于您编写的计算风格和您所在的系统 运行。但是,作为一个具体示例,如果您要连续访问数组的元素,那么多维数组通常会优于数组的数组,因为它的内存位置是连续的,正如您所注意到的。

Chapel 本身不太喜欢公开地址,但如果您依靠某些互操作性功能,则可以确定事物所在的位置。例如,以下程序使用 c_ptrTo() 来获取指向某些数组元素的 C 指针,然后使用 printf() 打印出这些位置:

use CPtr;

config const n = 3;

var A: [1..n][1..n] real;

var a11 = c_ptrTo(A[1][1]),
    a12 = c_ptrTo(A[1][2]),
    a21 = c_ptrTo(A[2][1]);

var B: [1..n, 1..n] real;

var b11 = c_ptrTo(B[1,1]),
    b12 = c_ptrTo(B[1,2]),
    b21 = c_ptrTo(B[2,1]);

extern proc printf(x...);

printf("%p %p %p\n", a11, a12, a21);
printf("%p %p %p\n", b11, b12, b21);