每个系统要正常运行都有赖于CPU 的性能, 系统软件, 中间件一集各种系统策略等等,智能手机也是一样。这篇文章主要探讨了给智能手机选择合适的CPU, 以及在手机电源管理中的动态电源管理(DPM) 和自适应电压调整(AVS) 技术。最后, 我还对手机软件设计进行一点优化工作, 实现了软件的节能设计。
关键词: Linux;嵌入式系统;智能手机
引言
智能手机中包含了很多耗能设备, 诸如MP3、MPEG- 4、Wi-Fi、数码相机、3D 游戏等等。在手机电池容量还没有实现质的飞跃的前提下, 我们不得不考虑手机电源节能的问题。我主要通过了以下四个方面来阐述在基于Linux 平台上的智能手机的解决方案。
CPU 的选择
尽管现在有了各种在不过多加重功耗负担的前提下提高性能的技术, 但用一个芯片来处理这么多各种各样的任务, 恐怕已经不是一个很好的选择了。一是因为这些功能对芯片处理功能的要求可能各不相同, 二是因为一个负担着如此众多任务的芯片势必需要很高的速度, 降低功耗变得很困难。
在这种情况下, 多CPU 系统(MPCore)成为一个必然的趋势。多CPU 系统的一个明显的优势是: 针对不同的任务处理需要, 不同的CPU 可以各尽其职, 将自身的优势充分发挥, 由此带给手机最优化的性能表现。另一个优势显然还是体现在对功耗的控制上: 假如用单CPU 来完成所有的功能, 不可避免地需要一个很高的CPU 速度, 从而造成很高的功耗。用一颗高速CPU 来完成这样的任务, 无疑是大牛拉小车, 同时浪费很多能源。多CPU 系统可以根据不同的任务需要合理地启动、停止相应的CPU 来完成任务,不需要的时候处于停歇状态, 实现最大限度地控制功耗。
既然我们选择了多CPU 的架构, 那么接下来CPU 的性能就是我们要考虑的第二大问题。一般的情况下, 我们是在CPU 的性能( Performance) 和功耗(PowerConsumption) 方面进行比较和选择。通常可以采用每执行1M次指令所消耗的能量来进行衡量, 即Watt/MIPS。
我们把CPU 的功率消耗分为两大部分: 内核消耗功率PCORE和外部接口控制器消耗功率PI/O, 总的功率等于两者之和, 即PPCORE+PI/O。对于PCORE, 关键在于其供电电压和时钟频率的高低; 对于PI/O 来讲, 除了留意各个专门I/O 控制器的功耗外, 还必须关注地址和数据总线宽度。
在数字集成电路设计中, CMOS 电路的静态功耗很低, 与其动态功耗相比基本可以忽略不计。CMOS 电路动态功耗的计算公式如下:
Pd=CT*V2*f, 其中Pd 是CMOS 芯片的动态功耗, C是CMOS芯片的负载电容, V 是CMOS 芯片的工作电压, f 是CMOS 芯片的工作频率。
由上可见, 当CPU 确定后, 我可以通过降低频率和电压来减少系统的功耗。
在CPU 的选择方面, 我们推荐采用Intel的Xscale 芯片, 以及IBM的PowerPC405G 芯片。
动态电源管理(DPM)
系统不可能始终处于满负荷状态, 因为系统的工作量随时都在改变。动态电源管理(DPM) 通过选择性的将空闲的系统组件置于低能耗状态实现了系统整体能耗的最优化。
我们更为关注的是DPM在Linux 框架结构下的实现。图1 展示了电源管理和嵌入式Linux 堆栈之间的关系。
以下是一些于电源管理相关的接口以及API:
内核接口。在针对Linux 的DPM 架构中, 内核中的DPM 子系统负责维持系统的电源状态, 并把DPM 系统的各个电源得到管理的元件联系在一起。DPM 子系统通过多个API 直接与设备驱动程序通信, 这些API 把驱动程序从完全运行状态转为各种电源得到管理的状态。策略管理器( 或应用软件自身) 通过多个API向DPM 子系统提供指导, 这些API 定义各种策略, 并在定义好的运行点之间转移整个系统。
驱动程序接口。启用了DPM 的设备驱动程序比默认驱动程序具有更多“状态”: 由外部事件通过各种状态来驱动它们, 或通过来自内核DPM 子系统的回调来驱动它们, 从而反映并遵循运行策略。驱动程序API 还允许驱动程序登记它们连接和管理的各个设备的基本运行特征, 从而实现更精细的策略决策。
用户程序API, 用户程序( 应用软件) 分为三类:
(1)可感知电源管理的应用软件; (2)可感知电源管理的“包装器”中的传统应用软件; (3)不带电源管理的传统应用软件。
可感知电源管理的应用软件能够充分利用来自策略管理器的API, 从而建立各自的基础约束, 并强制电源管理策略发生变化, 以便匹配各自的执行要求。不直接带有电源管理功能的传统应用软件可以“包装”到代码或补丁中, 从而实现相当的效果, 它们还可以按照默认行为来运行, 这取决于更宽范围的默认策略管理。
嵌入式Linux DPM 下的实际机制包括各种API, 比如dpm_set_os ()( 内核) 、assert_constraint ()、remove_constraint () 和set_operating_state () ( 内核和驱动程序) 、set_policy () 和set_task_state()( 经由系统调用的用户级接口) , 以及/proc 接口。
电源管理策略在系统电源管理中扮演了极为关键的角色。DPM的策略抽象模型的执行体系类似于状态机。在DPM中有2个概念很重要: 一个是执行点(operating points), 另一个是执行状态( operating states) 。DPM的执行点来自一些独立的系统参数, 包括执行电压, 频率, 以及总线带宽等等。随着事件的改变, 系统的状态也不断的改变( 如图2 所示) 。在DPM中, 每个系统状态都是一个执行状态, 包括空闲态、活动态和睡眠态。
自适应电压调整(AVS)
在CPU 的选择部分, 我们知道了系统能耗是与电压和频率紧密相关的。现在我们来探讨一下调整电压在降低能耗方面的作用。在电压调整方面, 自适应电压调整是一种很有效的方法。自适应电压调整AVS(Adaptive Voltage Scaling)是通过反馈机制将电源电压调整到给定工作负载(处理量)所需的最小值。这种闭环方式可进一步减小功耗, 但需要将部分电源管理电路置入主处理器。
成功实现AVS 的关键是在基带芯片中集成部分系统电源管理电路, 即内置AVS 控制器(图3)。这一关键模块包含专门的电路和算法, 用来确定给定处理量下的最优电压。通过向电压调整器的参考端输入馈送误差信号, 可以生成最优的VDD, 无需提供不必要的电压余量, 从而减少了电能损耗。对任何闭环方法来说, 环路带宽都是很重要的。环路快速跟踪并稳定的能力决定了基带电源动态调整以自适应工作负载突变的能力。
通过软件方法降低设备功耗
低能耗软件优化对于基于处理器系统的应用程序而言, 是最有发展前途的降低系统能耗的技术方法。这种方法对于那些计算复杂度较高的应用程序最为有效。因为只有在应用程序执行的时候, 才会消耗大量电源。
这项技术的最终目的是在执行较为复杂的应用程序时, 尽量降低能耗。我们的程序用于降低计算的复杂度, 但不能改变程序原本的行为。现在我们通过图4(A) 中的例子, 来阐述一下一些有关软件优化的想法。
考虑主函数中第一次调用过程test。如果档参数a 和差数k都是0 的概率为90%, 我们可以将源代码改写为图4(B) , 通过改写, 我们减少了test 过程中的循环数。但在现实中, 参数a 和k 并不是总是为0。那么test 的过程调用不能被新的过程sp_test 所完全替代。我们用一个条件语句来限定过程的调用, 所有的过程调用依赖于cvd_test()的结果。当过程cvd_test()检测为一般情况( a,k同时为0) , 符合此条件的修正后的代码被执行。如果当过程cvd_test()检测为非一般情况( a,k 非同时为0) , 原有的代码被执行。在另一方面, 当过程cvd_test()检测为非一般情况, 我们提升了程序的计算复杂度, 也相应提高了能耗。
一般而言, 对代码优化有各种各样不同的方法。如果我不考虑参数k, 我们可以将源代码转化为图4(C) 所示。a 为0 的概率大于a 和k 同时为0 的概率。在不同情况下, 对原有代码所做的修改有不同的效果。
最后, 我们必须检验修改过的代码对原有代码的影响, 是不是改变了原有代码的行为, 在任何条件下我们都不能去擅自改变原有代码的行为。代码质量的提升也是相当的重要的。对于C 语言来说, 将一些简单的函数转换为宏定义时一种比较有效的方法。
综上所述, 我们可以将一般情况下代码优化分为4 个步骤:
(1)一般案例的选择。选择最有效的、最长被调用的案例。
(2)一般案例的提炼。为给出的一般案例建立一个过程。
(3)全局检测。检测改变后的调用对于全局的影响。
(4)提高代码质量。使用一些编程语言中的基本技巧, 以提高代码质量。
总结
在移动终端设备设计方面, 节能成为了一个很重要的设计指标。我们选取了更高效的CPU 以降低能耗。对于交互式应用程序而言, 我们使用DPM策略降低处于空闲态的能耗, 这种方法主要使用于OS 层。而AVS 技术是通过电压调整来实现减少能耗。在应用程序层, 我们通过对软件的优化来达到降低能耗的目的。在Intel? PXA27x 处理芯片环境下, 通过以上方法, 我们降低了26%的能耗, 提高了30%的系统性能以及增加了7%的代码量。