メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

サイズと次元が異なるバッファーの再利用

サイズと形状が異なる行列にバッファーを再利用できます。この最適化を有効にするには、[コンフィギュレーション パラメーター] ダイアログ ボックスで [サイズと次元が異なるバッファーの再利用] を選択します。この最適化により、RAM と ROM の使用が抑えられ、コードの実行速度が改善します。

モデル例

モデル DifferentSizeReuse には、サイズと次元が異なる信号が含まれています。

model='DifferentSizeReuse';
open_system(model);

最適化を使用しないコードの生成

[コンフィギュレーション パラメーター] ダイアログ ボックスで [サイズと次元が異なるバッファーの再利用] パラメーターを off に設定するか、MATLAB® コマンド ウィンドウで次のように入力します。

set_param('DifferentSizeReuse','DifferentSizesBufferReuse','off');

コメントをオフにしてモデルをビルドします。

set_param('DifferentSizeReuse','GenerateComments','off');
slbuild('DifferentSizeReuse');
### Searching for referenced models in model 'DifferentSizeReuse'.
### Total of 1 models to build.
### Starting build procedure for: DifferentSizeReuse
### Successful completion of build procedure for: DifferentSizeReuse

Build Summary

Top model targets:

Model               Build Reason                                         Status                        Build Duration
=====================================================================================================================
DifferentSizeReuse  Information cache folder or artifacts were missing.  Code generated and compiled.  0h 0m 30.437s 

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 32.424s

最適化を行わない生成コードを表示します。D_Work 構造体は次のとおりです。

hfile = fullfile('DifferentSizeReuse_ert_rtw',...
    'DifferentSizeReuse.h');
coder.example.extractLines(hfile,'typedef struct {','} D_Work',1,1);
typedef struct {
  real_T ComplextoRealImag_o1[16384];
  real_T ComplextoRealImag_o2[16384];
  real_T z[3969];
  real_T z_n[3969];
  real_T z_j[4032];
  real_T z_m[4032];
  real_T z_g[4096];
  real_T z_e[4096];
} D_Work;

DifferentSizeReuse.c の部分は次のとおりです。

cfile = fullfile('DifferentSizeReuse_ert_rtw',...
    'DifferentSizeReuse.c');
coder.example.extractLines(cfile,'#include "DifferentSizeReuse.h"',...
    'void DifferentSizeReuse_initialize(void)',1,0);
#include "DifferentSizeReuse.h"
#include "rtwtypes.h"
#include <math.h>

D_Work rtDWork;
ExternalInputs rtU;
ExternalOutputs rtY;
static RT_MODEL rtM_;
RT_MODEL *const rtM = &rtM_;
static void Downsample(const real_T rtu_u[16384], real_T rty_z[4096]);
static void DeltaX(const real_T rtu_u[4096], real_T rty_z[4032]);
static void DeltaY(const real_T rtu_u[4032], real_T rty_z[3969]);
static void NoninplaceableSS1(void);
static void NoninplaceableSS2(void);
static void NoninplaceableSS3(void);
static void Downsample(const real_T rtu_u[16384], real_T rty_z[4096])
{
  int32_T tmp;
  int32_T tmp_0;
  int32_T tmp_1;
  int32_T x;
  int32_T y;
  for (x = 0; x < 64; x++) {
    for (y = 0; y < 64; y++) {
      tmp_0 = (y + 1) << 1;
      tmp_1 = (x + 1) << 1;
      tmp = ((tmp_0 - 2) << 7) + tmp_1;
      tmp_0 = ((tmp_0 - 1) << 7) + tmp_1;
      rty_z[x + (y << 6)] = (((rtu_u[tmp - 2] + rtu_u[tmp - 1]) + rtu_u[tmp_0 -
        2]) + rtu_u[tmp_0 - 1]) / 4.0;
    }
  }
}

static void NoninplaceableSS1(void)
{
  Downsample(rtDWork.ComplextoRealImag_o1, rtDWork.z_e);
  Downsample(rtDWork.ComplextoRealImag_o2, rtDWork.z_g);
}

static void DeltaX(const real_T rtu_u[4096], real_T rty_z[4032])
{
  int32_T tmp;
  int32_T x;
  int32_T y;
  for (x = 0; x < 63; x++) {
    for (y = 0; y < 64; y++) {
      tmp = (y << 6) + x;
      rty_z[x + 63 * y] = fabs(rtu_u[tmp] - rtu_u[tmp + 1]);
    }
  }
}

static void NoninplaceableSS2(void)
{
  DeltaX(rtDWork.z_e, rtDWork.z_m);
  DeltaX(rtDWork.z_g, rtDWork.z_j);
}

static void DeltaY(const real_T rtu_u[4032], real_T rty_z[3969])
{
  int32_T i;
  for (i = 0; i < 3969; i++) {
    rty_z[i] = fabs(rtu_u[i] - rtu_u[i + 63]);
  }
}

static void NoninplaceableSS3(void)
{
  DeltaY(rtDWork.z_m, rtDWork.z_n);
  DeltaY(rtDWork.z_j, rtDWork.z);
}

void DifferentSizeReuse_step(void)
{
  int32_T i;
  for (i = 0; i < 16384; i++) {
    rtDWork.ComplextoRealImag_o1[i] = rtU.ComplexData[i].re;
    rtDWork.ComplextoRealImag_o2[i] = rtU.ComplexData[i].im;
  }

  NoninplaceableSS1();
  NoninplaceableSS2();
  NoninplaceableSS3();
  for (i = 0; i < 3969; i++) {
    rtY.Out1[i].re = rtDWork.z_n[i];
    rtY.Out1[i].im = rtDWork.z[i];
  }
}

