高效的软件编码

时间:2008-09-15 05:06:06

标签: power-management embedded

在典型的手持/便携式嵌入式系统设备中,电池寿命是设计H / W,S / W以及设备可支持的功能的主要问题。从软件编程的角度来看,人们了解MIPS,内存(数据和程序)优化代码。 我知道H / W深度睡眠模式,待机模式用于为较低周期的硬件提供时钟或将时钟全部转换为一些未使用的电路以节省电力,但我从这个角度寻找一些想法:

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

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

是否存在任何s / w高级设计注意事项,在编码结构设计时应该记住这些注意事项,或者在低级设计期间要使代码尽可能节省能源(最少功耗)?

17 个答案:

答案 0 :(得分:22)

  • 如同1800 INFORMATION所说,避免投票;订阅活动并等待它们发生
  • 仅在必要时更新窗口内容 - 让系统决定何时重绘
  • 更新窗口内容时,请确保您的代码尽可能少地重新创建无效区域
  • 使用快速代码,CPU可以更快地返回深度睡眠模式,并且此类代码更有可能保留在L1缓存中
  • 一次操作小数据,因此数据也保留在缓存中
  • 确保您的应用程序在后台不执行任何不必要的操作
  • 使您的软件不仅节能,而且还具有电源感知功能 - 在使用电池时更少显示图形,禁用动画,减少硬盘抖动

并阅读其他一些guidelines。 ;)

最近,一系列名为"Optimizing Software Applications for Power"的帖子开始出现在英特尔软件博客上。可能对x86开发人员有用。

答案 1 :(得分:9)

Zeroith,使用可以在空闲时停止的完全静态机器。你无法击败零赫兹。

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

其次,确保您的空闲线程是省电模式,等待下一个中断指令。 你可以在大多数小型设备都处于监管不足的“用户空间”中这样做。

第三,如果您必须轮询或执行用户信心活动,例如更新UI, 睡觉,做,然后回去睡觉。

不要相信您没有检查过“睡眠和旋转”类代码的GUI框架。 特别是您可能想要用于#2的事件计时器。

使用select()/ epoll()/ WaitForMultipleObjects()在读取时阻塞线程而不是轮询。 强调线程计量器(和你的大脑),但设备通常没问题。 这最终会改变你的高级设计;它变得更整洁! 轮询所有你可能做的事情的主循环最终会在CPU上缓慢而浪费,但确实可以保证性能。 (保证慢)

缓存结果,懒洋洋地创建东西。用户希望设备速度慢,所以不要让他们失望。减少运行更好。尽可能少地跑步。 当您停止需要它们时,可以终止单独的线程。

尝试获得比您需要的更多内存,然后您可以插入多个哈希表并保存搜索。如果内存是DRAM,这是一个直接的权衡。

查看一个比您认为可能需要的实时系统。它可以节省时间(原文如此)。 他们也更好地应对线程化。

答案 2 :(得分:5)

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

例如,只在需要时打开蓝牙,类似手机功能,在不需要时关闭屏幕亮度,关闭音量等等。

这些功能使用的功率通常远远超过代码使用的功率。

答案 3 :(得分:5)

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

答案 4 :(得分:3)

避免民意调查是一个很好的建议。

微处理器的功耗大致与其时钟频率和电源电压的平方成正比。如果您有可能从软件中调整这些,那么可以节省一些电力。此外,关闭不需要的处理器部件(例如浮点单元)可能有所帮助,但这在很大程度上取决于您的平台。在任何情况下,您都需要一种方法来测量处理器的实际功耗,以便您可以找出哪些有效,哪些无效。就像速度优化一样,需要仔细分析功耗优化。

答案 5 :(得分:1)

尽量少考虑使用网络接口。您可能希望收集信息并以突发方式发送,而不是经常发送。

答案 6 :(得分:1)

查看编译器生成的内容,特别是对于热门代码区域。

答案 7 :(得分:1)

如果你有低优先级的间歇性操作,不要使用特定的定时器来唤醒它们,而是在处理其他事件时处理。

