Measuring CPU Usage

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

Moderators: utzig, lbednarz, tfAteba, barthess, RoccoMarco

Xamusk
Posts: 81
Joined: Sat Mar 05, 2011 10:47 pm

Measuring CPU Usage

Postby Xamusk » Thu Jun 30, 2011 5:45 pm

Hi,

Is there any simple way to measure CPU usage, or do I have to code my own timer and counting system?

If there were such a system in place, it would be great to measure the performance improvements that an RTOS can provide (against bare metal, for example), as well as check how much processing power is still available for additional tasks without performance impact.

User avatar
Giovanni
Site Admin
Posts: 12749
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 696 times
Been thanked: 573 times
Contact:

Re: Measuring CPU Usage

Postby Giovanni » Thu Jun 30, 2011 6:06 pm

Hi,

There is no default measurement system because several strategies could be implemented (recent usage only, usage since system start etc) but the system offers the hook and facilities to implement any measurement algorithm.

The hook macro SYSTEM_TICK_EVENT_HOOK() allows to hook code to handle performance counters without have to use a dedicated timer, for example you can check if the current thread is the idle thread (chThdSelf() == chSysGetIdleThread()) and update your counters according to your strategy.

In addition each thread maintains a counter of the used time in ticks, the value can be retrieved using chThdGetTicks(tp). Active threads can be scanned using the "registry" functions, examples of this are present in the demos that use the shell (ARMCM3-STM32F103-FATFS for example), the "threads" command lists all the threads including the used time.

Giovanni

Alessandro
Posts: 7
Joined: Fri Jul 08, 2011 3:25 pm

Re: Measuring CPU Usage

Postby Alessandro » Mon Jul 11, 2011 10:31 am

Hi,
in order to calculate the CPU usage, I tried a simple way.
I developed it in the WIN32 simulator, but I think it can be ported also to other targets.
This is the code snippet from hal_lld.c:

Code: Select all

  // Interrupt Timer simulation (10ms interval).
  QueryPerformanceCounter(&n);
  if (n.QuadPart > nextcnt.QuadPart) {
    nextcnt.QuadPart += slice.QuadPart;
    chSysTimerHandlerI();
    secCount += 10;
    if (chSchIsRescRequiredExI())
      chSchDoRescheduleI();
     else
        timeIdle += 10;
   
    if(secCount == 1000)
    {
          perc = (unsigned char)(((float)(1000 - timeIdle)/(float)secCount)*100);
          timeIdle = 0;
          secCount = 0;
    }
  }



secCount is always updated.
timeIdle is updated only if there is NO need to reschedule.
Every second I calculate the percentage and restart the algorythm.

I think that I can compare my strategy and your, in order to see the differences...

Regards,
Alessandro

UPDATE:
well, I tried the solution with a function called in the macro SYSTEM_TICK_EVENT_HOOK().
The function just increments 2 counters: 1 every time the macro is called, 1 only if condition (chThdSelf() == chSysGetIdleThread()) is true.
It seems that this condition is always true!!!
I tried to vary the sleeping time of the various threads, but my algorythm returns values between 0 and 100 percent, instead this function returns always 0 percent.
The condition (chThdSelf() == chSysGetIdleThread()) seems to tell that the system is always in idle state!
Now is very intresting the comprehension of what is the real CPU usage... :D

Alessandro
Posts: 7
Joined: Fri Jul 08, 2011 3:25 pm

Re: Measuring CPU Usage

Postby Alessandro » Mon Jul 11, 2011 3:27 pm

Hi Giovanni,

