批处理

什么是批处理?

批处理是指在传感器中心和/或硬件 FIFO 中缓冲传感器事件,然后再通过 Sensors HAL 报告事件。传感器事件被缓冲的位置(传感器中心和/或硬件 FIFO)在本页中称为“FIFO”。当传感器事件批处理未激活时,传感器事件在可用时会立即报告给 Sensors HAL。

批处理可以通过以下方式显著节省电量:仅当许多传感器事件准备好进行处理时才唤醒运行 Android 的主应用处理器 (AP),而不是为每个单独的事件唤醒它。潜在的电量节省与传感器中心和/或 FIFO 可以缓冲的事件数量直接相关:如果可以批处理更多事件,则节省电量的潜力更大。批处理利用低功耗内存来减少高功耗 AP 唤醒次数。

只有当传感器拥有硬件 FIFO 和/或可以在传感器中心内缓冲事件时,才会发生批处理。在任何一种情况下,传感器都必须通过 SensorInfo.fifoMaxEventCount 报告一次可以批处理的最大事件数。

如果传感器在 FIFO 中预留了空间,则传感器必须通过 SensorInfo.fifoReservedEventCount 报告预留事件的数量。如果 FIFO 专用于传感器,则 SensorInfo.fifoReservedEventCount 是 FIFO 的大小。如果 FIFO 在多个传感器之间共享,则此值可能为零。一个常见的用例是允许传感器使用整个 FIFO(如果它是唯一活动的传感器)。如果多个传感器处于活动状态,则每个传感器都保证在 FIFO 中至少有 SensorInfo.fifoReservedEventCount 个事件的空间。如果使用传感器中心,则可以通过软件强制执行保证。

传感器事件在以下情况下进行批处理

  • 传感器的当前最大报告延迟大于零,这意味着传感器事件最多可以延迟最大报告延迟,然后再通过 HAL 报告。
  • AP 处于暂停模式,并且传感器是非唤醒传感器。在这种情况下,事件不得唤醒 AP,并且必须存储到 AP 唤醒为止。

如果传感器不支持批处理且 AP 处于休眠状态,则只有唤醒传感器事件会报告给 AP,而非唤醒事件不得报告给 AP。

批处理参数

控制批处理行为的两个参数是 sampling_period_nsmax_report_latency_nssampling_period_ns 确定生成新传感器事件的频率,max_report_latency_ns 确定事件必须报告给 Sensors HAL 的时长。

sampling_period_ns

sampling_period_ns 参数的含义取决于指定的传感器的报告模式。

  • 连续模式:sampling_period_ns 是采样率,即事件生成的速率。
  • 变化时报告模式:sampling_period_ns 限制事件的采样率,意味着事件生成的速度不会快于每 sampling_period_ns 纳秒一次。如果长时间没有生成事件且测量值没有变化,则周期可能会长于 sampling_period_ns。有关更多详细信息,请参阅变化时报告模式
  • 单次模式:sampling_period_ns 会被忽略。它不起作用。
  • 特殊模式:有关 sampling_period_ns 如何用于特殊传感器的详细信息,请参阅传感器类型

有关 sampling_period_ns 在不同模式下的影响的更多信息,请参阅报告模式

对于连续模式和变化时报告模式的传感器

  • 如果 sampling_period_ns 小于 SensorInfo.minDelay,则 HAL 实现必须以静默方式将其钳制为 max(SensorInfo.minDelay, 1ms)。Android 不支持以超过 1000 Hz 的频率生成事件。
  • 如果 sampling_period_ns 大于 SensorInfo.maxDelay,则 HAL 实现必须以静默方式将其截断为 SensorInfo.maxDelay

物理传感器有时对其运行速率和时钟精度有限制。为了解决这个问题,实际采样频率可能与请求的频率有所不同,只要它满足下表中的要求即可。

如果请求的频率是

那么实际频率必须是

低于最小频率 (<1/maxDelay)

在最小频率的 90% 到 110% 之间

在最小频率和最大频率之间

在请求频率的 90% 到 220% 之间

高于最大频率 (>1/minDelay)

在最大频率的 90% 到 110% 之间,且低于 1100 Hz

max_report_latency_ns

max_report_latency_ns 设置了事件可以延迟并在硬件 FIFO 中存储的最长时间(以纳秒为单位),之后在 AP 唤醒时通过 HAL 报告。

值为零表示事件必须在测量后立即报告,要么完全跳过 FIFO,要么在传感器中出现一个事件后立即清空 FIFO。

