-1

There is easy way to calc duration of any function which described here: How to Calculate Execution Time of a Code Snippet in C++

start_timestamp = get_current_uptime();
// measured algorithm
duration_of_code = get_current_uptime() - start_timestamp;

But, it does not allow to get clear duration cause some time for execution other threads will be included in the measured time.

So question is: how to consider time which code spend in other threads? OSX code preffer. Although it's great to look to windows or linux code also...

upd: Ideal? concept of code

start_timestamp = get_this_thread_current_uptime();
// measured algorithm
duration_of_code = get_this_thread_current_uptime() - start_timestamp;
Community
  • 1
  • 1
Maxim Kholyavkin
  • 4,463
  • 2
  • 37
  • 82
  • Why will it contain the execution time of other threads? – herohuyongtao Jan 13 '14 at 13:40
  • Why is this tagged RTOS but OSX code preferred? OSX is not an RTOS. – Clifford Jan 20 '14 at 19:35
  • You are right. OSX is not RTOS. It is soft RTOS only. My fault. I updated question. – Maxim Kholyavkin Jan 21 '14 at 03:54
  • There is no way, on a modern system, to measure the duration of an operation accurately and fairly. Among other things, other threads may cause cache misses in your thread, while the action of your thread may "unfairly" pollute the cache for other threads. And then there's the hiccup that simply asking for the time causes. Do note, though, that some processors and/or operating systems maintain an accessible per-thread timer, so the time spent in other threads can be excluded. (How one would ask for this, however, is an exercise for the student.) – Hot Licks Jul 13 '14 at 02:03
  • And, BTW, any short-duration measurement should first do `overhead = get_current_time(); overhead = get_current_time() - overhead;`, and then subtract `overhead` from the final duration value. – Hot Licks Jul 13 '14 at 02:07
  • @HotLicks please give me some help to find how to exclude time spent in other threads - for any system. – Maxim Kholyavkin Jul 13 '14 at 02:28
  • I haven't mucked around at that level for about 15 years. IBM's iSeries OS maintained a timer per task that kept track of CPU cycles consumed by the task. It could be interrogated at the assembly language level. I think there was something similar in DEC's PDP-10 OS. Don't know if any PC OSes have anything similar. – Hot Licks Jul 13 '14 at 02:35

4 Answers4

1

I'm sorry to say that in the general case there is no way to do what you want. You are looking for worst-case execution time, and there are several methods to get a good approximation for this, but there is no perfect way as WCET is equivalent to the Halting problem.

jbr
  • 6,198
  • 3
  • 30
  • 42
  • Could you mention some methods from several to get a good approximation for this? – Maxim Kholyavkin Sep 23 '14 at 05:43
  • It's a very active research area, so knock your self out: http://scholar.google.dk/scholar?hl=en&as_sdt=0,5&q=worst+case+execution+time – jbr Sep 23 '14 at 07:59
1

If you want to exclude the time spent in other threads then you could disable task context switches upon entering the function that you want to measure. This is RTOS dependent but one possibility is to raise the priority of the current thread to the maximum. If this thread is max priority then other threads won't be able to run. Remember to reset the thread priority again at the end of the function. This measurement may still include the time spent in interrupts, however.

Another idea is to disable interrupts altogether. This could remove other threads and interrupts from your measurement. But with interrupts disabled the timer interrupt may not function properly. So you'll need to setup a hardware timer appropriately and rely on the timer's counter value register (rather than any time value derived from a timer interrupt) to measure the time. Also make sure your function doesn't call any RTOS routines that allow for a context switch. And remember to restore interrupts at the end of your function.

Another idea is to run the function many times and record the shortest duration measured over those many times. Longer durations probably include time spent in other threads but the shortest duration may be just the function with no other threads.

Another idea is to set a GPIO pin upon entry to and clear it upon exit from the function. Then monitor the GPIO pin with an oscilloscope (or logic analyzer). Use the oscilloscope to measure the period for when the GPIO pin is high. In order to remove the time spent in other threads you would need to modify the RTOS scheduler routine that selects the thread to run. Clear the GPIO pin in the scheduler when another thread runs and set it when the scheduler returns to your function's thread. You might also consider clearing the GPIO pin in interrupt handlers.

kkrambo
  • 6,643
  • 1
  • 17
  • 30
  • 1
    Disabling interrupts may disable *timer* interrupts too. Better off setting thread priority to maximum. +1 for using a `scope, though. – Roddy Jan 13 '14 at 14:13
0

Your question is entirely OS dependent. The only way you can accomplish this is to somehow get a guarantee from the OS that it won't preempt your process to perform some other task, and to my knowledge this is simply not possible in most consumer OS's.

RTOS often do provide ways to accomplish this though. With Windows CE, anything running at priority 0 (in theory) won't be preempted by another thread unless it makes a function/os api/library call that requires servicing from another thread.

I'm not super familer with OSx, but after glancing at the documentation, OSX is a "soft" realtime operating system. This means that technically what you want can't be guaranteed. The OS may decide that there is "Something" more important than your process that NEEDS to be done.

OSX does however allow you to specify a Real-time process which means the OS will make every effort to honor your request to not be interrupted and will only do so if it deems absolutely necessary.

Mac OS X Scheduling documentation provides examples on how to set up real-time threads

8bitwide
  • 2,071
  • 1
  • 17
  • 24
0

OSX is not an RTOS, so the question is mistitled and mistagged.

In a true RTOS you can lock the scheduler, disable interrupts or raise the task to the highest priority (with round-robin scheduling disabled if other tasks share that priority) to prevent preemption - although only interrupt disable will truly prevent preemption by interrupt handlers. In a GPOS, even if it has a priority scheme, that normally only controls the number of timeslices allowed to a process in what is otherwise round-robin scheduling, and does not prevent preemption.

One approach is to make many repeated tests and take the smallest value obtained, since that is likely to be the one where the fewest pre-emptions occurred. It will help also to set the process to the highest priority in order to minimise the number of preemtions. But bear in mind on a GPOS many interrupts from devices such as the mouse, keyboard, and system clock will occur and consume a small (an possibly negligible) amount of time.

Clifford
  • 88,407
  • 13
  • 85
  • 165