D_work 構造体に、DownsampleDeltaX、および DeltaY の入力と出力を保持するために 8 つのグローバル変数が含まれています。これらの変数はサイズがそれぞれ異なります。

最適化を使用したコードの生成

  1. [コンフィギュレーション パラメーター] ダイアログ ボックスで、[信号ストレージの再利用] が選択されていることを確認します。

  2. [サイズと次元が異なるバッファーの再利用] パラメーターを on に設定するか、MATLAB コマンド ウィンドウで次のように入力します。

set_param('DifferentSizeReuse','DifferentSizesBufferReuse','on');

モデルをビルドします。

set_param('DifferentSizeReuse','GenerateComments','off');
slbuild(model);
### Searching for referenced models in model 'DifferentSizeReuse'.
### Total of 1 models to build.
### Starting build procedure for: DifferentSizeReuse
### Successful completion of build procedure for: DifferentSizeReuse

Build Summary

Top model targets:

Model               Build Reason                     Status                        Build Duration
=================================================================================================
DifferentSizeReuse  Generated code was out of date.  Code generated and compiled.  0h 0m 12.018s 

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 12.51s

最適化を行わない生成コードを表示します。D_Work 構造体は次のとおりです。

coder.example.extractLines(hfile,'typedef struct {','} D_Work',1,1);
typedef struct {
  real_T z[4096];
  real_T z_n[16384];
  real_T z_a[16384];
} D_Work;

DifferentSizeReuse.c の部分は次のとおりです。

cfile = fullfile('DifferentSizeReuse_ert_rtw',...
    'DifferentSizeReuse.c');
coder.example.extractLines(cfile,'#include "DifferentSizeReuse.h"',...
    'void DifferentSizeReuse_initialize(void)',1,0);
#include "DifferentSizeReuse.h"
#include "rtwtypes.h"
#include <math.h>

D_Work rtDWork;
ExternalInputs rtU;
ExternalOutputs rtY;
static RT_MODEL rtM_;
RT_MODEL *const rtM = &rtM_;
static void Downsample(const real_T rtu_u[16384], real_T rty_z[4096]);
static void DeltaX(const real_T rtu_u[4096], real_T rty_z[4032]);
static void DeltaY(const real_T rtu_u[4032], real_T rty_z[3969]);
static void NoninplaceableSS1(void);
static void NoninplaceableSS2(void);
static void NoninplaceableSS3(void);
static void Downsample(const real_T rtu_u[16384], real_T rty_z[4096])
{
  int32_T tmp;
  int32_T tmp_0;
  int32_T tmp_1;
  int32_T x;
  int32_T y;
  for (x = 0; x < 64; x++) {
    for (y = 0; y < 64; y++) {
      tmp_0 = (y + 1) << 1;
      tmp_1 = (x + 1) << 1;
      tmp = ((tmp_0 - 2) << 7) + tmp_1;
      tmp_0 = ((tmp_0 - 1) << 7) + tmp_1;
      rty_z[x + (y << 6)] = (((rtu_u[tmp - 2] + rtu_u[tmp - 1]) + rtu_u[tmp_0 -
        2]) + rtu_u[tmp_0 - 1]) / 4.0;
    }
  }
}

static void NoninplaceableSS1(void)
{
  Downsample(rtDWork.z_n, rtDWork.z);
  Downsample(rtDWork.z_a, &rtDWork.z_n[0]);
}

static void DeltaX(const real_T rtu_u[4096], real_T rty_z[4032])
{
  int32_T tmp;
  int32_T x;
  int32_T y;
  for (x = 0; x < 63; x++) {
    for (y = 0; y < 64; y++) {
      tmp = (y << 6) + x;
      rty_z[x + 63 * y] = fabs(rtu_u[tmp] - rtu_u[tmp + 1]);
    }
  }
}

static void NoninplaceableSS2(void)
{
  DeltaX(rtDWork.z, &rtDWork.z_a[0]);
  DeltaX(&rtDWork.z_n[0], &rtDWork.z[0]);
}

static void DeltaY(const real_T rtu_u[4032], real_T rty_z[3969])
{
  int32_T i;
  for (i = 0; i < 3969; i++) {
    rty_z[i] = fabs(rtu_u[i] - rtu_u[i + 63]);
  }
}

static void NoninplaceableSS3(void)
{
  DeltaY(&rtDWork.z_a[0], &rtDWork.z_n[0]);
  DeltaY(&rtDWork.z[0], &rtDWork.z_a[0]);
}

void DifferentSizeReuse_step(void)
{
  int32_T i;
  for (i = 0; i < 16384; i++) {
    rtDWork.z_n[i] = rtU.ComplexData[i].re;
    rtDWork.z_a[i] = rtU.ComplexData[i].im;
  }

  NoninplaceableSS1();
  NoninplaceableSS2();
  NoninplaceableSS3();
  for (i = 0; i < 3969; i++) {
    rtY.Out1[i].re = rtDWork.z_n[i];
    rtY.Out1[i].im = rtDWork.z_a[i];
  }
}

今回は、D_work 構造体に、DownsampleDeltaX、および DeltaY の入力と出力を保持するために 8 つのグローバル変数ではなく 3 つのグローバル変数が含まれています。生成コードでは、これらの変数を使用してサイズが異なる入力と出力が保持されます。

モデルを閉じます。

bdclose(model)

制限

  • Reusable カスタム ストレージ クラスを使用してサイズと形状が異なる信号に対して再利用を指定する場合、[サイズと次元が異なるバッファーの再利用] パラメーターをオンにする必要があります。それ以外の場合、モデルはビルドされません。

  • コード ジェネレーターは、バッファーを、サイズが小さい、優先順位の低いバッファーに置換しません。

  • コード ジェネレーターは、サイズとシンボリック次元が異なるバッファーを再利用しません。

参考

トピック