Measuring CPU Usage

ChibiOS public support forum for all topics not covered by a specific support forum.

Moderators: RoccoMarco, lbednarz, tfAteba

musiclover
Posts: 4
Joined: Tue May 09, 2017 2:02 am
Has thanked: 5 times
Been thanked: 3 times

Re: Measuring CPU Usage

Post by musiclover »

Hi Giovanni,
I wrote a function to measure the average usage of CPU. The code is below. Is this correct? Thanks a lot!

Code: Select all

static void CPU_load(BaseSequentialStream *chp) {

  thread_t *tp;

  uint64_t sum=0;
  uint16_t tmp1, tmp2;

  tp = chRegFirstThread();
  do {
    sum += tp->p_stats.cumulative;
    tp = chRegNextThread(tp);
  } while (tp != NULL);
  sum += ch.kernel_stats.m_crit_thd.cumulative;
  sum += ch.kernel_stats.m_crit_isr.cumulative;

  tp = chRegFirstThread();
  do {
    tmp1 = (uint16_t)(tp->p_stats.cumulative*10000/sum);
    chprintf(chp, "%12s %u.%u%%\r\n", tp->p_name, tmp1/100, tmp1%100);
    tp = chRegNextThread(tp);
  } while (tp != NULL);

  tmp1 = (uint16_t)(ch.kernel_stats.m_crit_thd.cumulative*10000/sum);
  tmp2 = (uint16_t)(ch.kernel_stats.m_crit_isr.cumulative*10000/sum);

  chprintf(chp, "thd:%u.%u%%   isr:%u.%u%%\r\n",
      tmp1/100, tmp1%100,tmp2/100, tmp2%100);
  chprintf(chp, "\r\n");
}
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Measuring CPU Usage

Post by Giovanni »

Hi,

It looks OK, it is what I meant. Note that statistics make the operations a bit slower and use more RAM because handling of counters.

Giovanni
musiclover
Posts: 4
Joined: Tue May 09, 2017 2:02 am
Has thanked: 5 times
Been thanked: 3 times

Re: Measuring CPU Usage

Post by musiclover »

Thanks Giovanni and thanks for remind. That code will only be used for testing, and when testing is finished, I'll disable the code and change CH_DBG_STATISTICS to FALSE. :D
sntnjrg
Posts: 65
Joined: Mon Jul 22, 2019 2:19 pm
Has thanked: 18 times
Been thanked: 3 times

Re: Measuring CPU Usage

Post by sntnjrg »

Hi,

Why is it multiplied by 10000?

Thank you.
sntnjrg
Posts: 65
Joined: Mon Jul 22, 2019 2:19 pm
Has thanked: 18 times
Been thanked: 3 times

Re: Measuring CPU Usage

Post by sntnjrg »

Hi,

I understand the reason for the multiplication by 10000.

When I run the code, I have noticed that the sum of all the percentages of the threads is never the 100%.

When you do the following:

Code: Select all

tmp1 = (uint16_t)(tp->p_stats.cumulative*10000/sum);

Hasn't the value of the cumulative field changed from the one previously added?

What other approach would you recommend to obtain the CPU usage percentage of each thread?

Thank you.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Measuring CPU Usage

Post by Giovanni »

The system provides only the time spent by each thread as an absolute value (number of clock cycles), converting that in percentage could be subject to rounding errors.

Giovanni
sntnjrg
Posts: 65
Joined: Mon Jul 22, 2019 2:19 pm
Has thanked: 18 times
Been thanked: 3 times

Re: Measuring CPU Usage

Post by sntnjrg »

Thank you Giovanni for the help and musiclover for the function.
steved
Posts: 834
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 138 times

Re: Measuring CPU Usage

Post by steved »

Would there be any unexpected side effects from restarting the measurement by clearing all the measurement counters to zero at some arbitrary point?
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Measuring CPU Usage

Post by Giovanni »

The system would not be affected, those are only updated.

Giovanni
ych
Posts: 45
Joined: Tue Mar 03, 2015 11:38 pm
Has thanked: 17 times
Been thanked: 11 times

Re: Measuring CPU Usage

Post by ych »

What about the following approach for obtaining a general CPU usage value when
ChibiOS is configured with thread statistics and the idle thread enabled?

The idea is to sum the cumulative execution time of all registered threads,
subtract the idle thread contribution, and compute the CPU load as a percentage.

Code: Select all

uint8_t calculate_cpu_usage(void) {
  rttime_t threads_cumulative_sum = 0;

  thread_t *thread_p = chRegFirstThread();
  do {
    threads_cumulative_sum += thread_p->stats.cumulative;
    thread_p = chRegNextThread(thread_p);
  } while (thread_p != NULL);

  threads_cumulative_sum += currcore->kernel_stats.m_crit_thd.cumulative;
  threads_cumulative_sum += currcore->kernel_stats.m_crit_isr.cumulative;

  thread_t *idle_thread_p = chSysGetIdleThreadX();
  rttime_t idle_thread_cumulative = idle_thread_p->stats.cumulative;

  return (threads_cumulative_sum - idle_thread_cumulative) * 100 /
         threads_cumulative_sum;
}


Is this approach conceptually correct for estimating CPU usage, or does it require
adjustments (for example regarding what should be included in the total
cumulative time)?
Post Reply