Android timer precision increase 1000x

SDL_GetPerformanceCounter() on Android is implemented in
timer/unix/SDL_systimer.c, and uses the gettimeofday() implementation.

If HAVE_CLOCK_GETTIME is defined in the Android.mk’s CCFLAGS, it
successfully uses clock_gettime() instead. This is a 1000x increase of
precision (nanosecond resolution instead of microsecond).

Two time related concerns:

  1. Is there a reason why HAVE_CLOCK_GETTIME is not enabled on Android?

  2. SDL_GetPerformanceFrequency() returns a hardcoded value instead of
    calling clock_getres(). Is this a potential bug? From the clock_getres()
    manpage: “The resolution of clocks depends on the implementation”

Code excerpt from Mercurial:

#if HAVE_CLOCK_GETTIME
return 1000000000;
#elif

Asking around, experienced Android NDK game developers have told me that
they have successfully shipped games using nanosecond precision on various
Android hardware. Should SDL2 enable this by default?

Michael Labbe

Go ahead and submit a patch and we’ll look at it for 2.0.4.

Thanks!On Wed, May 13, 2015 at 3:05 PM, Michael Labbe wrote:

SDL_GetPerformanceCounter() on Android is implemented in
timer/unix/SDL_systimer.c, and uses the gettimeofday() implementation.

If HAVE_CLOCK_GETTIME is defined in the Android.mk’s CCFLAGS, it
successfully uses clock_gettime() instead. This is a 1000x increase of
precision (nanosecond resolution instead of microsecond).

Two time related concerns:

  1. Is there a reason why HAVE_CLOCK_GETTIME is not enabled on Android?

  2. SDL_GetPerformanceFrequency() returns a hardcoded value instead of
    calling clock_getres(). Is this a potential bug? From the clock_getres()
    manpage: “The resolution of clocks depends on the implementation”

Code excerpt from Mercurial:

#if HAVE_CLOCK_GETTIME
return 1000000000;
#elif

Asking around, experienced Android NDK game developers have told me that
they have successfully shipped games using nanosecond precision on various
Android hardware. Should SDL2 enable this by default?

Michael Labbe


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Hi,On Thu, May 14, 2015 at 1:05 AM, Michael Labbe wrote:

  1. SDL_GetPerformanceFrequency() returns a hardcoded value instead of
    calling clock_getres(). Is this a potential bug? From the clock_getres()
    manpage: “The resolution of clocks depends on the implementation”

Code excerpt from Mercurial:

#if HAVE_CLOCK_GETTIME
return 1000000000;
#elif

I would guess that this has to do with the fact that clock_gettime()
returns actual
time values rather than arbitrary ticks. You’ll often see something
like this used
to calculate a time value:
t = SDL_GetPerformanceCounter() / SDL_GetPerformanceFrequency();

As you’re getting known-length ticks out of the first call, you don’t
need to divide
it with whatever clock_getres() returns. In fact, it might completely
screw you over.

Does this make any sense?


Melker Narikka

Hi,

  1. SDL_GetPerformanceFrequency() returns a hardcoded value instead of
    calling clock_getres(). Is this a potential bug? From the clock_getres()
    manpage: “The resolution of clocks depends on the implementation”

Code excerpt from Mercurial:

#if HAVE_CLOCK_GETTIME
return 1000000000;
#elif

I would guess that this has to do with the fact that clock_gettime()
returns actual
time values rather than arbitrary ticks. You’ll often see something
like this used
to calculate a time value:
t = SDL_GetPerformanceCounter() / SDL_GetPerformanceFrequency();

As you’re getting known-length ticks out of the first call, you don’t
need to divide
it with whatever clock_getres() returns. In fact, it might completely
screw you over.

Does this make any sense?

