improve measurement accuracy

This commit is contained in:
Gabriel Wang 2022-07-06 22:43:39 +01:00
parent 90582a70f6
commit c63de7741d
5 changed files with 68 additions and 73 deletions

Binary file not shown.

View File

@ -37,7 +37,7 @@ extern "C" {
#define __PERF_COUNTER_VER_MINOR__ 9
#define __PERF_COUNTER_VER_REVISE__ 7
#define __PERF_COUNTER_VER_STR__ "dev"
#define __PERF_COUNTER_VER_STR__ "rel"
#define __PER_COUNTER_VER__ (__PERF_COUNTER_VER_MAJOR__ * 10000ul \
+__PERF_COUNTER_VER_MINOR__ * 100ul \
@ -301,7 +301,7 @@ __super_loop_monitor__()
#define __cycleof__(__STR, ...) \
using(int64_t _ = get_system_ticks(), __cycle_count__ = _, \
_=_, { \
_ = get_system_ticks() - _; \
_ = get_system_ticks() - _ - g_nOffset; \
__cycle_count__ = _; \
if (__PLOOC_VA_NUM_ARGS(__VA_ARGS__) == 0) { \
__perf_counter_printf__("\r\n"); \
@ -333,7 +333,7 @@ __super_loop_monitor__()
for(start_task_cycle_counter();; ({ \
if (!(--SAFE_NAME(cnt))) { \
__cpu_usage__.lTimeElapsed \
= get_system_ticks() - __cpu_usage__.lStart; \
= get_system_ticks() - __cpu_usage__.lStart - g_nOffset; \
__cpu_usage__.lTaskUsedCycles = stop_task_cycle_counter(); \
\
if (__PLOOC_VA_NUM_ARGS(__VA_ARGS__) == 0) { \
@ -371,6 +371,8 @@ struct task_cycle_info_agent_t {
/*! @} */
/*============================ GLOBAL VARIABLES ==============================*/
extern volatile int64_t g_lLastTimeStamp;
extern volatile int32_t g_nOffset;
/*============================ LOCAL VARIABLES ===============================*/
/*============================ PROTOTYPES ====================================*/
@ -380,21 +382,42 @@ struct task_cycle_info_agent_t {
* @{
*/
/*!
* \brief get the elapsed cycles since perf_counter is initialised
* \return int64_t the elpased cycles
*/
__attribute__((noinline))
extern int64_t get_system_ticks(void);
/*!
* \brief get the elapsed milliseconds since perf_counter is initialised
* \return int32_t the elapsed milliseconds
*/
extern int32_t get_system_ms(void);
/*!
* \brief try to set a start pointer for the performance counter
* \retval false the LOAD register is too small
* \retval true performance counter starts
*/
__attribute__((noinline))
extern bool start_cycle_counter(void);
__STATIC_INLINE
void start_cycle_counter(void)
{
g_lLastTimeStamp = get_system_ticks();
}
/*!
* \brief calculate the elapsed cycle count since the last start point
* \note you can have multiple stop_cycle_counter following one start point
* \return int32_t the elapsed cycle count
*/
__attribute__((noinline))
extern int32_t stop_cycle_counter(void);
__STATIC_INLINE
int32_t stop_cycle_counter(void)
{
int32_t nTemp = (int32_t)(get_system_ticks() - g_lLastTimeStamp);
return nTemp - g_nOffset;
}
/*!
* \brief delay specified time in microsecond
@ -437,18 +460,7 @@ __attribute__((noinline))
extern int64_t clock(void);
#endif
/*!
* \brief get the elapsed cycles since perf_counter is initialised
* \return int64_t the elpased cycles
*/
__attribute__((noinline))
extern int64_t get_system_ticks(void);
/*!
* \brief get the elapsed milliseconds since perf_counter is initialised
* \return int32_t the elapsed milliseconds
*/
extern int32_t get_system_ms(void);
/*! @} */

Binary file not shown.

View File

@ -158,8 +158,8 @@ struct __task_cycle_info_t {
extern uint32_t SystemCoreClock;
/*============================ LOCAL VARIABLES ===============================*/
volatile static int32_t s_nCycleCounts = 0;
volatile static int32_t s_nOffset = 0;
volatile int64_t g_lLastTimeStamp = 0;
volatile int32_t g_nOffset = 0;
volatile static int32_t s_nUSUnit = 1;
volatile static int32_t s_nMSUnit = 1;
volatile static int32_t s_nMSResidule = 0;
@ -196,7 +196,6 @@ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
void user_code_insert_to_systick_handler(void)
{
uint32_t wLoad = SysTick->LOAD + 1;
s_nCycleCounts += wLoad;
s_lSystemClockCounts += wLoad;
// update system ms counter
@ -204,7 +203,6 @@ void user_code_insert_to_systick_handler(void)
int32_t nMS = s_nMSResidule / s_nMSUnit;
s_nMSResidule -= nMS * s_nMSUnit;
s_nSystemMS += nMS;
}
__WEAK
@ -227,12 +225,11 @@ void init_cycle_counter(bool bIsSysTickOccupied)
SysTick_Config(0x01000000); // use the longest period
}
SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk;
g_lLastTimeStamp = get_system_ticks();
g_nOffset = get_system_ticks() - g_lLastTimeStamp;
}
start_cycle_counter();
//s_nSystemClockCounts = s_nCycleCounts;
s_nOffset = stop_cycle_counter();
update_perf_counter();
s_lSystemClockCounts = 0; // reset system cycle counter
s_nSystemMS = 0; // reset system millisecond counter
@ -248,20 +245,6 @@ void init_cycle_counter(bool bIsSysTickOccupied)
__perf_os_patch_init();
}
__attribute__((noinline))
bool start_cycle_counter(void)
{
if (SysTick->LOAD < PERF_CNT_COMPENSATION_THRESHOLD) {
return false;
}
__IRQ_SAFE {
s_nCycleCounts = (int32_t)SysTick->VAL - (int32_t)SysTick->LOAD;
}
return true;
}
/*! \note this function should only be called when irq is disabled
* hence SysTick-LOAD and (SCB->ICSR & SCB_ICSR_PENDSTSET_Msk)
* won't change.
@ -299,18 +282,6 @@ __STATIC_INLINE int32_t check_systick(void)
return nTemp;
}
__attribute__((noinline))
int32_t stop_cycle_counter(void)
{
int32_t nTemp = 0;
__IRQ_SAFE {
nTemp = check_systick() + s_nCycleCounts;
}
return nTemp - s_nOffset;
}
#if defined(__IS_COMPILER_IAR__)
__attribute__((constructor))
#else
@ -583,7 +554,7 @@ void __on_context_switch_in(uint32_t *pwStack)
void __on_context_switch_out(uint32_t *pwStack)
{
struct __task_cycle_info_t *ptRootAgent = (struct __task_cycle_info_t *)pwStack;
int64_t lCycleUsed = get_system_ticks() - ptRootAgent->lLastTimeStamp;
int64_t lCycleUsed = get_system_ticks() - ptRootAgent->lLastTimeStamp - g_nOffset;
ptRootAgent->tInfo.nUsedRecent = lCycleUsed;
ptRootAgent->tInfo.lUsedTotal += lCycleUsed;
@ -635,7 +606,7 @@ int64_t __stop_task_cycle_counter(task_cycle_info_t *ptInfo)
int64_t lCycles = 0;
__IRQ_SAFE {
int64_t lCycleUsed = get_system_ticks() - ptRootAgent->lLastTimeStamp;
int64_t lCycleUsed = get_system_ticks() - ptRootAgent->lLastTimeStamp - g_nOffset;
ptRootAgent->tInfo.lUsedTotal += lCycleUsed;
if (NULL != ptInfo) {

View File

@ -37,7 +37,7 @@ extern "C" {
#define __PERF_COUNTER_VER_MINOR__ 9
#define __PERF_COUNTER_VER_REVISE__ 7
#define __PERF_COUNTER_VER_STR__ "dev"
#define __PERF_COUNTER_VER_STR__ "rel"
#define __PER_COUNTER_VER__ (__PERF_COUNTER_VER_MAJOR__ * 10000ul \
+__PERF_COUNTER_VER_MINOR__ * 100ul \
@ -301,7 +301,7 @@ __super_loop_monitor__()
#define __cycleof__(__STR, ...) \
using(int64_t _ = get_system_ticks(), __cycle_count__ = _, \
_=_, { \
_ = get_system_ticks() - _; \
_ = get_system_ticks() - _ - g_nOffset; \
__cycle_count__ = _; \
if (__PLOOC_VA_NUM_ARGS(__VA_ARGS__) == 0) { \
__perf_counter_printf__("\r\n"); \
@ -333,7 +333,7 @@ __super_loop_monitor__()
for(start_task_cycle_counter();; ({ \
if (!(--SAFE_NAME(cnt))) { \
__cpu_usage__.lTimeElapsed \
= get_system_ticks() - __cpu_usage__.lStart; \
= get_system_ticks() - __cpu_usage__.lStart - g_nOffset; \
__cpu_usage__.lTaskUsedCycles = stop_task_cycle_counter(); \
\
if (__PLOOC_VA_NUM_ARGS(__VA_ARGS__) == 0) { \
@ -371,6 +371,8 @@ struct task_cycle_info_agent_t {
/*! @} */
/*============================ GLOBAL VARIABLES ==============================*/
extern volatile int64_t g_lLastTimeStamp;
extern volatile int32_t g_nOffset;
/*============================ LOCAL VARIABLES ===============================*/
/*============================ PROTOTYPES ====================================*/
@ -380,21 +382,42 @@ struct task_cycle_info_agent_t {
* @{
*/
/*!
* \brief get the elapsed cycles since perf_counter is initialised
* \return int64_t the elpased cycles
*/
__attribute__((noinline))
extern int64_t get_system_ticks(void);
/*!
* \brief get the elapsed milliseconds since perf_counter is initialised
* \return int32_t the elapsed milliseconds
*/
extern int32_t get_system_ms(void);
/*!
* \brief try to set a start pointer for the performance counter
* \retval false the LOAD register is too small
* \retval true performance counter starts
*/
__attribute__((noinline))
extern bool start_cycle_counter(void);
__STATIC_INLINE
void start_cycle_counter(void)
{
g_lLastTimeStamp = get_system_ticks();
}
/*!
* \brief calculate the elapsed cycle count since the last start point
* \note you can have multiple stop_cycle_counter following one start point
* \return int32_t the elapsed cycle count
*/
__attribute__((noinline))
extern int32_t stop_cycle_counter(void);
__STATIC_INLINE
int32_t stop_cycle_counter(void)
{
int32_t nTemp = (int32_t)(get_system_ticks() - g_lLastTimeStamp);
return nTemp - g_nOffset;
}
/*!
* \brief delay specified time in microsecond
@ -437,18 +460,7 @@ __attribute__((noinline))
extern int64_t clock(void);
#endif
/*!
* \brief get the elapsed cycles since perf_counter is initialised
* \return int64_t the elpased cycles
*/
__attribute__((noinline))
extern int64_t get_system_ticks(void);
/*!
* \brief get the elapsed milliseconds since perf_counter is initialised
* \return int32_t the elapsed milliseconds
*/
extern int32_t get_system_ms(void);
/*! @} */