2013-02-20 58 views
7

我正在寻找一种方法来获取Android上的高分辨率定时器(时钟源)。这必须使用本机代码,并且可能相当不便携。我想要微秒分辨率,或更好。对于我的特殊应用,分辨率比精度更重要,而单调的计时器是最好的。我一直在用Android 4.0.3测试特定的ARMv7芯片组。如何在Android本机代码中获取高分辨率计时器?

我试过到目前为止:

  • clock_gettime(CLOCK_MONOTONIC):增量1ms的单位在目标硬件上(编辑原本我以为,由于10ms的错误在我的代码,1ms的是正确的,但仍然不是很好)
  • gettimeofday():类似clock_gettime

我还没有尝试过:

参见(相关的问题,但没有回答):

+0

你能假设设备的根访问权限? – 2013-02-20 09:20:38

+0

@Maratyszcza:是的,如果需要,我可以拥有根。 – 2013-02-20 09:50:01

+0

这不是关于Android,而是Linux,这是不可能的。 http://elinux.org/High_Resolution_Timers – auselen 2013-02-20 10:31:23

回答

6

你可以使用CPU周期计数器测量周期的两个时刻之间的号码,然后将其转换的分辨率到秒。为了保证CPU以标称频率运行,将其调节调节器切换到“性能”模式(Play商店中有许多应用程序可以执行此操作,但需要根访问权限)。你也必须很好地冷却你的设备,以确保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! library(我是作者)能够在任何时候使用任何方法,并且包含一个内核模式驱动程序,以启用对性能计数器的用户模式访问。你可能会发现this example有帮助。

+0

我提到了同样的事情,看起来像有人不喜欢我的建议一样多... – sgupta 2013-02-23 16:26:51

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

编辑:你可能还看https://groups.google.com/forum/?fromgroups=#!topic/android-ndk/dgrqhgHWbHI和clock_getres()检查clock_gettime()