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.
Measuring CPU Usage
Moderators: RoccoMarco, lbednarz, utzig, tfAteba, barthess
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: Measuring CPU Usage
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
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
-
- Posts: 7
- Joined: Fri Jul 08, 2011 3:25 pm
Re: Measuring CPU Usage
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:
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...
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...
-
- Posts: 7
- Joined: Fri Jul 08, 2011 3:25 pm
Re: Measuring CPU Usage
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 )
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
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 )
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
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: Measuring CPU Usage
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
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
-
- Posts: 7
- Joined: Fri Jul 08, 2011 3:25 pm
Re: Measuring CPU Usage
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!!!!
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
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
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: Measuring CPU Usage
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
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
-
- Posts: 4
- Joined: Tue May 09, 2017 2:02 am
- Has thanked: 5 times
- Been thanked: 3 times
Re: Measuring CPU Usage
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!
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: Measuring CPU Usage
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
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
-
- Posts: 4
- Joined: Tue May 09, 2017 2:02 am
- Has thanked: 5 times
- Been thanked: 3 times
Who is online
Users browsing this forum: No registered users and 35 guests