6

他の言語とは異なり、Chapel には配列をヒープに割り当てるためのallocateornew構文がないように見えますが、通常の「宣言」のような構文を使用します。たとえば、次のコードでは、2 つの配列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

最後に、ユーザーがこれらのアレイを手動で作成する必要はdeallocateなくdelete、必要に応じてシステムが自動的に割り当てを解除するのでしょうか?

4

1 に答える 1

4

上記の構文では、サイズに関係なく常に A と B がヒープに割り当てられると想定してもよろしいですか?

Chapel 1.15.0 では、Chapel 配列要素は常にヒープに割り当てられます。適切な場合に配列の要素をスタックに格納するために使用される可能性のあるメカニズム (カスタム ドメイン マップなど) または最適化の追加について説明しましたが、そのような機能はまだ追求していません。配列の要素はヒープに割り当てられますが、配列も「インプレース」に割り当てられるランタイム記述子を使用して実装されることに注意してください (たとえば、例のスタック上)---この記述子は、ヒープに割り当てられた要素を参照します。 .

また、ドメイン変数の割り当て (または再割り当て) は、配列の割り当て (または再割り当て) の役割を果たしているようです。

その通りです。これは再割り当ての物理的ではなく論理的な概念であることを強調する価値があります。具体的には、配列のドメインが再割り当てされると、古いドメインと新しいドメインの両方のインデックス セットにある場合、 は同じ値を格納し続けます。これが、上記のコードでからに変更したときにが保持された理由です。これは、2 つのセットの交差を表すためです。A[i]idomC{1..3}{-1..5}A[1..3]

割り当ては常にヒープで行われますか (再び)?

はい、配列の初期割り当てと同様です。

ユーザーがこれらのアレイを手動で割り当て解除または削除する必要はありませんが、必要に応じてシステムが自動的に割り当て解除しますか?

その通りです。配列のメモリ管理は、通常、実装によって処理されます。配列メモリを手動で管理する方法は、配列フィールドを持つクラス変数を持つことです (クラスは手動でメモリ管理されるため)。

于 2017-06-06T04:45:22.247 に答える