Reuse Buffers of Different Sizes and Dimensions
You can reuse buffers for matrices that have different sizes and shapes. In the Configuration Parameters dialog box, you enable this optimization by selecting Reuse buffers of different sizes and dimensions. This optimization conserves RAM and ROM usage and improves code execution speed.
Example Model
The model DifferentSizeReuse
contains signals of different sizes and dimensions.
model='DifferentSizeReuse';
open_system(model);
Generate Code Without Optimization
In the Configuration Parameters dialog box, set Reuse buffers of different sizes and dimension parameter to off
or in the MATLAB® Command Window, enter:
set_param('DifferentSizeReuse','DifferentSizesBufferReuse','off');
Turn off comments and build the model.
set_param('DifferentSizeReuse','GenerateComments','off'); slbuild('DifferentSizeReuse');
### 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 17.595s 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 18.22s
View the generated code without the optimization. The D_Work
structure is:
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;
The portion of DifferentSizeReuse.c
is:
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]; } }
The D_work
structure contains eight global variables for holding the inputs and outputs of Downsample
, DeltaX
, and DeltaY
. These variables have different sizes.
Generate Code with Optimization
In the Configuration Parameters dialog box, verify that Signal storage reuse is selected.
Set the Reuse buffers of different sizes and dimensions parameter to
on
or in the MATLAB Command Window, enter:
set_param('DifferentSizeReuse','DifferentSizesBufferReuse','on');
Build the model.
set_param('DifferentSizeReuse','GenerateComments','off'); slbuild(model);
### 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.295s 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 13.209s
View the generated code without the optimization. The D_Work
structure is:
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;
The portion of DifferentSizeReuse.c
is:
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]; } }
The D_work
structure now contains three global variables instead of eight global variables for holding the inputs and outputs of Downsample
, DeltaX
, and DeltaY
. The generated code uses these variables to hold the differently-sized inputs and outputs.
Close the model.
bdclose(model)
Limitations
If you use a
Reusable
custom storage class to specify reuse on signals that have different sizes and shapes, you must select the Reuse buffers of different sizes and dimensions parameter. Otherwise, the model does not build.The code generator does not replace a buffer with a lower priority buffer that has a smaller size.
The code generator does not reuse buffers that have different sizes and symbolic dimensions.
See Also
Reuse buffers of different sizes and dimensions