Lucas De Marchi
9 years ago
4 changed files with 0 additions and 329 deletions
@ -1,214 +0,0 @@
@@ -1,214 +0,0 @@
|
||||
#include "AP_PerfMon.h" |
||||
|
||||
extern const AP_HAL::HAL& hal; |
||||
|
||||
// static class variable definitions
|
||||
uint8_t AP_PerfMon::nextFuncNum; |
||||
char AP_PerfMon::functionNames[PERFMON_MAX_FUNCTIONS][PERFMON_FUNCTION_NAME_LENGTH]; |
||||
uint32_t AP_PerfMon::time[PERFMON_MAX_FUNCTIONS]; |
||||
uint32_t AP_PerfMon::maxTime[PERFMON_MAX_FUNCTIONS]; |
||||
uint32_t AP_PerfMon::numCalls[PERFMON_MAX_FUNCTIONS]; |
||||
uint32_t AP_PerfMon::allStartTime; |
||||
uint32_t AP_PerfMon::allEndTime; |
||||
AP_PerfMon* AP_PerfMon::lastCreated = NULL; |
||||
bool AP_PerfMon::_enabled = true; |
||||
|
||||
// constructor
|
||||
AP_PerfMon::AP_PerfMon(uint8_t funcNum) : _funcNum(funcNum), _time_this_iteration(0) |
||||
{ |
||||
// exit immediately if we are disabled
|
||||
if( !_enabled ) { |
||||
return; |
||||
} |
||||
|
||||
// check global start time
|
||||
if( allStartTime == 0 ) { |
||||
allStartTime = AP_HAL::micros(); |
||||
} |
||||
|
||||
// stop recording time from parent
|
||||
_parent = lastCreated; // add pointer to parent
|
||||
if( _parent != NULL ) { |
||||
_parent->stop(); |
||||
} |
||||
|
||||
// record myself as the last created instance
|
||||
lastCreated = this; |
||||
|
||||
numCalls[_funcNum]++; // record that this function has been called
|
||||
start(); // start recording time spent in this function
|
||||
} |
||||
|
||||
// destructor
|
||||
AP_PerfMon::~AP_PerfMon() |
||||
{ |
||||
// exit immediately if we are disabled
|
||||
if( !_enabled ) { |
||||
return; |
||||
} |
||||
|
||||
stop(); // stop recording time spent in this function
|
||||
lastCreated = _parent; // make my parent the last created instance
|
||||
|
||||
// calculate max time spent in this function
|
||||
if( _time_this_iteration > maxTime[_funcNum] ) { |
||||
maxTime[_funcNum] = _time_this_iteration; |
||||
} |
||||
|
||||
// restart recording time for parent
|
||||
if( _parent != NULL ) |
||||
_parent->start(); |
||||
} |
||||
|
||||
// record function name in static list
|
||||
uint8_t AP_PerfMon::recordFunctionName(const char funcName[]) |
||||
{ |
||||
uint8_t nextNum = nextFuncNum++; |
||||
uint8_t i; |
||||
|
||||
// clear existing function name (if any)
|
||||
functionNames[nextNum][0] = 0; |
||||
|
||||
// store function name
|
||||
for( i=0; i<PERFMON_FUNCTION_NAME_LENGTH-1 && funcName[i] != 0; i++ ) { |
||||
functionNames[nextNum][i] = funcName[i]; |
||||
} |
||||
functionNames[nextNum][i] = 0; |
||||
|
||||
return nextNum; |
||||
} |
||||
|
||||
// stop recording time
|
||||
void AP_PerfMon::start() |
||||
{ |
||||
_startTime = AP_HAL::micros(); // start recording time spent in this function
|
||||
} |
||||
|
||||
// stop recording time
|
||||
void AP_PerfMon::stop() |
||||
{ |
||||
uint32_t temp_time = AP_HAL::micros()-_startTime; |
||||
_time_this_iteration += temp_time; |
||||
time[_funcNum] += temp_time; |
||||
} |
||||
|
||||
// ClearAll - clears all data from static members
|
||||
void AP_PerfMon::ClearAll() |
||||
{ |
||||
uint8_t i; |
||||
AP_PerfMon *p = lastCreated; |
||||
|
||||
for(i=0; i<PERFMON_MAX_FUNCTIONS; i++) { |
||||
time[i] = 0; // reset times
|
||||
numCalls[i] = 0; // reset num times called
|
||||
maxTime[i] = 0; // reset maximum time
|
||||
} |
||||
|
||||
// reset start time to now
|
||||
allStartTime = AP_HAL::micros(); |
||||
allEndTime = 0; |
||||
|
||||
// reset start times of any active counters
|
||||
while( p != NULL ) { |
||||
p->_startTime = allStartTime; |
||||
p = p->_parent; |
||||
} |
||||
} |
||||
|
||||
// DisplayResults - displays table of timing results
|
||||
void AP_PerfMon::DisplayResults() |
||||
{ |
||||
uint8_t i,j,changed; |
||||
float hz; |
||||
float pct; |
||||
uint32_t totalTime; |
||||
uint32_t avgTime; |
||||
uint32_t sumOfTime = 0; |
||||
uint32_t unExplainedTime; |
||||
uint8_t order[PERFMON_MAX_FUNCTIONS]; |
||||
|
||||
// record end time
|
||||
if( allEndTime == 0 ) { |
||||
allEndTime = AP_HAL::micros(); |
||||
} |
||||
|
||||
// turn off any time recording
|
||||
if( lastCreated != NULL ) { |
||||
lastCreated->stop(); |
||||
} |
||||
_enabled = false; |
||||
|
||||
// reorder results
|
||||
for(i=0; i<nextFuncNum; i++) { |
||||
order[i] = i; |
||||
} |
||||
changed=0; |
||||
do{ |
||||
changed = 0; |
||||
for(i=0; i<nextFuncNum-1; i++) |
||||
if(time[order[i]]<time[order[i+1]]) { |
||||
j = order[i]; |
||||
order[i] = order[i+1]; |
||||
order[i+1] = j; |
||||
changed = 1; |
||||
} |
||||
}while(changed != 0); |
||||
|
||||
// calculate time elapsed
|
||||
totalTime = allEndTime - allStartTime; |
||||
|
||||
// ensure serial is blocking
|
||||
hal.console->set_blocking_writes(true); |
||||
|
||||
// print table of results
|
||||
hal.console->printf("\nPerfMon elapsed:%lu(ms)\n",(unsigned long)totalTime/1000); |
||||
hal.console->printf("Fn:\t\tcpu\ttot(ms)\tavg(ms)\tmax(ms)\t#calls\tHz\n"); |
||||
for( i=0; i<nextFuncNum; i++ ) { |
||||
j=order[i]; |
||||
sumOfTime += time[j]; |
||||
|
||||
// calculate average execution time
|
||||
if( numCalls[j] > 0 ) { |
||||
avgTime = time[j] / numCalls[j]; |
||||
}else{ |
||||
avgTime = 0; |
||||
} |
||||
|
||||
hz = numCalls[j]/(totalTime/1000000); |
||||
pct = ((float)time[j] / (float)totalTime) * 100.0f; |
||||
hal.console->printf("%-10s\t%4.2f\t%lu\t%4.3f\t%4.3f\t%lu\t%4.1f\n", |
||||
functionNames[j], |
||||
pct, |
||||
(unsigned long)time[j]/1000, |
||||
(float)avgTime/1000.0f, |
||||
(float)maxTime[j]/1000.0f, |
||||
numCalls[j], |
||||
hz); |
||||
} |
||||
// display unexplained time
|
||||
if( sumOfTime >= totalTime ) { |
||||
unExplainedTime = 0; |
||||
} else { |
||||
unExplainedTime = totalTime - sumOfTime; |
||||
} |
||||
pct = ((float)unExplainedTime / (float)totalTime) * 100.0f; |
||||
hal.console->printf("unexpl:\t\t%4.2f\t%lu\n",pct,(unsigned long)unExplainedTime/1000); |
||||
|
||||
// restore to blocking writes if necessary
|
||||
hal.console->set_blocking_writes(false); |
||||
|
||||
// turn back on any time recording
|
||||
if( lastCreated != NULL ) { |
||||
lastCreated->start(); |
||||
} |
||||
_enabled = true; |
||||
} |
||||
|
||||
// DisplayAndClear - will display results after this many milliseconds. should be called regularly
|
||||
void AP_PerfMon::DisplayAndClear(uint32_t display_after_seconds) |
||||
{ |
||||
if( (AP_HAL::micros() - allStartTime) > (uint32_t)(display_after_seconds * 1000000) ) { |
||||
DisplayResults(); |
||||
ClearAll(); |
||||
} |
||||
} |
@ -1,52 +0,0 @@
@@ -1,52 +0,0 @@
|
||||
#ifndef AP_PERFMON_H |
||||
#define AP_PERFMON_H |
||||
|
||||
// macros to make integrating into code easier
|
||||
#define AP_PERFMON_REGISTER static uint8_t myFunc = AP_PerfMon::recordFunctionName(__func__); AP_PerfMon perfMon(myFunc); |
||||
#define AP_PERFMON_REGISTER_NAME(functionName) static uint8_t myFunc = AP_PerfMon::recordFunctionName(functionName); AP_PerfMon perfMon(myFunc); |
||||
|
||||
#define AP_PERFMON_REGISTER_FN(func_name) static uint8_t func_name ## _num = AP_PerfMon::recordFunctionName(#func_name); |
||||
#define AP_PERFMON_FUNCTION(func_name) AP_PerfMon perfMon(func_name ## _num); |
||||
|
||||
|
||||
#define PERFMON_MAX_FUNCTIONS 12 |
||||
#define PERFMON_FUNCTION_NAME_LENGTH 10 |
||||
|
||||
#include <AP_HAL/AP_HAL.h> |
||||
#include <AP_Math/AP_Math.h> |
||||
|
||||
class AP_PerfMon |
||||
{ |
||||
public: |
||||
// static methods
|
||||
static uint8_t recordFunctionName(const char funcName[]); |
||||
static void DisplayResults(); |
||||
static void ClearAll(); |
||||
static void DisplayAndClear(uint32_t display_after_seconds); // will display results after this many milliseconds. should be called regularly
|
||||
|
||||
// public methods
|
||||
AP_PerfMon(uint8_t funcNum); // Constructor - records function start time
|
||||
~AP_PerfMon(); // Destructor - records function end time
|
||||
void stop(); // stops recording time spent in this function - meant to be called by a child.
|
||||
void start(); // restarts recording time spent in this function
|
||||
|
||||
private: |
||||
// static variables
|
||||
static uint8_t nextFuncNum; |
||||
static char functionNames[PERFMON_MAX_FUNCTIONS][PERFMON_FUNCTION_NAME_LENGTH]; |
||||
static uint32_t time[PERFMON_MAX_FUNCTIONS]; |
||||
static uint32_t numCalls[PERFMON_MAX_FUNCTIONS]; |
||||
static uint32_t maxTime[PERFMON_MAX_FUNCTIONS]; |
||||
static uint32_t allStartTime; |
||||
static uint32_t allEndTime; |
||||
static AP_PerfMon* lastCreated; |
||||
static bool _enabled; |
||||
|
||||
// instance variables
|
||||
uint8_t _funcNum; |
||||
unsigned long _startTime; |
||||
unsigned long _time_this_iteration; |
||||
AP_PerfMon* _parent; |
||||
}; |
||||
|
||||
#endif // AP_PERFMON_H
|
@ -1,58 +0,0 @@
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
AP_PerfMon |
||||
Code by Randy Mackay |
||||
*/ |
||||
|
||||
#include <AP_Common/AP_Common.h> |
||||
#include <AP_Param/AP_Param.h> |
||||
#include <AP_Math/AP_Math.h> |
||||
#include <AP_HAL/AP_HAL.h> |
||||
#include <StorageManager/StorageManager.h> |
||||
#include <AP_PerfMon/AP_PerfMon.h> // PerfMonitor library |
||||
|
||||
const AP_HAL::HAL& hal = AP_HAL::get_HAL(); |
||||
|
||||
AP_PERFMON_REGISTER_FN(setup) |
||||
AP_PERFMON_REGISTER_FN(loop) |
||||
AP_PERFMON_REGISTER_FN(testFn) |
||||
AP_PERFMON_REGISTER_FN(testFn2) |
||||
|
||||
void setup() |
||||
{ |
||||
AP_PERFMON_FUNCTION(setup) |
||||
|
||||
hal.console->print("Performance Monitor test v1.1\n"); |
||||
} |
||||
|
||||
void loop() |
||||
{ |
||||
AP_PERFMON_FUNCTION(loop) |
||||
|
||||
int16_t i = 0; |
||||
|
||||
for( i=0; i<10; i++ ) { |
||||
testFn(); |
||||
} |
||||
|
||||
AP_PerfMon::DisplayAndClear(5); |
||||
//AP_PerfMon::DisplayResults();
|
||||
//AP_PerfMon::ClearAll();
|
||||
|
||||
hal.scheduler->delay(2000); |
||||
} |
||||
|
||||
void testFn() |
||||
{ |
||||
AP_PERFMON_FUNCTION(testFn) |
||||
hal.scheduler->delay(10); |
||||
testFn2(); |
||||
hal.scheduler->delay(10); |
||||
} |
||||
|
||||
void testFn2() |
||||
{ |
||||
AP_PERFMON_FUNCTION(testFn2) |
||||
hal.scheduler->delay(10); |
||||
} |
||||
|
||||
AP_HAL_MAIN(); |
Loading…
Reference in new issue