在Chapel中分配数组

问题描述:

与其他语言不同,Chapel中没有allocatenew语法用于在堆上分配数组,而是使用通常的“声明”类语法。例如,在下面的代码,I“声明”两个阵列在功能AB基于正式(虚设)参数:在Chapel中分配数组

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手动这些阵列,但根据需要而系统会自动解除分配它们?

可以假设上面的语法总是在堆上分配A和B,而不管它们的大小如何?

礼拜堂1.15.0的礼拜堂数组元素始终分配在堆上。我们已经讨论过添加机制(例如,自定义域映射)或可能的优化,可能用于在适当的时候将数组的元素存储在堆栈上,但尚未追求这些功能。请注意,虽然数组的元素分配在堆上,但数组也可以使用“就地”分配的运行时描述符来实现(例如,在您的示例中的堆栈上) - 此描述符指的是堆分配的元素。

另外,域变量的赋值(或重新赋值)似乎扮演着数组分配(或重新赋值)的角色。

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

该分配是否总是出现在堆上(再次)?

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

用户无需手动释放或删除这些数组,而是系统根据需要自动释放它们?

这是正确的,数组内存管理通常由实现来处理。一种手动管理数组内存的方法是使用一个数组字段(因为类是手动内存管理的)。

+1

非常感谢您的解释。我认为有趣的是,赋值域变量意味着对数组(或与该域相关联的所有数组)进行“调整大小”,并且自动完成必要的分配/重新分配。谢谢:) – roygvib

+0

[顺便说一下,第一段中的下列句子“请注意,虽然数组的元素分配在_stack_上”可能是“请注意,尽管数组的元素分配在_heap_上” ? (尽管它可能取决于解释的上下文)] – roygvib

+0

感谢您指出我修复的拼写错误。一旦域使用某种语言,它们似乎是调整数组大小的最自然/最明显的方式,即使有一些学习曲线可以适应它。 – Brad