roy*_*vib 5 arrays allocation chapel
与其他语言不同,Chapel中似乎没有allocate或new语法在堆上分配数组,而是使用通常的"声明"类语法.例如,在下面的代码中,我"声明"了两个数组,A并B在一个基于正式(虚拟)参数的函数中:
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
Run Code Online (Sandbox Code Playgroud)
这给出了以下结果:
A.domain = {1..3}
B.domain = {2..5}
A.domain = {1..10000000}
B.domain = {-10000000..10000000}
Run Code Online (Sandbox Code Playgroud)
因为没有堆栈溢出(尽管大小很大B),可以假设上面的语法总是在堆上分配A并且B不管它们的大小如何?
此外,域变量的赋值(或重新赋值)似乎扮演了数组的分配(或重新分配)的角色.例如,以下代码按预期工作.在这种情况下,分配是否总是在堆上发生(再次)?
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 );
Run Code Online (Sandbox Code Playgroud)
结果:
C =
C = 7.0 7.0 7.0
C = 0.0 0.0 7.0 7.0 7.0 0.0 0.0
Run Code Online (Sandbox Code Playgroud)
最后,用户是否需要手动deallocate或delete这些数组,而是系统根据需要自动解除分配?
是否可以假设上述语法始终在堆上分配 A 和 B,无论它们的大小如何?
从 Chapel 1.15.0 开始,Chapel 数组元素始终分配在堆上。我们已经讨论了添加机制(例如,自定义域映射)或可能的优化,这些机制可用于在适当时将数组元素存储在堆栈上,但尚未追求此类功能。请注意,虽然数组的元素是在堆上分配的,但数组也是使用“就地”分配的运行时描述符来实现的(例如,在示例中的堆栈上)——该描述符指的是堆分配的元素。
此外,域变量的赋值(或重新分配)似乎起到了数组分配(或重新分配)的作用。
这是正确的,值得强调的是,这是一个逻辑上而非物理上的重新分配概念。具体来说,当一个数组的域被重新分配时,如果是在旧域和新域的索引集中,A[i]将继续存储相同的值。i这就是为什么当您在上面的代码中domC从更改{1..3}为时,被保留,因为它代表两个集合的交集。{-1..5}A[1..3]
分配是否总是发生在堆上(再次)?
是的,就像初始数组分配一样。
是否不需要用户手动释放或删除这些数组,而是系统根据需要自动释放它们?
没错,数组内存管理通常由实现来处理。手动管理数组内存的一种方法是使用带有数组字段的类变量(因为类是手动管理内存的)。