I've got another doubt about the threads structure! It is needed for measuring the CPU time.
In my app I've got 5 tasks(threads):
the idle task
the test task (I've made it static, not dynamic... it can be unblocked by a semaphore)
the shell task
and 2 idle tasks for personal uses, always running (and sleeping :D )

If I run the test from console, and after I digit the command "threads", I can see the time counter of test thread that has been updated.
However, if I do nothing, only the idle task increments its time counter!!!
The 2 tasks always running doesn't increment the time counter of the thread structure.

There may be something wrong, but I don't know what!!!! Are there particular conditions in order to obtain the p_time to be updated?

Thank you very much,
Alessandro

User avatar
Giovanni
Site Admin
Posts: 12749
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 696 times
Been thanked: 573 times
Contact:

Re: Measuring CPU Usage

Postby Giovanni » Mon Jul 11, 2011 3:45 pm

Hi Alessandro,

The various demos are designed to not use much CPU time so the idle thread always run very close to 100%.

Now it is important to understand how the measurement work, the blinker threads only are running for few microseconds every second so the chance that the system tick interrupt preempts them is very close to zero (exactly zero if you consider that the blinker threads are synchronized on the system tick because chThdSleep()), this is why their CPU usage fields never increments.

You should also consider that if a thread has a real CPU usage of like 0.3% it will probably still show as 0% because integer rounding.

In order to see p_time updated you should create some time-intensive thread in the system, try a thread that does random loops and sleep phases.

Giovanni

Alessandro
Posts: 7
Joined: Fri Jul 08, 2011 3:25 pm

Re: Measuring CPU Usage

Postby Alessandro » Tue Jul 12, 2011 3:14 pm

Hi Giovanni,

this is exactly what I tried to do, also before posting here. I've created a thread that loops and sleeps for seconds.
I noticed a very interesting thing...
If I create a thread with loops and sleeps but without ChkIntSources(); the system goes slower, but the p_time variable doesn't increment.
Instead, if I create a thread similar to your test benchmark example, p_time is incremented!!!!

Code: Select all

static msg_t ptimeTask(void *arg)
{
    unsigned long waste=0;
    /* forever */
    for(;;)
    {
      chBSemWait(&semTime);
      do {
        chMtxLock(&mtxTest);
        chMtxUnlock();
        chMtxLock(&mtxTest);
        chMtxUnlock();
        chMtxLock(&mtxTest);
        chMtxUnlock();
        chMtxLock(&mtxTest);
        chMtxUnlock();
        ChkIntSources();
        waste++;
      } while (waste < 2000000);
      waste=0;
    }
    return (msg_t)1;
}


With a thread like this I can see also the CPU percentage going up till 100%.

I'm always working on Win32 platform!
Thank you for your patience, but I'd like to well understand what is going on before developing more on my project! ;)
Alessandro

User avatar
Giovanni
Site Admin
Posts: 12749
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 696 times
Been thanked: 573 times
Contact:

Re: Measuring CPU Usage

Postby Giovanni » Tue Jul 12, 2011 6:21 pm

The simulator is just a simulator :-) and it is not really preemptive too unless you place those ChkIntSources() in long loops so what you reported is the normal behavior.

I still recommend to work on a real target, the simulator is mainly meant for testing and demonstrations but you should not expect it to have a true real-time behavior.

Giovanni

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

Re: Measuring CPU Usage

Postby musiclover » Tue May 09, 2017 4:31 pm

Giovanni wrote:Hi,

There is no default measurement system because several strategies could be implemented (recent usage only, usage since system start etc) but the system offers the hook and facilities to implement any measurement algorithm.

The hook macro SYSTEM_TICK_EVENT_HOOK() allows to hook code to handle performance counters without have to use a dedicated timer, for example you can check if the current thread is the idle thread (chThdSelf() == chSysGetIdleThread()) and update your counters according to your strategy.

In addition each thread maintains a counter of the used time in ticks, the value can be retrieved using chThdGetTicks(tp). Active threads can be scanned using the "registry" functions, examples of this are present in the demos that use the shell (ARMCM3-STM32F103-FATFS for example), the "threads" command lists all the threads including the used time.

Giovanni


Hi Giovanni.
I have the same question about Measuring CPU usage. Your answer has been very early, when the kernel is based on the tick mode. After 3.x, the kernel defaults to use the tickless mode, and in the tickless mode how to measure the CPU usage? Should I use the chVTGetSystemTimeX () function in the macro CH_CFG_IDLE_ENTER_HOOK() and CH_CFG_IDLE_LEAVE_HOOK()?
Thank you.
by the way, ChibiOS is great!

User avatar
Giovanni
Site Admin
Posts: 12749
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 696 times
Been thanked: 573 times
Contact:

Re: Measuring CPU Usage

Postby Giovanni » Tue May 09, 2017 4:55 pm

Hi,

Newest RT kernel has a statistics module, it measures CPU usage in threads and ISRs in cycles.

Using those hooks is a way if you want to implement a load measurement but stats can be used too, you may implement a periodic thread that scans other threads in the registry and calculates load based on stat fields.

Giovanni

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

Re: Measuring CPU Usage

Postby musiclover » Wed May 10, 2017 4:26 am

Hi Giovanni

Thank you very much, I'll try it.


Return to “General Support”

Who is online

Users browsing this forum: No registered users and 5 guests