Main Content

スタック領域使用量の制御

コンパイラまたはハードウェアによって使用される最大スタック サイズを制御できます。スタックとは、プログラム実行用のローカル変数を格納するメモリのブロックです。スタック メモリはコード生成時に割り当てられます。通常、スタックの割り当てでは静的な割り当てよりも効率的にメモリが使用されます。

構成設定 StackUsageMax の値はバイト単位で測定されます。ターゲット ハードウェア設定とコード内の可能な実行パスの情報に基づいて、StackUsageMax の特定の値で対応可能なスタック変数が推測されます。この推測では、C コンパイラによって行われたスタック サイズの変更は考慮されません。スタック メモリに収まらない変数は、スタックからあふれます。スタックからあふれた変数は、静的メモリに格納されるか、再呼び出し可能なコードを生成する場合はスピル構造体に格納されます。

  • StackUsageMax を大きくすると、スタック メモリに割り当てられる変数の数を増やすことができます。ターゲット ハードウェアに十分なスタック領域がある場合は、これによってスタックからあふれる変数の数が減ります。

  • StackUsageMax を小さくすると、スタック メモリに割り当てられる変数の数を減らすことができます。ターゲット ハードウェアに十分なスタック領域がない場合は、これによってスタックからあふれる変数の数が増えます。

スタックに収まらない再帰関数内の変数は、静的メモリまたはスピル構造体 (再呼び出し可能なコードを生成する場合) に格納されません。再帰関数内の変数は、スタック使用量サイズを超えてもスタックからあふれません。

同様に、コード生成では、coder.cevalの呼び出しでカスタム コードのスタック使用量は考慮されません。

この例では、生成コードが使用する最大スタック領域を設定する方法を示します。以下の場合に最大スタック使用量を設定します。

  • 組み込みターゲットなどで、スタック領域が制限されている場合。

  • C コンパイラが実行時のスタック オーバーフローをレポートする。

MATLAB Coder アプリを使用したスタック領域の使用量の制御

  1. [生成] ダイアログ ボックスを開くために、[コード生成] ページの [生成] 矢印 をクリックします。

  2. (要件に応じて) [ビルド タイプ][ソース コード][MEX][スタティック ライブラリ][ダイナミック ライブラリ] または [実行可能ファイル] に設定します。

  3. [詳細設定] をクリックします。

  4. [メモリ] タブで、[最大スタック使用量] を必要な値に設定します。

コマンド ラインでのスタック領域の使用量の制御

  1. コード生成の構成オブジェクトを作成します。

    coder.config を、引数 'lib'mex'dll' または 'exe' を (要件に応じて) 指定して使用します。次に例を示します。

    cfg = coder.config('lib');
  2. StackUsageMax プロパティを求める値に設定します。

    cfg.StackUsageMax=400000;

あふれた変数のない生成コード

結果はスタック領域の容量によって異なります。

十分なスタック領域がある場合に次の MATLAB® コードに対応するコードを生成すると、生成コードは以下のようになります。

function y = fooNorm(x)
b = cast(x,'uint32');
y = sum(b);
end

関数 fooNorm(x) への入力は、100100 列の 1 の行列です。

void fooNorm(const double x[10000], double y[100])
{
  double d;
  unsigned int b[10000];
  ...
}
static void main_fooNorm(void)
{
  double dv[10000];
  double y[100];
  argInit_100x100_real_T(dv);
  fooNorm(dv, y);
}
このコードの抜粋では、エントリポイント関数 fooNorm を取り上げています。関数 main_fooNorm は、関数 fooNorm への入力であるスタック上の変数 dv[10000] および y[100] を宣言しています。

あふれた変数のある生成コード

スタック領域が不十分な場合に同じ MATLAB コードに対応するコードを生成すると、コードは以下のようになります。

void fooNorm(const double x[10000], double y[100])
{
  static unsigned int b[10000];
  double d;
  ...
}
static void main_fooNorm(void)
{
  static double dv[10000];
  static double y[100];
  argInit_100x100_real_T(dv);
  fooNorm(dv, y);
}
変数 b[10000]dv[10000] および y[100] は、スタックに収まらないため静的変数として宣言されています。

あふれた変数のある生成された再呼び出し可能なコード

スタック領域が不十分な場合に同じ MATLAB コードに対応する再呼び出し可能なコードを生成すると、生成コードは以下のようになります。

void fooNorm(fooNormStackData *SD, const double x[10000], double y[100])
{
  double d;
  ...
}
static void main_fooNorm(void)
{
  static double dv[10000];
  static double y[100];
  argInit_100x100_real_T(dv);
  fooNorm(&fooNormStackDataGlobal, dv, y);
}
fooNorm への入力は構造体 fooNormStackData です。再呼び出し可能なコードを生成すると、変数がスタックからあふれる場合に、スタックに収まらない変数を保持するスピル構造体が生成されます。

構造体 fooNormStackData は次のように定義されます。

typedef struct {
  struct {
    unsigned int b[10000];
  } f0;
} fooNormStackData;

関連するトピック