Chapel 中数组的分配

Allocation of arrays in Chapel

与其他语言不同,Chapel 中似乎没有 allocatenew 语法用于在堆上分配数组,而是使用通常的 "declaration" 类语法。例如,在下面的代码中,我 "declare" 两个数组 AB 在一个基于正式(虚拟)参数的函数中:

proc test( n, D )
{
    var A: [1..n] real;  // local array
    var B: [D] real;     // local array

    writeln( "A.domain = ", A.domain );
    writeln( "B.domain = ", B.domain );
}

test( 3, {2..5} );               // request small arrays
test( 10**7, {-10**7..10**7} );  // request large arrays

结果如下:

A.domain = {1..3}
B.domain = {2..5}
A.domain = {1..10000000}
B.domain = {-10000000..10000000}

因为没有发生堆栈溢出(尽管B的大小很大),是否可以假设上面的语法总是在堆上分配AB而不考虑他们的尺寸?

此外,域变量的赋值(或重新赋值)似乎起到了数组分配(或重新分配)的作用。例如,以下代码按预期工作。在这种情况下,分配是否总是发生在堆上(再次)?

var domC: domain(1);
var C: [domC] real;
writeln( "C = ", C );

domC = { 1..3 };       // assign a domain
C = 7.0;               // assign some value to the array
writeln( "C = ", C );

domC = { -1..5 };      // re-assign a domain
writeln( "C = ", C );

结果:

C = 
C = 7.0 7.0 7.0
C = 0.0 0.0 7.0 7.0 7.0 0.0 0.0

最后,用户是否不需要手动deallocatedelete这些数组,而是系统根据需要自动释放它们?

is it OK to assume that the above syntax always allocates A and B on the heap regardless of their size?

从 Chapel 1.15.0 开始,Chapel 数组元素始终分配在堆上。我们已经讨论了添加机制(例如,自定义域映射)或可能用于在适当时将数组元素存储在堆栈上的优化,但尚未追求此类功能。请注意,虽然数组的元素是在堆上分配的,但数组也是使用分配的运行时描述符实现的 "in-place" (例如,在您的示例中的堆栈上)---此描述符指的是堆分配的元素.

Also, assignment (or re-assignment) of a domain variable seems to play the role of allocation (or re-allocation) of an array.

没错,值得强调的是,这是 逻辑上 而不是 物理上 的重新分配概念。具体来说,当数组的域被重新分配时,如果 i 在旧域和新域的索引集中,A[i] 将继续存储相同的值。这就是为什么当您在上面的代码中将 domC{1..3} 更改为 {-1..5} 时,A[1..3] 被保留,因为它代表两个集合的交集。

does the allocation always occur on the heap (again)?

是的,与初始数组分配一样。

is it not necessary for the user to deallocate or delete these arrays manually, but rather the system automatically deallocates them as needed?

没错,数组内存管理通常由实现处理。手动管理数组内存的一种方法是使用带有数组字段的 class 变量(因为 classes 是手动内存管理的)。