高效的软件编码

在典型的手持式/便携式embedded式系统设备中电池寿命是deviseH / W,S / W和设备所能支持的主要关注点。 从软件编程的angular度来看,人们知道MIPS,存储器(数据和程序)优化的代码。 我知道的H / W深度睡眠模式,待机模式,用于在较低的周期时钟的硬件时钟或整个时钟整个一些未使用circutis节省电力,但我从这个angular度寻找一些想法:

其中,我的代码正在运行,需要继续执行,因此,如何有效地编写代码“power”以便消耗最小的瓦特?

是否有任何特殊的编程结构,数据结构,控制结构,我应该看看,以实现给定function的最低功耗。

在代码结构devise时应考虑哪些高层次的devise考虑因素,或者在低层次devise中如何使代码尽可能节能(尽可能降低功耗)?

  • 1800 INFORMATION说,避免投票; 订阅事件并等待它们发生
  • 仅在必要时更新窗口内容 – 让系统决定何时重新绘制它
  • 更新窗口内容时,请确保您的代码尽可能less地重新创build无效区域
  • 通过快速代码,CPU可以更快地回到深度睡眠模式,这样的代码更有可能停留在L1caching中
  • 一次操作小数据,所以数据也保留在caching中
  • 确保你的应用程序在后台不做任何不必要的操作
  • 使您的软件不仅功率高效,而且还具有电源感知function – 在使用电池时更新显卡次数less,禁用animation,减less硬盘驱动器抖动

并阅读其他一些指导方针 。 ;)

最近,一系列名为“优化软件电源应用”的post开始出现在“英特尔软件博客”上。 可能对x86开发人员有用。

Zeroith,使用完全静态的机器,可以在闲置时停下来。 你不能击败零赫兹。

首先,切换到无滴答的操作系统调度程序。 唤醒每一毫秒左右的浪费电力。 如果您不能,请考虑减慢调度程序中断。

其次,确保你的空闲线程是省电,等待下一个中断指令。 您可以在大多数小型设备所具有的“用户空间不足”的情况下做到这一点。

第三,如果您必须轮询或执行更新用户界面的用户信任活动,请进入睡眠状态,然后重新进入睡眠状态。

不要相信你没有检查过“睡眠和旋转”types的GUI框架。 特别是您可能会尝试使用#2的事件计时器。

通过select()/ epoll()/ WaitForMultipleObjects()来读取而不是轮询时阻塞线程。 把重点放在线程模拟器(和你的大脑),但设备一般都没问题。 这最终会改变你的高层devise, 它变得更加整洁! 轮询所有你可能做的事情的一个主循环在CPU上慢慢浪费,但确保性能。 (保证慢)

caching结果,懒洋洋地创build事物。 用户期望设备速度慢,所以不要让他们失望。 less跑就更好。 尽可能less地运行。 当你停止需要它们时,单独的线程可以被杀死。

尝试获取比你需要更多的内存,然后你可以插入到多个哈希表,并保存search。 如果内存是DRAM,这是一个直接的折衷。

看看一个比你想象的更实时的系统。 它节省了时间(原文如此)。 他们也更好地应对线程。

不要投票。 使用事件和其他操作系统原语等待通知事件。 轮询可确保CPU保持活动状态并延长电池寿命。

从我使用智能手机的工作中,我发现保留电池寿命的最佳方法是确保您的程序在特定点上不需要的所有function都被禁用。

例如,只需要在需要时打开蓝牙function,类似于手机的function,在不需要时降低屏幕亮度,降低音量等。

这些function使用的功率通常远远超过您的代码所使用的功率。

避免投票是一个很好的build议。

微处理器的功耗大致与其时钟频率成正比,并与其电源电压的平方成正比。 如果你有可能从软件中调整这些,那可以节省一些电力。 另外,closures不需要的处理器部件(例如浮点单元)可能会有所帮助,但这非常依赖于您的平台。 在任何情况下,您都需要一种方法来测量处理器的实际功耗,以便了解哪些是有效的,哪些不是。 就像速度优化一样,功耗优化也需要仔细分析。

考虑最less使用networking接口。 您可能需要收集信息并以突发方式发送,而不是经常发送。