例如,当 AP 唤醒时,以 50 Hz 激活且 max_report_latency_ns=0 的加速度计将每秒触发 50 次中断。

max_report_latency_ns>0 时,传感器事件不需要在检测到后立即报告。它们可以暂时存储在 FIFO 中并批量报告,只要没有事件延迟超过 max_report_latency_ns 纳秒。这意味着自上一批次以来的所有事件都会被记录并一次性返回。这减少了发送到 AP 的中断数量,并允许 AP 在传感器捕获和批量处理数据时切换到较低功耗模式(空闲)。

每个事件都有一个与之关联的时间戳。延迟事件的报告时间不会影响事件时间戳。时间戳必须准确,并且对应于事件实际发生的时间,而不是报告时间。

允许传感器事件临时存储在 FIFO 中不会修改向 HAL 提交事件的行为;来自不同传感器的事件可以交错,并且来自同一传感器的所有事件都按时间顺序排列。

唤醒和非唤醒事件

来自唤醒传感器的传感器事件必须存储在一个或多个唤醒 FIFO 中。一种常见的设计是使用单个大型共享唤醒 FIFO,其中来自所有唤醒传感器的事件交错排列。或者,您可以为每个传感器设置一个唤醒 FIFO,或者为特定的唤醒传感器设置专用 FIFO,并为其余唤醒传感器设置共享 FIFO。

类似地,来自非唤醒传感器的传感器事件必须存储在一个或多个非唤醒 FIFO 中。

在所有情况下,唤醒传感器事件和非唤醒传感器事件都不能在同一个 FIFO 中交错。唤醒事件必须存储在唤醒 FIFO 中,而非唤醒事件必须存储在非唤醒 FIFO 中。

对于唤醒 FIFO,单个大型共享 FIFO 设计提供了最佳的功耗优势。对于非唤醒 FIFO,单个大型共享 FIFO 和多个小型保留 FIFO 设计具有相似的功耗特性。有关如何配置每个 FIFO 的更多建议,请参阅FIFO 分配优先级

挂起模式外的行为

当 AP 唤醒(未处于挂起模式)时,事件会临时存储在 FIFO 中,只要它们延迟不超过 max_report_latency

只要 AP 不进入挂起模式,就不会丢弃或丢失任何事件。如果内部 FIFO 在 max_report_latency 到期之前已满,则会在此时报告事件,以确保不会丢失任何事件。

如果多个传感器共享同一个 FIFO,并且其中一个传感器的 max_report_latency 到期,则会报告 FIFO 中的所有事件,即使其他传感器的 max_report_latency 尚未到期。这减少了事件批量报告的次数。当必须报告一个事件时,会报告来自所有传感器的所有事件。

例如,如果激活了以下传感器

  • 加速度计批量处理,max_report_latency = 20 秒
  • 陀螺仪批量处理,max_report_latency = 5 秒

加速度计批次与陀螺仪批次同时报告(每 5 秒一次),即使加速度计和陀螺仪不共享同一个 FIFO。

挂起模式下的行为

批量处理对于在后台收集传感器数据而无需保持 AP 唤醒状态特别有益。由于传感器驱动程序和 HAL 实现不允许持有唤醒锁*,即使在收集传感器数据时,AP 也可以进入挂起模式。

当 AP 挂起时,传感器的行为取决于传感器是否为唤醒传感器。有关更多详细信息,请参阅唤醒传感器

当非唤醒 FIFO 填满时,它必须回绕并表现得像一个循环缓冲区,用新事件覆盖旧事件。max_report_latency 在挂起模式下对非唤醒 FIFO 没有影响。

当唤醒 FIFO 填满,或者当其中一个唤醒传感器的 max_report_latency 到期时,硬件必须唤醒 AP 并报告数据。

在这两种情况下(唤醒和非唤醒),一旦 AP 退出挂起模式,就会生成一个包含所有 FIFO 内容的批次,即使某些传感器的 max_report_latency 尚未到期。这最大限度地降低了 AP 在返回挂起模式后不久必须再次唤醒的风险,从而最大限度地降低了功耗。

*驱动程序不允许持有唤醒锁的一个值得注意的例外情况是,当具有连续报告模式的唤醒传感器在 max_report_latency < 1 秒的情况下激活时。在这种情况下,驱动程序可以持有唤醒锁,因为 AP 没有时间进入挂起模式,因为它会在到达挂起模式之前被唤醒事件唤醒。

