Performance monitoring

In this section, we will build upon the previous example and add features that allow monitoring the performance of the MARTe2 application, namely the timing of the GAMs and of the thread cycle time.

We want to monitor:

  • The cycle time of the thread executing the GAMs. This is the time between two consecutive executions of the thread. It is expected to be constant and equal to the inverse of the Frequency parameter of the GAMTimer.

  • The execution time of the GAMs. This is the time taken by the GAMs to execute their logic.

  • The time it takes to copy from the DataSource to the GAMs. This includes any overhead of the DataSource (e.g. to access the hardware) and the time taken to copy the data from the DataSource to the GAMs.

  • The time it takes to copy from the GAMs to the DataSources. This includes any overhead of the DataSource (e.g. to access the hardware) and the time taken to copy the data from the GAMs to the DataSources.

All the times are absolute with respect to the start of the real-time cycle and are measured in microseconds.

Mass-spring-damper timings.

Timing diagram for the mass-spring-damper system.

Note

The GAM that synchronises with the DataSource pacing the thread waits during its read phase for the trigger to arrive. Consequently, this provides an indirect measurement of the thread’s available free time (the higher, the better).

Note

The cycle time is measured between the end of two consecutive cycles, rather than between the thread’s synchronisation points (i.e. when the LinuxTimer is triggered). While this is typically not an issue, if the GAM load varies over time it may result in a cycle time that appears non-constant, even when the synchronisation trigger is very stable.

Note

Since the measurements are taken during the cycle, the execution order of the GAM that reads from the Timing DataSource determines whether the reported times for other GAMs correspond to the current or the previous cycle. If the Timing GAM executes before the others, the reported times will refer to the previous cycle, but will remain consistent across all GAMs.

Updated configuration with the two missing GAMs.
1                +Thread1 = {
2                    Class = RealTimeThread
3                    CPUs = 0x1
4                    Functions = {GAMPerfMonitor GAMTimer GAMReference GAMController GAMSpringMass GAMDisplay}
5                }

Running the application

Start the application with:

./MARTeApp.sh -f ../Configurations/MassSpring/RTApp-MassSpring-3.cfg -l RealTimeLoader -s State1

Once the application is running, inspect the screen output and verify that the log shows the cycle time and the execution times of the GAMs. The log should show entries similar to the following:

$ [Information - LoggerBroker.cpp:152]: Thread1CycleTime [0:0]:9992
$ [Information - LoggerBroker.cpp:152]: GAMTimer_ReadTime [0:0]:9878
$ [Information - LoggerBroker.cpp:152]: GAMTimer_ExecTime [0:0]:9878
$ [Information - LoggerBroker.cpp:152]: GAMTimer_WriteTime [0:0]:9878
$ [Information - LoggerBroker.cpp:152]: GAMReference_ExecTime [0:0]:9879
$ [Information - LoggerBroker.cpp:152]: GAMReference_WriteTime [0:0]:9879
$ [Information - LoggerBroker.cpp:152]: GAMController_ReadTime [0:0]:9879
$ [Information - LoggerBroker.cpp:152]: GAMController_ExecTime [0:0]:9879
$ [Information - LoggerBroker.cpp:152]: GAMController_WriteTime [0:0]:9879
$ [Information - LoggerBroker.cpp:152]: GAMDisplay_ReadTime [0:0]:9896
$ [Information - LoggerBroker.cpp:152]: GAMDisplay_ExecTime [0:0]:9897
$ [Information - LoggerBroker.cpp:152]: GAMDisplay_WriteTime [0:0]:9991
...

Exercises

Ex. 1: Add the missing times

  1. Edit the file ../Configurations/MassSpring/RTApp-MassSpring-4.cfg and add the Read, Exec, and Write times for the two missing GAMs.

  2. Verify that the two missing times are now present in the logger output.

./MARTeApp.sh -f ../Configurations/MassSpring/RTApp-MassSpring-4.cfg -l RealTimeLoader -s State1
Solution

The solution is to add the missing signals in the GAMPerMonitor and GAMDisplay.

Updated configuration with the two missing GAMs.
  1        +GAMPerfMonitor = {
  2            Class = IOGAM            
  3            InputSignals = {
  4                GAMSpringMass_ReadTime = {
  5                    DataSource = Timings
  6                    Type = uint32
  7                }
  8                GAMSpringMass_ExecTime = {
  9                    DataSource = Timings
 10                    Type = uint32
 11                }
 12                GAMSpringMass_WriteTime = {
 13                    DataSource = Timings
 14                    Type = uint32
 15                }
 16                GAMPerfMonitor_ReadTime = {
 17                    DataSource = Timings
 18                    Type = uint32
 19                }
 20                GAMPerfMonitor_ExecTime = {
 21                    DataSource = Timings
 22                    Type = uint32
 23                }
 24                GAMPerfMonitor_WriteTime = {
 25                    DataSource = Timings
 26                    Type = uint32
 27                }
 28            OutputSignals = {
 29                GAMSpringMass_ReadTime = {
 30                    DataSource = DDB1
 31                    Type = uint32
 32                }
 33                GAMSpringMass_ExecTime = {
 34                    DataSource = DDB1
 35                    Type = uint32
 36                }
 37                GAMSpringMass_WriteTime = {
 38                    DataSource = DDB1
 39                    Type = uint32
 40                }
 41                GAMPerfMonitor_ReadTime = {
 42                    DataSource = DDB1
 43                    Type = uint32
 44                }
 45                GAMPerfMonitor_ExecTime = {
 46                    DataSource = DDB1
 47                    Type = uint32
 48                }
 49                GAMPerfMonitor_WriteTime = {
 50                    DataSource = DDB1
 51                    Type = uint32
 52                }
 53        +GAMDisplay = {
 54            Class = IOGAM            
 55            InputSignals = {
 56                GAMSpringMass_ReadTime = {
 57                    DataSource = DDB1
 58                    Type = uint32
 59                }
 60                GAMSpringMass_ExecTime = {
 61                    DataSource = DDB1
 62                    Type = uint32
 63                }
 64                GAMSpringMass_WriteTime = {
 65                    DataSource = DDB1
 66                    Type = uint32
 67                }
 68                GAMPerfMonitor_ReadTime = {
 69                    DataSource = DDB1
 70                    Type = uint32
 71                }
 72                GAMPerfMonitor_ExecTime = {
 73                    DataSource = DDB1
 74                    Type = uint32
 75                }
 76                GAMPerfMonitor_WriteTime = {
 77                    DataSource = DDB1
 78                    Type = uint32
 79                }
 80            OutputSignals = {
 81                GAMSpringMass_ReadTime = {
 82                    DataSource = Display
 83                    Type = uint32
 84                }
 85                GAMSpringMass_ExecTime = {
 86                    DataSource = Display
 87                    Type = uint32
 88                }
 89                GAMSpringMass_WriteTime = {
 90                    DataSource = Display
 91                    Type = uint32
 92                }
 93                GAMPerfMonitor_ReadTime = {
 94                    DataSource = Display
 95                    Type = uint32
 96                }
 97                GAMPerfMonitor_ExecTime = {
 98                    DataSource = Display
 99                    Type = uint32
100                }
101                GAMPerfMonitor_WriteTime = {
102                    DataSource = Display
103                    Type = uint32
104                }