Main Content

Optimize Memory Usage for Time Counters

This example shows how to optimize the amount of memory that the code generator allocates for time counters. The example optimizes the memory that stores elapsed time, which is the time interval between two consecutive executions of a block.

The code generator represents timers for absolute and elapsed time as unsigned integers. In generated code, the word size is optimized. The code generator stores time counters as unsigned integers that have a word size of 8, 16,32, or 64 bits. In generated code, the word size automatically is set to the minimum size that can accommodate the largest number of clock ticks that the algorithm uses. The code generator uses settings of model configuration parameters Application lifespan (days) and Clock resolution (seconds, -1 for inherited) to compute the largest number of clock ticks. Application lifespan is the number of days an application that contains blocks or charts depending on elapsed or absolute time should be able to execute before a timer overflow occurs. Clock resolution is the smallest increment of a clock value in seconds. For details on how the code generator uses these parameters to compute the largest number of clock ticks that an algorithm uses, see Timer Data Types and Memory Allocation.

Open Example Model

Open the example model TimerMemoryOptimization.

open_system('TimerMemoryOptimization');

The model consists of subsystems SS1, SS2, and SS3 and is configured for the code generator to use the GRT system taraget file and a lifespan of inf days.

The three subsystems contain a discrete-time integrator that requires elapsed time as input to compute the output value. The subsystems vary as follows:

  • SS1 - Clocked at 1 kHz. Does not require a time counter. The Sample time type parameter for the trigger port is set to periodic. Elapsed time is inlined as 0.001.

  • SS2 - Clocked at 100 Hz. Requires a time counter. Based on a lifespan of 1 day, a 32-bit counter stores the elapsed time.

  • SS3 - Clocked at 0.5 Hz. Requires a time counter. Based on a lifespan of 1 day, a 16-bit counter stores the elapsed time.

Simulate the Model

Simulate the model. By default, the model is configured to show sample times in different colors. Discrete sample times for the three subsystems appear red, green, and blue. Triggered subsystems are highlighted with a light blue box.

Generate Code and Report

Generate code and a code generation report.

slbuild('TimerMemoryOptimization');
### Starting build procedure for: TimerMemoryOptimization
### Successful completion of build procedure for: TimerMemoryOptimization

Build Summary

Top model targets:

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

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

Review Generated Code

Open the generated source file TimerMemoryOptimization.h.

cfile = fullfile('TimerMemoryOptimization_grt_rtw', 'TimerMemoryOptimization.h');
coder.example.extractLines(cfile,'/* Real-time Model Data Structure */', '/* Block states (auto storage) */', 0, 1);
struct tag_RTM_TimerMemoryOptimizati_T {
  const char_T *errorStatus;

  /*
   * Timing:
   * The following substructure contains information regarding
   * the timing information for the model.
   */
  struct {
    uint32_T clockTick1;
    uint32_T clockTickH1;
    uint32_T clockTick2;
    uint32_T clockTickH2;
    struct {
      uint16_T TID[3];
      uint16_T cLimit[3];
    } TaskCounters;
  } Timing;
};

/* Block states (default storage) */
extern DW_TimerMemoryOptimization_T TimerMemoryOptimization_DW;

/* Zero-crossing (trigger) state */
extern PrevZCX_TimerMemoryOptimizati_T TimerMemoryOptimization_PrevZCX;

/* External inputs (root inport signals with default storage) */
extern ExtU_TimerMemoryOptimization_T TimerMemoryOptimization_U;

/* External outputs (root outports fed by signals with default storage) */
extern ExtY_TimerMemoryOptimization_T TimerMemoryOptimization_Y;

/* Model entry point functions */
extern void TimerMemoryOptimization_initialize(void);
extern void TimerMemoryOptimization_step0(void);/* Sample time: [0.001s, 0.0s] */
extern void TimerMemoryOptimization_step1(void);/* Sample time: [0.01s, 0.0s] */
extern void TimerMemoryOptimization_step2(void);/* Sample time: [2.0s, 0.0s] */
extern void TimerMemoryOptimization_terminate(void);

/* Real-time Model object */
extern RT_MODEL_TimerMemoryOptimizat_T *const TimerMemoryOptimization_M;