Yep, clock_gettime always returns nanoseconds, (or actually seconds +
nanoseconds) so no need for dividing.
If the internal clock doesn’t have nanosecond-resolution it just means
that you might get the same value in several calls to clock_gettime(),
even though (at least) a nanosecond passed inbetween.
The SDL_GetPerformance*() API is like it is because on some platforms
(like Windows) the API that’s used by SDL returns ticks that need to be
divided by the frequency (which may depend on the CPUs frequency or
whatever) to get a time.

Cheers,
DanielOn 05/14/2015 03:07 PM, Melker Narikka wrote:

On Thu, May 14, 2015 at 1:05 AM, Michael Labbe wrote:

A read through the clock_getres source code, and a test against four
separate hardware platforms seem to confirm that clock_getres always
returns 1ns for CLOCK_MONOTONIC. Actually calling it rather than returning
the number of nanoseconds in a second would be an academic exercise.

Enabling HAVE_CLOCK_GETTIME on Android is a patch I can contribute. I’ll
see about doing it this weekend!On Thu, May 14, 2015 at 12:22 AM, Sam Lantinga wrote:

Go ahead and submit a patch and we’ll look at it for 2.0.4.

Thanks!

On Wed, May 13, 2015 at 3:05 PM, Michael Labbe <@Michael_Labbe> wrote:

SDL_GetPerformanceCounter() on Android is implemented in
timer/unix/SDL_systimer.c, and uses the gettimeofday() implementation.

If HAVE_CLOCK_GETTIME is defined in the Android.mk’s CCFLAGS, it
successfully uses clock_gettime() instead. This is a 1000x increase of
precision (nanosecond resolution instead of microsecond).

Two time related concerns:

  1. Is there a reason why HAVE_CLOCK_GETTIME is not enabled on Android?

  2. SDL_GetPerformanceFrequency() returns a hardcoded value instead of
    calling clock_getres(). Is this a potential bug? From the clock_getres()
    manpage: “The resolution of clocks depends on the implementation”

Code excerpt from Mercurial:

#if HAVE_CLOCK_GETTIME
return 1000000000;
#elif

Asking around, experienced Android NDK game developers have told me that
they have successfully shipped games using nanosecond precision on various
Android hardware. Should SDL2 enable this by default?

Michael Labbe


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

It doesn’t matter, actually, because even if the resolution is not 1ns,
the values returned by clock_gettime is still in seconds + nanoseconds
and diving them by the resolution or something would give wrong results.

I was wondering if maybe gettimeofday() is faster than clock_gettime()
on Android, maybe one uses vDSO[*] on ARM and the other one doesn’t or
something.
Anyway that doesn’t seem to be the case: On ARM64 both gettimeofday()
and clock_gettime() seem to be implemented via vDSO and such should have
equally low overhead, see


For ARM (without 64) it seems like both require a real syscall. And I
don’t know whether ARM or ARM64 is used by common Android devices.
Anyway, at least clock_gettime() with CLOCK_REALTIME and gettimeofday()
seem to use the same thing in the kernel eventually
(__getnstimeofday64()), while clock_gettime() with CLOCK_MONOTONIC ends
up calling ktime_get_ts64(). The implementations of ktime_get_ts64() and
__getnstimeofday64() are very similar, the only difference seems to be
that the former adds a some “tomono” value which probably is adjusted in
case the clock is set to another date/time.
See

and

I briefly looked at the 2.6.32 kernel source as well and at least in
timekeeping.c ktime_get_ts() and getnstimeofday() look similar as well,
so probably gettimeofday() isn’t any faster than clock_gettime() on
older kernels either.

So… what what this all about? Oh, right.
Yeah, I think using clock_gettime() instead of gettimeofday() makes
perfect sense and shouldn’t be any slower.

Cheers,
Daniel

[*] basically, some syscalls (syscalls generally require a context
switch and thus are slow-ish) like gettimeofday() are replaced with
userspace-code that just reads values from memory that is mapped into
the userspace by the kernel and updated. So the kernel keeps the time
values in that memory up to date and userspace programs using
gettimeofday() can just read it without doing a real syscall.
This is used for clock_gettime() too, at least for some clocks,
including CLOCK_MONOTONIC.On 05/14/2015 09:26 PM, Michael Labbe wrote:

A read through the clock_getres source code, and a test against four
separate hardware platforms seem to confirm that clock_getres always
returns 1ns for CLOCK_MONOTONIC. Actually calling it rather than
returning the number of nanoseconds in a second would be an academic
exercise.

I have attached a one line patch against 2.0.4rc1 that enables
HAVE_CLOCK_GETTIME on Android. I have been running this for about a month
on various devices without issue.On Thu, May 14, 2015 at 12:22 AM, Sam Lantinga wrote:

Go ahead and submit a patch and we’ll look at it for 2.0.4.

Thanks!

On Wed, May 13, 2015 at 3:05 PM, Michael Labbe <@Michael_Labbe> wrote:

SDL_GetPerformanceCounter() on Android is implemented in
timer/unix/SDL_systimer.c, and uses the gettimeofday() implementation.

If HAVE_CLOCK_GETTIME is defined in the Android.mk’s CCFLAGS, it
successfully uses clock_gettime() instead. This is a 1000x increase of
precision (nanosecond resolution instead of microsecond).

Two time related concerns:

  1. Is there a reason why HAVE_CLOCK_GETTIME is not enabled on Android?

  2. SDL_GetPerformanceFrequency() returns a hardcoded value instead of
    calling clock_getres(). Is this a potential bug? From the clock_getres()
    manpage: “The resolution of clocks depends on the implementation”

Code excerpt from Mercurial:

#if HAVE_CLOCK_GETTIME
return 1000000000;
#elif

Asking around, experienced Android NDK game developers have told me that
they have successfully shipped games using nanosecond precision on various
Android hardware. Should SDL2 enable this by default?

Michael Labbe


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

-------------- next part --------------
A non-text attachment was scrubbed…
Name: Android.mk.patch
Type: application/octet-stream
Size: 449 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20150617/7d60fb88/attachment.obj

Just to be clear: is there some old Android version we still support that doesn’t have clock_gettime()?

–ryan.> On Jun 17, 2015, at 4:45 PM, Michael Labbe wrote:

I have attached a one line patch against 2.0.4rc1 that enables HAVE_CLOCK_GETTIME on Android. I have been running this for about a month on various devices without issue.

On Thu, May 14, 2015 at 12:22 AM, Sam Lantinga wrote:
Go ahead and submit a patch and we’ll look at it for 2.0.4.

Thanks!

On Wed, May 13, 2015 at 3:05 PM, Michael Labbe wrote:
SDL_GetPerformanceCounter() on Android is implemented in timer/unix/SDL_systimer.c, and uses the gettimeofday() implementation.

If HAVE_CLOCK_GETTIME is defined in the Android.mk’s CCFLAGS, it successfully uses clock_gettime() instead. This is a 1000x increase of precision (nanosecond resolution instead of microsecond).

Two time related concerns:

  1. Is there a reason why HAVE_CLOCK_GETTIME is not enabled on Android?

  2. SDL_GetPerformanceFrequency() returns a hardcoded value instead of calling clock_getres(). Is this a potential bug? From the clock_getres() manpage: “The resolution of clocks depends on the implementation”

Code excerpt from Mercurial:

#if HAVE_CLOCK_GETTIME
return 1000000000;
#elif

Asking around, experienced Android NDK game developers have told me that they have successfully shipped games using nanosecond precision on various Android hardware. Should SDL2 enable this by default?

Michael Labbe


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

<Android.mk.patch>


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

I think I used clock_gettime() in ALmixer on Android on 2.2 and
maybe even 2.0. Lots of users and devices with no problems. I’m pretty
certain I used it in 2.3 without problems.

-EricOn 6/18/15, Ryan C. Gordon wrote:

Just to be clear: is there some old Android version we still support that
doesn’t have clock_gettime()?

–ryan.

I doubt that, CLOCK_MONOTONIC is used by
android.os.SystemClock.uptimeMillis(), which has been available since API 1.On 19-Jun-15 4:14, Ryan C. Gordon wrote:

Just to be clear: is there some old Android version we still support
that doesn’t have clock_gettime()?

–ryan.

On Jun 17, 2015, at 4:45 PM, Michael Labbe <mike at frogtoss.com <mailto:mike at frogtoss.com>> wrote:

I have attached a one line patch against 2.0.4rc1 that enables
HAVE_CLOCK_GETTIME on Android. I have been running this for about a
month on various devices without issue.

On Thu, May 14, 2015 at 12:22 AM, Sam Lantinga <slouken at libsdl.org <mailto:slouken at libsdl.org>> wrote:

Go ahead and submit a patch and we'll look at it for 2.0.4.

Thanks!

On Wed, May 13, 2015 at 3:05 PM, Michael Labbe <mike at frogtoss.com <mailto:mike at frogtoss.com>> wrote:

    SDL_GetPerformanceCounter() on Android is implemented in
    timer/unix/SDL_systimer.c, and uses the gettimeofday()
    implementation.

    If HAVE_CLOCK_GETTIME is defined in the Android.mk's CCFLAGS,
    it successfully uses clock_gettime() instead.  This is a
    1000x increase of precision (nanosecond resolution instead of
    microsecond).

    Two time related concerns:

    1. Is there a reason why HAVE_CLOCK_GETTIME is not enabled on
    Android?

    2. SDL_GetPerformanceFrequency() returns a hardcoded value
    instead of calling clock_getres(). Is this a potential bug? 
    From the clock_getres() manpage: "The resolution of clocks
    depends on the implementation"

    Code excerpt from Mercurial:

     #if HAVE_CLOCK_GETTIME
            return 1000000000;
    #elif ...

    Asking around, experienced Android NDK game developers have
    told me that they have successfully shipped games using
    nanosecond precision on various Android hardware.  Should
    SDL2 enable this by default?

    Michael Labbe

    _______________________________________________
    SDL mailing list
    SDL at lists.libsdl.org <mailto:SDL at lists.libsdl.org>
    http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org



_______________________________________________
SDL mailing list
SDL at lists.libsdl.org <mailto:SDL at lists.libsdl.org>
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

<Android.mk.patch>


SDL mailing list
SDL at lists.libsdl.org <mailto:SDL at lists.libsdl.org>
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

This change is in for 2.0.4, thanks!

https://hg.libsdl.org/SDL/rev/7cfd071cd9a2On Wed, Jun 17, 2015 at 1:45 PM, Michael Labbe wrote:

I have attached a one line patch against 2.0.4rc1 that enables
HAVE_CLOCK_GETTIME on Android. I have been running this for about a month
on various devices without issue.

On Thu, May 14, 2015 at 12:22 AM, Sam Lantinga <@slouken> wrote:

Go ahead and submit a patch and we’ll look at it for 2.0.4.

Thanks!

On Wed, May 13, 2015 at 3:05 PM, Michael Labbe wrote:

SDL_GetPerformanceCounter() on Android is implemented in
timer/unix/SDL_systimer.c, and uses the gettimeofday() implementation.

If HAVE_CLOCK_GETTIME is defined in the Android.mk’s CCFLAGS, it
successfully uses clock_gettime() instead. This is a 1000x increase of
precision (nanosecond resolution instead of microsecond).

Two time related concerns:

  1. Is there a reason why HAVE_CLOCK_GETTIME is not enabled on Android?

  2. SDL_GetPerformanceFrequency() returns a hardcoded value instead of
    calling clock_getres(). Is this a potential bug? From the clock_getres()
    manpage: “The resolution of clocks depends on the implementation”

Code excerpt from Mercurial:

#if HAVE_CLOCK_GETTIME
return 1000000000;
#elif

Asking around, experienced Android NDK game developers have told me that
they have successfully shipped games using nanosecond precision on various
Android hardware. Should SDL2 enable this by default?

Michael Labbe


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org