Timestamping - looking for a reasonably good timer with microsecond granularity
-
- KVRist
- 205 posts since 12 Feb, 2009 from Perú
I've been adding some time stamping features to my app - the idea is that every "external" event that arrives to the app is time stamped. This applies to MIDI events (appart from their own timestamping), GUI events (the user entering a value using some edit box) and events arriving from GPIOs (when the app is running on the Raspberry Pi). So far I have used the timing facilities provided by the ZThread library, and it worked reasonably well, except that I think it would be better if I used something with a microsecond granularity (ZThread works in milliseconds).
Why? Imagine using an ultrasonic sensor to calculate distances... the sensor sends a series of ultrasonic pulses and then triggers an event when the pulses come back to the unit after bouncing off some surface. If I tried to calculate the distance of that surface by going (endtime - startTime)... in milliseconds, the result could be off by 30+ centimeters! Imagine what that error could mean if I was trying to generate MIDI events based on that result...
What library would you recommend? I read about Boost chrono, and after having a quick glance at it, it surely looks interesting... lots of options. Then I found these two sites:
http://www.songho.ca/misc/timer/timer.html
http://www.devx.com/cplus/Article/35375/0/page/2
The first one looks suspiciously simple.....or not?
The second one states that although it shows Linux code, the lib used is available on most Windows systems.... is that right?
BTW, I'm using VC2008, but my code must run on Linux too (Intel and ARM).
Thanks in advance.
Why? Imagine using an ultrasonic sensor to calculate distances... the sensor sends a series of ultrasonic pulses and then triggers an event when the pulses come back to the unit after bouncing off some surface. If I tried to calculate the distance of that surface by going (endtime - startTime)... in milliseconds, the result could be off by 30+ centimeters! Imagine what that error could mean if I was trying to generate MIDI events based on that result...
What library would you recommend? I read about Boost chrono, and after having a quick glance at it, it surely looks interesting... lots of options. Then I found these two sites:
http://www.songho.ca/misc/timer/timer.html
http://www.devx.com/cplus/Article/35375/0/page/2
The first one looks suspiciously simple.....or not?
The second one states that although it shows Linux code, the lib used is available on most Windows systems.... is that right?
BTW, I'm using VC2008, but my code must run on Linux too (Intel and ARM).
Thanks in advance.
-
tony tony chopper tony tony chopper https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=3103
- KVRAF
- 3561 posts since 20 Jun, 2002
in a multithreaded OS, I'm not sure you'll get the accuracy you need in a reliable way, normally such things are done in the kernel, as drivers, no?
DOLPH WILL PWNZ0R J00r LAWZ!!!!
-
- KVRist
- Topic Starter
- 205 posts since 12 Feb, 2009 from Perú
Well, for what I've read, in Windows there's a function that will eventually get called (regardless of which library you'reusing) which is QueryPerformanceCounter (...). That function will "enter kernel mode" to get the info it needs. But a call to that function can be expensive - which shouldn't be a problem if only called once in a while I guess.
-
- KVRist
- Topic Starter
- 205 posts since 12 Feb, 2009 from Perú
Looks like boost chrono won't help me - it uses c++11, so it won't copile on VC2008.... and VC2010 is ridiculously slow on my netbook.
-
tony tony chopper tony tony chopper https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=3103
- KVRAF
- 3561 posts since 20 Jun, 2002
what kind of "event" does it trigger btw?
generally, something that comes from a piece of hardware is read by a driver anyway, and that's where it can be timestamped accurately (could indeed be using QueryPerformanceCounter).
In user mode you will definitely get better than ms accuracy, but certainly not microseconds, because your process will only get the timeslices it deserves.
generally, something that comes from a piece of hardware is read by a driver anyway, and that's where it can be timestamped accurately (could indeed be using QueryPerformanceCounter).
In user mode you will definitely get better than ms accuracy, but certainly not microseconds, because your process will only get the timeslices it deserves.
DOLPH WILL PWNZ0R J00r LAWZ!!!!
-
- KVRist
- Topic Starter
- 205 posts since 12 Feb, 2009 from Perú
On the RPi, once the state of an input pin changes, a function is called.tony tony chopper wrote:what kind of "event" does it trigger btw?
You got me thinking..... yes, mouse moves, button clicks and keystrokes come already time stamped, so I could use that value. In windows (I don't know about Linux and Mac OS yet) the time stamping is done in milliseconds, but for those events (mouse and keyboard) I guess that resolution is ok. It's the interaction with the RPi pins that worries me. But then again, the RPi runs under Linux, and I think Linux has some facilities for getting time in microseconds, unless...tony tony chopper wrote:generally, something that comes from a piece of hardware is read by a driver anyway, and that's where it can be timestamped accurately (could indeed be using QueryPerformanceCounter).
What do you mean? As long as I can call a function that tells me how long it's been since the system started (or since epoch or whatever other point in time that can be used as a reference) with microseconds accuracy then I'm happy. Or am I asking too much?tony tony chopper wrote: In user mode you will definitely get better than ms accuracy, but certainly not microseconds, because your process will only get the timeslices it deserves.
-
tony tony chopper tony tony chopper https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=3103
- KVRAF
- 3561 posts since 20 Jun, 2002
you will be calling a function yes, but when? It'll probably be called late. But I still don't understand, you're receiving an event from a piece of hardware, but without the help of a driver, and this in user mode in Windows? I didn't even know it was possible.
DOLPH WILL PWNZ0R J00r LAWZ!!!!
-
- KVRist
- Topic Starter
- 205 posts since 12 Feb, 2009 from Perú
Yes, I should have mentioned that. The incoming event is placed in a queue (with relevant information, including the time when the event arrived), and an event manager living on it's onw thread will process the queue sometime.tony tony chopper wrote:you will be calling a function yes, but when? It'll probably be called late.
No, this is in Linux! The Windows version of the app won't get hardware events, only mouse/keyboard events (which are also hardware, but you get the idea).tony tony chopper wrote: But I still don't understand, you're receiving an event from a piece of hardware, but without the help of a driver, and this in user mode in Windows? I didn't even know it was possible.
In Linux, with the Raspberry Pi, I'm using a library which lets me register a callback function. When a hardware event arrives (a pin changes status) the OS calls the callback function, letting me know that something happened. There I want to create a timestamp to log when the event arrived.
-
tony tony chopper tony tony chopper https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=3103
- KVRAF
- 3561 posts since 20 Jun, 2002
in Windows you can get all of the past (64 or something?) mouse events with timestamps
however.. we're not talking about the echo of a casted ray anymore, but user input, so I don't see why you'd need <1ms accuracy, since the human who controls them is much much less accurate than that
however.. we're not talking about the echo of a casted ray anymore, but user input, so I don't see why you'd need <1ms accuracy, since the human who controls them is much much less accurate than that
DOLPH WILL PWNZ0R J00r LAWZ!!!!
-
- KVRist
- Topic Starter
- 205 posts since 12 Feb, 2009 from Perú
Yes, in Windows I can live with ms accuracy, since all incoming events will be generated by inaccurate humans.
(Actually that is true for any OS ewhen it comes to mouse/keyboard events). I have that part clear now. And I think I know how to get better resolution when working on the RPi for those "pulse is coming home" moments.
-
- KVRer
- 13 posts since 26 Apr, 2013
On a POSIX compliant system (*nix) you want to use either gettimeofday() or clock_gettime() (reading the CLOCK_MONOTONIC_RAW (or on older kernels the CLOCK_MONOTONIC clock)).
The problem with gettimeofday() is the granularity is not specified so can be anything from micro to milliseconds.
clock_gettime() has an accompanying clock_getres() to check the resolution. But in either case if the system does not provide nanosecond clock granularity you might be stuck with only microseconds (and if I remember correct microseconds is what the Raspberry Pi provides).
The next problem you will notice will likely be that the callback function you register is not in fact called right in the interrupt handler of the driver but rather as a OS event and/or signal thus inaccurate in itself.
Anyway things to avoid: clock(), time()
And if you want to get really accurate timing you want to read the ARM processor's cycle count, like:
But you might need to allow user mode to run the above code.
The problem with gettimeofday() is the granularity is not specified so can be anything from micro to milliseconds.
clock_gettime() has an accompanying clock_getres() to check the resolution. But in either case if the system does not provide nanosecond clock granularity you might be stuck with only microseconds (and if I remember correct microseconds is what the Raspberry Pi provides).
The next problem you will notice will likely be that the callback function you register is not in fact called right in the interrupt handler of the driver but rather as a OS event and/or signal thus inaccurate in itself.
Anyway things to avoid: clock(), time()
And if you want to get really accurate timing you want to read the ARM processor's cycle count, like:
Code: Select all
unsigned cycle_count;
asm volatile ( "mrc p15, 0, %0, c15, c12, 1"
: "=r" (cycle_count));
-
- KVRer
- 13 posts since 26 Apr, 2013
You can use superresolution techniques to get better accuracy.Tzarls wrote: Why? Imagine using an ultrasonic sensor to calculate distances... the sensor sends a series of ultrasonic pulses and then triggers an event when the pulses come back to the unit after bouncing off some surface. If I tried to calculate the distance of that surface by going (endtime - startTime)... in milliseconds, the result could be off by 30+ centimeters! Imagine what that error could mean if I was trying to generate MIDI events based on that result...
This means you basically measure multiple times and then "average". This way you can get accuracy beyond your timer granularity. Alas at the expense of response time of the system.
-
- KVRist
- Topic Starter
- 205 posts since 12 Feb, 2009 from Perú
Thank you guys, you've been really helpful! 