/*-
 * The generated code includes comments that allow you to trace directly
 * back to the appropriate location in the model.  The basic format
 * is <system>/block_name, where system is the system number (uniquely
 * assigned by Simulink) and block_name is the name of the block.
 *
 * Use the MATLAB hilite_system command to trace the generated code back
 * to the model.  For example,
 *
 * hilite_system('<S3>')    - opens system 3
 * hilite_system('<S3>/Kp') - opens and selects block Kp which resides in S3
 *
 * Here is the system hierarchy for this model
 *
 * '<Root>' : 'TimerMemoryOptimization'
 * '<S1>'   : 'TimerMemoryOptimization/SS1'
 * '<S2>'   : 'TimerMemoryOptimization/SS2'
 * '<S3>'   : 'TimerMemoryOptimization/SS3'
 */
#endif                                 /* TimerMemoryOptimization_h_ */

Four 32-bit unsigned integers, clockTick1 , clockTickH1 , clockTick2 , and clockTickH2 are counters for storing the elapsed time for subsystems SS2 and SS3.

Enable Optimization and Regenerate Code

1. Set model configuration parameter Application lifespan (days) (LifeSpan) to 1 day.

set_param('TimerMemoryOptimization', 'LifeSpan', '1');

2.Save the model and regenerate the code.

slbuild('TimerMemoryOptimization');
### Starting build procedure for: TimerMemoryOptimization
### Successful completion of build procedure for: TimerMemoryOptimization

Build Summary

Top model targets:

Model                    Build Reason                   Status                        Build Duration
====================================================================================================
TimerMemoryOptimization  Incremental checksum changed.  Code generated and compiled.  0h 0m 8.4292s 

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

Review Regenerated Code

cfile = fullfile('TimerMemoryOptimization_grt_rtw', 'TimerMemoryOptimization.h');
coder.example.extractLines(cfile,'/* Real-time Model Data Structure */', '/* Block states (auto storage) */', 0, 1);
struct tag_RTM_TimerMemoryOptimizati_T {
  const char_T *errorStatus;

  /*
   * Timing:
   * The following substructure contains information regarding
   * the timing information for the model.
   */
  struct {
    uint32_T clockTick1;
    uint16_T clockTick2;
    struct {
      uint16_T TID[3];
      uint16_T cLimit[3];
    } TaskCounters;
  } Timing;
};

/* Block states (default storage) */
extern DW_TimerMemoryOptimization_T TimerMemoryOptimization_DW;

/* Zero-crossing (trigger) state */
extern PrevZCX_TimerMemoryOptimizati_T TimerMemoryOptimization_PrevZCX;

/* External inputs (root inport signals with default storage) */
extern ExtU_TimerMemoryOptimization_T TimerMemoryOptimization_U;

/* External outputs (root outports fed by signals with default storage) */
extern ExtY_TimerMemoryOptimization_T TimerMemoryOptimization_Y;

/* Model entry point functions */
extern void TimerMemoryOptimization_initialize(void);
extern void TimerMemoryOptimization_step0(void);/* Sample time: [0.001s, 0.0s] */
extern void TimerMemoryOptimization_step1(void);/* Sample time: [0.01s, 0.0s] */
extern void TimerMemoryOptimization_step2(void);/* Sample time: [2.0s, 0.0s] */
extern void TimerMemoryOptimization_terminate(void);

/* Real-time Model object */
extern RT_MODEL_TimerMemoryOptimizat_T *const TimerMemoryOptimization_M;

/*-
 * The generated code includes comments that allow you to trace directly
 * back to the appropriate location in the model.  The basic format
 * is <system>/block_name, where system is the system number (uniquely
 * assigned by Simulink) and block_name is the name of the block.
 *
 * Use the MATLAB hilite_system command to trace the generated code back
 * to the model.  For example,
 *
 * hilite_system('<S3>')    - opens system 3
 * hilite_system('<S3>/Kp') - opens and selects block Kp which resides in S3
 *
 * Here is the system hierarchy for this model
 *
 * '<Root>' : 'TimerMemoryOptimization'
 * '<S1>'   : 'TimerMemoryOptimization/SS1'
 * '<S2>'   : 'TimerMemoryOptimization/SS2'
 * '<S3>'   : 'TimerMemoryOptimization/SS3'
 */
#endif                                 /* TimerMemoryOptimization_h_ */

The new setting for the Application lifespan (days) parameter instructs the code generator to set aside less memory for the time counters. The regenerated code includes:

  • 32-bit unsigned integer, clockTick1, for computing and storing the elapsed time of the task for SS2

  • 16-bit unsigned integer, clockTick2, for computing and storing the elapsed time of the task for SS3

Related Topics