Main Content

動的な配列のアクセスの最適化

構成プロパティ CacheDynamicArrayDataPointer を使用して、コード内の動的な配列の実行を速くすることができます。このプロパティは、データのポインターを一時変数にホイストします。その後、動的な配列の場合は、この一時変数が行列データへのアクセスに使用されます。

既定では、このプロパティは、MEX、スタティック ライブラリ、ダイナミック リンク ライブラリ、および実行可能ファイルの構成で有効になっています。動的な配列データのポインターのキャッシュにより、動的な配列の実行時間を静的な配列の実行時間とほぼ等しくなるまで短縮できます。多くの場合、このプロパティはコードの可読性の改善にも役立ちます。

動的な配列データのポインターをキャッシュするプロパティの無効化

MATLAB® Coder™ アプリを使用してプロパティを無効にするには、次のようにします。

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

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

  3. [詳細設定] タブで、[動的な配列データをキャッシュ][いいえ] に設定します。

コマンド ラインでプロパティを無効にするには、次のようにします。

  1. MATLAB ワークスペースで、coder.config を使用して構成オブジェクトを定義します。'mex''lib''dll'、または 'exe' のいずれかの引数を (要件に応じて) 指定します。

    cfg = coder.config('lib');
  2. 構成オブジェクトの CacheDynamicArrayDataPointer プロパティを false に設定します。

    cfg.CacheDynamicArrayDataPointer = false;

生成される C コードの比較

動的な配列データのポインターのキャッシュを有効にした場合と動的な配列データのポインターのキャッシュを無効にした場合で、生成される C コードを比較します。

関数 matrixAdd について考えてみます。

function c = matrixAdd(a,b) %#codegen
c = a+b;
end

構成オブジェクトを定義し、codegen コマンドを使用して C コードを生成します。

  1. 動的な配列データのポインターのキャッシュを有効にして C コードを生成するには、次のようにします。

    cfg = coder.config('lib');
    codegen -config cfg matrixAdd -args ... 
    {coder.typeof(0, [1 Inf]), coder.typeof(0, [1 Inf])} -report
    Code generation successful: View report
  2. 動的な配列データのポインターのキャッシュを無効にして C コードを生成するには、次のようにします。

    cfg = coder.config('lib');
    cfg.CacheDynamicArrayDataPointer = false;
    codegen -config cfg matrixAdd -args ...
    {coder.typeof(0, [1 Inf]), coder.typeof(0, [1 Inf])} -report
    Code generation successful: View report

レポートを開き、生成されたコードを検査します。

次の表は、生成される C コードを比較したものです。プロパティが有効な場合の生成コードには、*a_data*b_data*c_data などの一時変数が含まれています。一時変数の使用により、行列データにアクセスするための double 型のポインターの逆参照が不要になります。そのため、生成される C コードでの動的な配列の実行時間が改善されます。

動的な配列データのポインターのキャッシュを有効化動的な配列データのポインターのキャッシュを無効化
void matrixAdd(const emxArray_real_T *a,... 
const emxArray_real_T *b, emxArray_real_T *c)
{
  double *a_data;
  double *b_data;
  double *c_data;
  int i;
  b_data = b->data;
  a_data = a->data;
  if (a->size[1] == b->size[1]) {
    int loop_ub;
    i = c->size[0] * c->size[1];
    c->size[0] = 1;
    c->size[1] = a->size[1];
    emxEnsureCapacity_real_T(c, i);
    c_data = c->data;
    loop_ub = a->size[1];
    for (i = 0; i < loop_ub; i++) {
      c_data[i] = a_data[i] + b_data[i];
    }
  } else {
    plus(c, a, b);
  }
}
void matrixAdd(const emxArray_real_T *a,... 
const emxArray_real_T *b, emxArray_real_T *c)
{
  int i;
  if (a->size[1] == b->size[1]) {
    int loop_ub;
    i = c->size[0] * c->size[1];
    c->size[0] = 1;
    c->size[1] = a->size[1];
    emxEnsureCapacity_real_T(c, i);
    loop_ub = a->size[1];
    for (i = 0; i < loop_ub; i++) {
      c->data[i] = a->data[i] + b->data[i];
    }
  } else {
    plus(c, a, b);
  }
}

制限

動的な配列データのポインターのキャッシュは、以下についてはサポートされていません。

  • C++ coder::array

  • GPU Coder

  • データ配置仕様を含むコード置換ライブラリ (CRL)

参考

|

関連するトピック