如何获得Android本机代码中的高分辨率定时器?

我正在寻找一种方法来获得Android上的高分辨率定时器(时钟源)。 这必须在本地代码,并可能是相当不便携的。 我想微秒的分辨率,或更好。 对于我的特殊应用,分辨率比精度更重要,而单调的计时器是最好的。 我已经使用Android 4.0.3在特定的ARMv7芯片组上进行了testing。

我到目前为止所尝试的是:

  • clock_gettime(CLOCK_MONOTONIC) :在目标硬件上以1ms为单位递增( EDIT最初由于我的代码中的错误而被认为是10ms,1ms是正确的,但还不是很好)
  • gettimeofday() :类似于clock_gettime

我还没有尝试过:

  • System.nanoTime() :这不是本地的。 我相信这是基于clock_gettime(),但是我更愿意找出底层的东西,直接使用它。
  • /dev/rtc
  • 某种ARM指令/工具,可能是SysTick ( http://web.eecs.umich.edu/~prabal/teaching/eecs373-f10/readings/ARMv7-M_ARM.pdf )或通用计时器(GPT)。

另见(相关问题,但不回答):

  • Android JNI中的高精度定时器

  • 在Android上获得高精度定时

Solutions Collecting From Web of "如何获得Android本机代码中的高分辨率定时器?"

您可以使用CPU周期计数器来测量两个时刻之间的周期数,然后将其转换为秒。 为了保证CPU以标称频率运行,将其调节调节器切换到“性能”模式(Play商店中有许多应用程序需要这样做,但是需要root访问)。 您还必须很好地冷却您的设备,以确保CPU不会调节(这对手机来说尤其重要)。 最后,你必须把你的代码绑定到单个核心(最好是核心0,因为其他核心可以被系统脱机)。

有两种方法可以访问ARM上的循环计数器:在Linux中使用perf_event子系统或直接从CP15协处理器读取循环计数器。 如果Linux内核编译时支持这个子系统(文件/ proc / sys / kernel / perf_event_paranoid存在)并且读取事件计数器不受限制(文件/ proc / sys / kernel / perf_event_paranoid包含0或 – 1;有了root权限,你可以覆盖这个文件中的值)。 只有在性能计数器的用户模式访问被启用的情况下,CP15方法才能工作(默认情况下,它始终是禁用的,您将不得不打补丁内核或使用内核驱动来启用它)。 Yeppp! 库 (我是作者)在任何时候都可以使用任何方法,并且包含一个内核模式驱动程序,以启用对性能计数器的用户模式访问。 你可能会发现这个例子有帮助。

  1. Android不支持ARMv7-M,所以Systick是不合适的。
  2. 我对android / linux中的定时器并不是很有经验,如果你要在你自己的设备上运行这个软件,你可以在linux中启用PMU,并使用CPU的周期计数寄存器来精确到几纳秒。 如果您打算发布您的软件或将其提供给某个最终用户,这是不可取的,因为制造商在不同的设备上具有不同的内核configuration,因此PMU可能无法启用/可用。

编辑:你可以另外看https://groups.google.com/forum/?fromgroups=#!topic/android-ndk/dgrqhgHWbHI和clock_getres()来检查clock_gettime()的分辨率