Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get high resolution timer in Android native code?

Tags:

android

time

arm

I am looking for a way to get high-resolution timer (clock source) on Android. This must be in native code, and may be fairly non-portable. I would like microsecond resolution, or better. For my particular application, resolution is more important than precision, and a timer which is monotonic is best. I've been testing on a particular ARMv7 chipset with Android 4.0.3.

What I've tried so far:

  • clock_gettime(CLOCK_MONOTONIC): increments in units of 1ms on target hardware (EDIT originally I thought 10ms due to bug in my code, 1ms is correct but still not very good)
  • gettimeofday(): similar to clock_gettime

What I haven't tried:

  • System.nanoTime(): this is not native. I believe it is based on clock_gettime(), but I would prefer to find out whatever is under the hood and use that directly.
  • /dev/rtc
  • Some kind of ARM instruction/facility, maybe SysTick (http://web.eecs.umich.edu/~prabal/teaching/eecs373-f10/readings/ARMv7-M_ARM.pdf) or General Purpose Timer (GPT).

See also (related questions, but no answer):

  • High-precision timer in Android JNI

  • Getting High Precision Timing on Android

like image 844
Alex I Avatar asked Feb 20 '13 08:02

Alex I


1 Answers

You could use CPU cycle counter to measure the number of cycles between the two moments and then convert it to seconds. To guarantee that the CPU runs at its nominal frequency, switch its scaling governor to "performance" mode (there is a number of apps in Play store to do it, but root access it needed). You also will have to cool your device well to make sure the CPU doesn't throttle (this is especially important for phones). Finally, you have to bind your code to a single core (preferably core 0, because other cores can be put offline by the system).

There are two ways to access cycle counter on ARM: using perf_event subsystem in Linux or by directly reading cycle counter from CP15 coprocessor. perf_event method will only work if Linux kernel is compiled with support for this subsystem (the file /proc/sys/kernel/perf_event_paranoid exists) and reading event counters is not restricted (the file /proc/sys/kernel/perf_event_paranoid contains 0 or -1; with root access you can overwrite the value in this file). The CP15 method will work only if user-mode access to performance counters is enabled (by default it is always disabled, and you will have to either patch the kernel or use a kernel driver to enable it). Yeppp! library (I'm the author) is capable of using either method whenever available, and includes a kernel-mode driver to enable user-mode access to performance counters. You may find this example helpful.

like image 191
Marat Dukhan Avatar answered Oct 02 '22 07:10

Marat Dukhan