メインコンテンツ

coder.nullcopy

生成されたコードでの初期化されていない変数の宣言

説明

coder.nullcopy を使用すると、変数値をコピーせずに、初期化されていない変数を宣言することで、生成されたコードを最適化できます。coder.nullcopy は、次の 2 つの特定の状況でのみ使用してください。

  • コード生成時に、次のいずれかのエラーが表示された場合:

    コード生成では、すべての変数を使用前に完全に定義する必要があります。

    コード生成では、すべての cell 配列要素を使用前に完全に定義する必要があります。

    ただし、すべての実行パス上のすべての変数と cell 配列要素が完全に定義されており、他のトラブルシューティングの解決策を検討して却下した場合です。問題の解決: 変数は使用前に完全に定義する必要がある (MATLAB Coder)および問題の解決: cell 配列の要素は使用前に完全に定義する必要があるを参照してください。

  • 生成されたコードに冗長な変数代入がある場合。つまり、変数に値が代入されてから、その変数が使用される前に別の値が代入されている場合です。

coder.nullcopy は注意して使用してください。ほとんどの場合、MATLAB® コードに coder.nullcopy 関数を含めなくても、コード ジェネレーターは coder.nullcopy に対応する最適化を自動的に実行します。coder.nullcopy を使用して変数を宣言し、使用する前に変数に完全な代入を行わないと、生成されたコードの動作が予測不能になることがあります。

X = coder.nullcopy(A) は、A の型、サイズおよび実数/複素数を X にコピーしますが、要素の値はコピーしません。生成されたコードでは、coder.nullcopy は初期化されていない変数を宣言し、メモリの初期化のオーバーヘッドを発生させることなく、X のメモリを事前に割り当てます。MATLAB の実行では、coder.nullcopy は入力値を返します。

ほとんどの場合、coder.nullcopy は再帰的に適用されます。つまり、A が集約型 (クラス、構造体、または cell 配列) の場合、coder.nullcopyA のフィールド、プロパティ、または要素のメモリを事前に割り当てます。ただし、A が 1 つ以上の可変サイズの配列を含む集約型である場合は、特別な考慮事項が適用されます。クラス、構造体、または cell 配列内での可変サイズの配列の宣言を参照してください。

X を使用するか返す前に、そのすべての要素に値を代入しなければなりません。そうしないと、生成されたコードの動作が予測不能になる可能性があります。

すべて折りたたむ

この例では、配列の各要素に値を代入するオーバーヘッドを発生させずに、生成されたコードで配列を宣言する方法を示します。

nn 列の行列を返す MATLAB 関数 foo を作成します。配列の各要素に値 1 を代入して、出力行列変数 out を初期化します。次に、for ループを使用して、out の各要素に値を再度代入します。

function out = foo(inp) %#codegen
out = ones(inp);
for idx = 1:inp*inp
   if mod(idx,2) == 0
      out(idx) = idx;
   else
      out(idx) = idx + 1;
   end
end

この関数の C コードを生成し、生成されたコードを調べます。C コードは、for ループ内で out の各要素に値 1.0 を明示的に代入しています (C コード マッピングの 33 行目から 35 行目)。生成されたコードは、次に、2 番目の for ループで out の要素に値を再度代入しています (行 37 ~ 43)。

Code mapping between MATLAB code and generated C code without using coder.nullcopy

foo を修正し、coder.nullcopy を使用して、out を double の nn 列の行列として宣言してから、for ループを使用して各要素に値を代入します。

function out = foo(inp) %#codegen
out = coder.nullcopy(ones(inp));
for idx = 1:inp*inp
   if mod(idx,2) == 0
      out(idx) = idx;
   else
      out(idx) = idx + 1;
   end
end

この関数の C コードを生成し、生成されたコードを、coder.nullcopy を使用せずに生成されたコードと比較します。coder.nullcopy を使用している場合、生成されたコードは out の要素に 1 回だけ値を代入します。

Code mapping between MATLAB code and generated C code when using coder.nullcopy

1 つ以上の可変サイズの配列を含む集約型 (クラス、構造体、または cell 配列) で coder.nullcopy を呼び出す場合は、for ループを使用して値を代入する前に、可変サイズの配列に対して coder.nullcopy を直接呼び出す必要もあります。ベクトル化された代入を実行する場合、あるいはフィールド、プロパティ、または cell 配列の要素が固定サイズの場合は、この追加の手順は必要ありません。

たとえば、関数 copyStructExample について考えます。この関数は、3 つのフィールド (そのうち 2 つは可変サイズ) をもつ構造体を返します。coder.nullcopy を使用してこの構造体を宣言してから、各フィールドに値を代入します。

  • for ループを使用して、固定サイズの out.field1 に値を代入します。

  • ベクトル化を使用して、可変サイズの out.field2 に値を代入します。

  • 可変サイズの s.field3 に対して直接 coder.nullcopy を呼び出してから、for ループを使用して out.field3 に値を代入します。

function out = copyStructExample(n) %#codegen

s.field1 = ones(1,5);
s.field2 = ones(1,n);
s.field3 = ones(1,n);
out = coder.nullcopy(s); % out is a structure with unassigned contents

for i = 1:5
    out.field1(i) = i+2;
end

out.field2 = 5:5:n*5;

out.field3 = coder.nullcopy(s.field3);
for i = 1:n
    out.field3(i) = i*2;
end
end

入力引数

すべて折りたたむ

コピーする変数。スカラー、ベクトル、行列、構造体、または多次元配列として指定します。

データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | logical | char | string | struct | class
複素数のサポート: あり

制限

  • coder.nullcopy はスパース行列では使用できません。

  • coder.nullcopy は、オーバーロードされたかっこをサポートするクラス、または table などのデータにアクセスするためにインデックス手法を必要とするクラスでは使用できません。

拡張機能

すべて展開する

C/C++ コード生成
MATLAB® Coder™ を使用して C および C++ コードを生成します。

GPU コード生成
GPU Coder™ を使用して NVIDIA® GPU のための CUDA® コードを生成します。

バージョン履歴

R2011a で導入