Gamasutra: The Art & Business of Making Gamesspacer
Getting High Precision Timing on Android
View All     RSS
April 19, 2019
arrowPress Releases
April 19, 2019
Games Press
View All     RSS








If you enjoy reading this site, you might also want to check out these UBM Tech sites:


 

Getting High Precision Timing on Android


June 6, 2012 Article Start Previous Page 2 of 3 Next
 

Getting Time from the Linux Kernel

The clock_gettime() posix function provides access to several useful timers with a resolution of nanoseconds. Clock_gettime() is the best way for getting an accurate timer in a portable way: it is implemented directly in the kernel and returns the best possible time measurement.

Investigating further, clock_gettime() is defined in the C standard library (libc); Android uses a custom version of this library, called Bionic, smaller and faster than GNU libc (glibc). The Bionic library will make a syscall to the kernel (calling the function at the address __NR_clock_gettime defined in the syscall table); the kernel will return the best possible timer existing on the current hardware.

Android is based on the Linux Kernel, and as happens in any system based on Kernel 2.6, at boot time initializes a linked list with available clocksources; the list is sorted by rating, and the kernel chooses the best clock available. It is also possible to specify the clocksource at build time.

You can find out which clock your system is using reading the content of /sys/devices/system/clocksource/clocksource0/current_clocksource and /sys/devices/system/clocksource/clocksource0/available_clocksource files.

On a Galaxy SII the clock source is mct-frc, the local timer which is included the Exynos4210 system-on-a-chip (SoC); on an LG Optimus One the current timer is dg_timer, the debug timer (DGT) that, together with the general-purpose timer (GPT), is an ARM11 performance counter.

In the following table is reported a list of available and current timers on some Android phone:

 

Samsung Galaxy S 2

LG Optimus One

Nexus S

Nexus 1

Nexus Galaxy S

Galaxy Ace

Available clocksource

mct-frc

dg_timer gp_timer

clock_source_systimer

gp_timer dg_timer

32k_counter

dg_timer gp_timer

Current clocksource

mct-frc

dg_timer

clock_source_systimer

gp_timer

32k_counter

dg_timer

As you can see from the previous table, there are so many different hardware timers that it could be a good idea to use kernel primitives to access timing information!

A similar primitive is gettimeofday() (__NR_gettimeofday in the syscall table), but uses the same back end of clock_gettime() starting from kernel 2.6.18. POSIX.1-2008 marks gettimeofday() as obsolete, recommending instead the use of clock_gettime().

Getting access to an hardware timer through a system call requires a switch from user to kernel/supervisor mode; this switch can be expensive, and can vary from platform to platform.

For example on SH or x86 CPUs, gettimefoday() and clock_gettime() both implement vsyscalls. A system that on modern Linux kernels prevents the crossing of the boundary between the user mode and the kernel mode.

In this case, the Bionic library will call kernel functions (gettimefoday() and clock_gettime()) that are mapped in a kernel page executable with the userspace privileges; vsyscall allows to access hardware timers without the overhead of a user to kernel mode switch.

So on systems with SH or x86 CPUs, the primitive clock_gettime() can be even faster than direct hardware access, and in all other cases (as ARM CPUs actually represent the bigger part of the market), for a little overhead we have a really portable and accurate solution.

In this article we will assume that clock_gettime() is the best possible primitive to get tick count in Android using native code.

Timing in Java

Java does not offer the clock_gettime() function. Unless you develop native applications in C, or you use JNI to call native code, so what is the state of the art on Android for measuring time?

I am going to analyze and test five different solutions:

SystemClock.uptimeMillis()

System.currentTimeMillis()

System.currentThreadTimeMillis()

System.nanoTime()

SystemClock.elapsedRealtime()

We should consider, for each possible solution:

  • Resolution/Accuracy. It is obvious that we want to measure the time in the most accurate way.
  • Overhead. If we are simply benchmarking, we can always cut it out in production code, but if we need to measure the time for other purposes, for example to know the FPS rate of an interactive game, in order to make the animations on the screen FPS-independent, we really need to find a way to measure the time in an efficient manner.

In the following paragraphs we are going to test, benchmark, and discuss these functions, in hopes of finding the best solution.


Article Start Previous Page 2 of 3 Next

Related Jobs

Insomniac Games
Insomniac Games — Burbank CA or Durham NC, California, United States
[04.19.19]

Sr. Engine Programmer
Insomniac Games
Insomniac Games — Burbank CA or Durham NC, California, United States
[04.19.19]

Mid to Senior Engine Programmer (Tools)
Remedy Entertainment
Remedy Entertainment — Espoo, Finland
[04.19.19]

Software Developer for DevOps
DeepMind
DeepMind — London, England, United Kingdom
[04.19.19]

Games System Engineer





Loading Comments

loader image