批量处理唤醒传感器时的注意事项

根据设备的不同,AP 可能需要几毫秒才能完全退出挂起模式并开始刷新 FIFO。必须在 FIFO 中分配足够的预留空间,以允许设备退出挂起模式,而不会导致唤醒 FIFO 溢出。不得丢失任何事件,并且必须遵守 max_report_latency

批量处理非唤醒变化时报告模式传感器时的注意事项

变化时报告模式传感器仅在它们测量的值发生变化时才生成事件。如果测量值在 AP 处于挂起模式时发生变化,则应用程序希望在 AP 唤醒后立即收到事件。因此,如果变化时报告模式传感器与其他传感器共享其 FIFO,则必须谨慎执行非唤醒变化时报告模式传感器事件的批量处理。每个变化时报告模式传感器生成的最后一个事件必须始终保存在共享 FIFO 之外,这样它永远不会被其他事件覆盖。当 AP 唤醒时,在报告完 FIFO 中的所有事件后,必须报告最后一个变化时报告模式传感器事件。

这是要避免的情况

  1. 应用程序注册到非唤醒步数计数器(变化时报告模式)和非唤醒加速度计(连续模式),两者共享同一个 FIFO。
  2. 应用程序收到一个步数计数器事件 step_count=1000 steps
  3. AP 进入挂起模式。
  4. 用户行走 20 步,导致步数计数器和加速度计事件交错,最后一个步数计数器事件为 step_count = 1020 steps
  5. 用户长时间不动,导致加速度计事件继续在 FIFO 中累积,最终覆盖共享 FIFO 中的每个 step_count 事件。
  6. AP 唤醒,FIFO 中的所有事件都发送到应用程序。
  7. 应用程序仅收到加速度计事件,并认为用户没有行走。

通过将最后一个步数计数器事件保存在 FIFO 之外,即使所有其他步数计数器事件都被加速度计事件覆盖,HAL 也可以在 AP 唤醒时报告此事件。这样,应用程序在 AP 唤醒时会收到 step_count = 1020 steps

实现批量处理

为了节省功耗,批量处理必须在没有 AP 辅助的情况下实现,并且必须允许 AP 在批量处理期间挂起。

如果批量处理在传感器 hub 中执行,则应最大限度地减少传感器 hub 的功耗。

最大报告延迟可以随时修改,尤其是在指定的传感器已启用时;这不应导致事件丢失。

FIFO 分配优先级

在硬件 FIFO 和/或传感器 hub 缓冲区大小受限的平台上,系统设计人员可能必须选择为每个传感器保留多少 FIFO。为了帮助您做出此选择,以下是在不同传感器上实现批量处理时可能的应用列表。

高价值:低功耗行人航位推算

目标批量处理时间:1 到 10 分钟

要批量处理的传感器

  • 唤醒步数检测器
  • 5 Hz 的唤醒游戏旋转矢量
  • 5 Hz 的唤醒气压计
  • 5 Hz 的唤醒未校准磁力计

批量处理此数据允许执行行人航位推算,同时让 AP 进入挂起模式。

高价值:中等功耗间歇性活动/手势识别

目标批量处理时间:3 秒

要批量处理的传感器:50 Hz 的非唤醒加速度计

批量处理此数据允许定期识别任意活动和手势,而无需在收集数据时保持 AP 唤醒状态。

中等价值:中等功耗连续活动/手势识别

目标批量处理时间:1 到 3 分钟

要批量处理的传感器:50 Hz 的唤醒加速度计

批量处理此数据允许连续识别任意活动和手势,而无需在收集数据时保持 AP 唤醒状态。

中高价值:中断负载减少

目标批量处理时间:< 1 秒

要批量处理的传感器:任何高频传感器,通常是非唤醒传感器。

如果陀螺仪设置为 240 Hz,即使仅批量处理 10 个陀螺仪事件也可以将中断次数从 240 次/秒减少到 24 次/秒。

中等价值:连续低频数据收集

目标批量处理时间:1 到 10 分钟

要批量处理的传感器

  • 1 Hz 的唤醒气压计
  • 1 Hz 的唤醒湿度传感器
  • 其他类似速率的低频唤醒传感器

允许创建低功耗监控应用程序。

中低价值:连续全传感器收集

目标批量处理时间:1 到 10 分钟

要批量处理的传感器:所有唤醒传感器,以高频率

允许在将 AP 置于挂起模式的同时完整收集传感器数据。仅在 FIFO 空间不是问题时考虑。