使用逻辑来避免愚蠢的情况,在这种情况下,您的应用可能会睡眠10毫秒,然后必须再次唤醒以进行下一个事件。对于所提到的那种平台,如果同时处理这两个事件应该无关紧要。 拥有自己的计时器和回调机制可能适合此类决策。权衡取决于代码复杂性和维护与可能的节能。

答案 8 :(得分:1)

简单地说,尽量少做。

答案 9 :(得分:1)

嗯,如果您的代码可以完全在处理器缓存中执行,那么您将减少总线活动并节省电量。如果您的程序足够小以完全将代码+数据放入缓存中,那么您将获得“免费”的好处。 OTOH,如果您的程序太大,并且您可以将程序划分为或多或少独立于另一个的模块,则可以通过将其划分为单独的程序来节省一些功率。 (我想也可以制作一个工具链,将相关的代码和数据包分成缓存大小的块......)

我认为,从理论上讲,你可以通过减少指针解除引用的次数来节省一些不必要的工作,并通过重构你的跳转来最大限度地跳转 - 但这对程序员来说是不现实的。 。

Transmeta的想法是让机器在运行中进行一些指令优化以节省电力......但这似乎没有足够的帮助...... And look where that got them.

答案 10 :(得分:1)

将未使用的内存或闪存设置为0xFF而不是0x00。这对于flash和eeprom来说肯定是正确的,不确定s或d ram。对于舞会有一个倒置,所以0被存储为1并且需要更多的能量,1被存储为零并且需要更少。这就是在擦除块后读取0xFF的原因。

答案 11 :(得分:0)

不要投票,睡觉

尽可能避免使用芯片的耗电区域。例如,乘数很耗电,如果你可以移动并添加你可以节省一些焦耳(只要你不做那么多移动并添加实际上乘数就是胜利!)

如果你真的很认真,我会得到一个功耗感知的调试器,它可以将电源使用与源代码相关联。 Like this

答案 12 :(得分:0)

相当及时的这篇关于Hackaday的文章今天关于测量各种命令的功耗: Hackaday: the-effect-of-code-on-power-consumption

除此之外:
- 中断是你的朋友
- 轮询/等待()不是你的朋友
- 尽量少做
- 使您的代码尽可能小/高效
- 在微型计算机中尽可能多地关闭模块,引脚和外围设备
- 尽可能慢地跑
- 如果微控制器具有引脚驱动强度,转换速率等设置,请检查它们。配置它们,默认值通常是全功率/最大速度。
- 返回上面的文章,返回并测量功率&看看你是否可以通过改变来放弃它。

答案 13 :(得分:0)

选择快速且基本块较小且内存访问量最少的高效算法。

了解处理器的缓存大小和功能单元。

不要访问内存。如果它们在可用缓存之外扩展您的工作代码或数据集,请不要使用对象或垃圾收集或任何其他高级构造。如果您知道缓存大小和关联性,请在低功耗模式下布置您需要的整个工作数据集,并将其全部放入dcache中(忘记一些在单独的对象或数据中分散数据的“正确”编码实践结构,如果这导致缓存废弃)。与所有子程序相同。如果需要,将您的工作代码集全部放在一个模块中,以便在icache中对其进行全部条带化。如果处理器具有多级缓存,请尽量适应最低级别的指令或数据缓存。不要使用浮点单元或任何其他可能启动任何其他可选功能单元的指令,除非您能够说明使用这些指令可以显着缩短CPU退出睡眠模式的时间。

答案 14 :(得分:0)

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

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

答案 15 :(得分:0)

尽快完成工作,然后进入等待中断(或事件)的空闲状态。尝试使用尽可能少的外部内存流量使代码耗尽缓存。

答案 16 :(得分:0)

同样重要的是降低数学运算的精度,寻找可用的最小数据集,以及开发环境包数据和聚合运算可用的数据集。

knuth books可以为您提供保存内存或CPU所需的特定算法的所有变体,或者降低精度以最小化舍入误差

还花了一些时间检查所有嵌入式设备API - 例如,大多数symbian手机可以通过专用硬件进行音频编码