看看你的编译器产生了什么,特别是对于代码的热门领域。

如果您的间歇操作优先级较低,请不要使用特定的定时器来处理这些操作,而应该在处理其他事件时处理。

使用逻辑来避免愚蠢的情况,在这种情况下,您的应用可能会进入睡眠状态10 ms,然后必须再次唤醒以进行下一个事件。 对于提到的这种平台,如果两个事件同时被处理,这应该不重要。 有你自己的计时器和callback机制可能适合这种决策。 代码的复杂性和维护与可能的节能相比。

简而言之,尽可能less做。

那么,只要你的代码可以完全在处理器caching中执行,你将有更less的总线活动和节省电力。 如果程序足够小,可以将代码+数据完全放入caching中,则可以免费获得该优势。 OTOH,如果你的程序太大了,你可以把你的程序分成几个独立于另一个的模块,你可以通过将它分成不同的程序来节省一些功耗。 (我想也可以制作一个工具链,将相关的代码和数据捆绑到caching大小的块中)

我想,理论上来说,通过减less指针解引用的数量,并通过重构跳转,以便最有可能的跳转被首先进行,可以节省一些不必要的工作。但作为程序员来说,这是不现实的。

全美达有想让机器做一些指令优化,以节省电力…但是这似乎没有足够的帮助… 看看他们得到了什么。

将未使用的内存或闪存设置为0xFF而不是0x00。 对于flash和eeprom来说,这当然是正确的,不知道s或d ram。 对于proms有一个反转,所以0被存储为1并且需要更多的能量,1被存储为零并且更less。 这就是为什么擦除块后读取0xFFs的原因。

也不是微不足道的事情是降低math运算的精度,find可用的最小数据集,如果开发环境可用的话,打包数据和聚合操作。

knuth的书可以给你所有的具体algorithm的变种,你需要保存内存或CPU,或降低精度最小化舍入误差

还花了一些时间检查所有的embedded式设备API – 例如大多数Symbian手机可以通过专用硬件进行audio编码

尽快完成工作,然后进入一些空闲状态,等待中断(或事件)发生。 尝试使代码尽可能less的外部内存stream量运行caching。

在Linux上,安装powertop来查看哪个软件唤醒CPU的频率。 并遵循powertop网站链接的各种提示,其中一些可能适用于非Linux。

http://www.lesswatts.org/projects/powertop/

select快速且具有小块基本块和最小内存访问的高效algorithm。

了解您的处理器的caching大小和function单位。

不要访问内存。 如果在可用caching之外展开工作代码或数据集,则不要使用对象或垃圾回收或任何其他高级构造。 如果您知道caching大小和关联性,请在低功耗模式下布置所需的整个工作数据集,并将其全部纳入到dcache中(忘记一些“恰当的”编码实践,将数据分散在不同的对象或数据中结构,如果这会导致caching垃圾)。 和所有的子程序一样。 把你的工作代码全部放在一个模块中,如果有必要的话,把所有的代码都放在icache中。 如果处理器具有多级caching,则尽可能使用最低级别的指令或数据caching。 不要使用浮点单元或任何其他可能会启动任何其他可选function单元的指令,除非您能够很好地使用这些指令,从而显着缩短了CPU退出睡眠模式的时间。

等等

更恰当的是,今天关于Hackaday的关于测量各种命令的功耗的文章: Hackaday:代码功耗

除此之外:
– 中断是你的朋友
– 轮询/等待()不是你的朋友
– 尽可能less做
– 尽可能使您的代码尽可能小/高效
– closures尽可能多的模块,引脚,外设尽可能在微
– 尽可能慢地运行
– 如果微设置了引脚驱动强度,摆率等,检查并configuration它们,默认情况下通常是满功率/最大速度。
– 回到上面的文章,回去衡量权力,看看你是否可以通过改变的东西放弃它。

不要投票,睡觉

尽可能避免使用芯片中功耗较大的区域。 例如乘数是耗电的,如果你可以换class加点的话可以节省一些焦耳(只要你没有做太多的转换,并且增加乘数就是一个胜利!)

如果你真的认真,我得到一个功耗感知debugging器,它可以关联你的源代码的电源使用情况。 喜欢这个