在典型的手持式/便携式嵌入式系统设备中,电池寿命是硬件、软件和设备支持的功能设计中的一个主要考虑因素。 从软件编程的角度来看,人们知道MIPS,即内存(数据和程序)优化代码。
我知道硬件深度睡眠模式、待机模式用于以较低的周期为硬件提供时钟或将时钟完全转向一些未使用的电路以节省电量,但我正在从这个角度寻找一些想法:
我的代码正在运行,并且需要继续执行,鉴于此,我如何才能有效地编写代码“电源”以消耗最少的瓦数?
是否有任何特殊的编程结构、数据结构、控制结构,我应该考虑这些结构,以实现给定功能的最低功耗。
在代码结构设计时或在低级设计期间是否应该牢记任何软件高级设计注意事项,以使代码尽可能节能(功耗最低)?
In a typical handheld/portable embedded system device Battery life is a major concern in design of H/W, S/W and the features the device can support. From the Software programming perspective, one is aware of MIPS, Memory(Data and Program) optimized code.
I am aware of the H/W Deep sleep mode, Standby mode that are used to clock the hardware at lower Cycles or turn of the clock entirel to some unused circutis to save power, but i am looking for some ideas from that point of view:
Wherein my code is running and it needs to keep executing, given this how can I write the code "power" efficiently so as to consume minimum watts?
Are there any special programming constructs, data structures, control structures which i should look at to achieve minimum power consumption for a given functionality.
Are there any s/w high level design considerations which one should keep in mind at time of code structure design, or during low level design to make the code as power efficient(Least power consuming) as possible?
发布评论
评论(17)
1800 INFORMATION
所说,避免轮询; 订阅事件并等待它们发生并阅读其他一些指南。 ;)
最近一系列名为 “优化软件应用程序以提高功耗”,开始出现在英特尔软件博客上。 可能对 x86 开发人员有一定用处。
1800 INFORMATION
said, avoid polling; subscribe to events and wait for them to happenAnd read some other guidelines. ;)
Recently a series of posts called "Optimizing Software Applications for Power", started appearing on Intel Software Blogs. May be of some use for x86 developers.
Zeroith,使用完全静态的机器,可以在空闲时停止。 你无法击败零赫兹。
首先,切换到无滴答操作系统调度程序。 每毫秒左右唤醒一次会浪费电量。 如果不能,请考虑减慢调度程序中断速度。
其次,确保您的空闲线程处于省电状态,等待下一个中断指令。
您可以在大多数小型设备所拥有的不受监管的“用户区”中执行此操作。
第三,如果您必须轮询或执行用户信心活动(例如更新 UI),
睡觉,做,然后再睡觉。
不要相信那些没有检查过“睡眠和旋转”类型代码的 GUI 框架。
特别是您可能会想将事件计时器用于#2。
在读取时阻塞线程,而不是使用 select()/epoll()/WaitForMultipleObjects() 进行轮询。
给线程调度程序(和你的大脑)带来压力,但设备通常运行良好。
这最终会稍微改变你的高层设计; 它变得更整洁!
轮询您可能执行的所有操作的主循环最终会缓慢且浪费 CPU,但确实保证了性能。 (保证很慢)
缓存结果,懒惰地创建东西。 用户希望设备运行缓慢,所以不要让他们失望。 少跑步更好。 尽可能少跑。
当您不再需要单独的线程时,可以将其杀死。
尝试获得比您需要的更多的内存,然后您可以插入多个哈希表并保存搜索。 如果内存是 DRAM,这是一个直接的权衡。
查看比您认为可能需要的更实时的系统。 以后可以节省时间(原文如此)。
它们也能更好地处理线程。
Zeroith, use a fully static machine that can stop when idle. You can't beat zero Hz.
First up, switch to a tickless operating system scheduler. Waking up every millisecend or so wastes power. If you can't, consider slowing the scheduler interrupt instead.
Secondly, ensure your idle thread is a power save, wait for next interrupt instruction.
You can do this in the sort of under-regulated "userland" most small devices have.
Thirdly, if you have to poll or perform user confidence activities like updating the UI,
sleep, do it, and get back to sleep.
Don't trust GUI frameworks that you haven't checked for "sleep and spin" kind of code.
Especially the event timer you may be tempted to use for #2.
Block a thread on read instead of polling with select()/epoll()/ WaitForMultipleObjects().
Puts stress on the thread scheuler ( and your brain) but the devices generally do okay.
This ends up changing your high-level design a bit; it gets tidier!.
A main loop that polls all the things you Might do ends up slow and wasteful on CPU, but does guarantee performance. ( Guaranteed to be slow)
Cache results, lazily create things. Users expect the device to be slow so don't disappoint them. Less running is better. Run as little as you can get away with.
Separate threads can be killed off when you stop needing them.
Try to get more memory than you need, then you can insert into more than one hashtable and save ever searching. This is a direct tradeoff if the memory is DRAM.
Look at a realtime-ier system than you think you might need. It saves time (sic) later.
They cope better with threading too.
尽快完成工作,然后进入空闲状态等待中断(或事件)发生。 尝试以尽可能少的外部内存流量使代码耗尽缓存。
Do your work as quickly as possible, and then go to some idle state waiting for interrupts (or events) to happen. Try to make the code run out of cache with as little external memory traffic as possible.
还有一件并非易事的事情是降低数学运算的精度,寻求可用的最小数据集,如果您的开发环境可用,则打包数据和聚合运算。
knuth 书籍可以为您提供节省内存或 CPU 所需的特定算法的所有变体,或者以降低的精度最小化舍入误差
,也可以花一些时间检查所有嵌入式设备 api - 例如大多数 symbian 手机可以进行音频编码通过专门的硬件
also something that is not trivial to do is reduce precision of the mathematical operations, go for the smallest dataset available and if available by your development environment pack data and aggregate operations.
knuth books could give you all the variant of specific algorithms you need to save memory or cpu, or going with reduced precision minimizing the rounding errors
also, spent some time checking for all the embedded device api - for example most symbian phones could do audio encoding via a specialized hardware
简单来说,就是尽可能少做。
Simply put, do as little as possible.
好吧,如果您的代码可以完全在处理器缓存中执行,您将拥有更少的总线活动并节省电量。 如果您的程序足够小,可以将代码+数据完全放入缓存中,您就可以“免费”获得这种好处。 OTOH,如果您的程序太大,并且您可以将程序划分为或多或少相互独立的模块,则可以通过将其划分为单独的程序来节省一些电量。 (我想也可以制作一个工具链,将相关的代码和数据包分散到缓存大小的块中......)
我想,理论上,您可以通过减少指针取消引用的数量来节省一些不必要的工作,并重构你的跳转,以便首先执行最可能的跳转——但这对于程序员来说是不现实的。
Transmeta 的想法是让机器即时进行一些指令优化以节省电量...但这似乎没有足够的帮助... 看看它们是从哪里来的。
Well, to the extent that your code can execute entirely in the processor cache, you'll have less bus activity and save power. To the extent that your program is small enough to fit code+data entirely in the cache, you get that benefit "for free". OTOH, if your program is too big, and you can divide your programs into modules that are more or less independent of the other, you might get some power saving by dividing it into separate programs. (I suppose it's also possible to make a toolchain that spreas out related bundles of code and data into cache-sized chunks...)
I suppose that, theoretically, you can save some amount of unnecessary work by reducing the number of pointer dereferencing, and by refactoring your jumps so that the most likely jumps are taken first -- but that's not realistic to do as a programmer.
Transmeta had the idea of letting the machine do some instruction optimization on-the-fly to save power... But that didn't seem to help enough... And look where that got them.
将未使用的内存或闪存设置为 0xFF 而不是 0x00。 对于闪存和 eeprom 来说确实如此,但对于 s 或 d ram 则不确定。 对于 proms 来说,存在反转,因此 0 存储为 1 并消耗更多的能量,1 存储为 0 并消耗更少的能量。 这就是为什么在擦除块后读取 0xFF。
Set unused memory or flash to 0xFF not 0x00. This is certainly true for flash and eeprom, not sure about s or d ram. For the proms there is an inversion so a 0 is stored as a 1 and takes more energy, a 1 is stored as a zero and takes less. This is why you read 0xFFs after erasing a block.
今天 Hackaday 上关于测量各种命令的功耗的文章相当及时:
Hackaday:the-effect-of-code-功耗
除此之外:
- 中断是你的朋友
- 轮询 / wait() 不是你的朋友
- 尽可能少做
- 让你的代码尽可能小/高效
- 关闭微控制器中尽可能多的模块、引脚、外设
- 尽可能慢地跑
- 如果微控制器有引脚驱动强度、转换速率等设置,请检查它们并进行设置。 配置它们,默认值通常是全功率/最大速度。
-回到上面的文章,返回并测量功率和功率。 看看是否可以通过改变一些东西来放弃它。
Rather timely this, article on Hackaday today about measuring power consumption of various commands:
Hackaday: the-effect-of-code-on-power-consumption
Aside from that:
- Interrupts are your friends
- Polling / wait() aren't your friends
- Do as little as possible
- make your code as small/efficient as possible
- Turn off as many modules, pins, peripherals as possible in the micro
- Run as slowly as possible
- If the micro has settings for pin drive strengh, slew rate, etc. check them & configure them, the defaults are often full power / max speed.
- returning to the article above, go back and measure the power & see if you can drop it by altering things.
如果有低优先级的间歇性操作,不要使用特定的定时器来唤醒来处理它们,而是在处理其他事件时处理。
使用逻辑来避免愚蠢的情况,即您的应用可能会休眠 10 毫秒,然后必须再次唤醒以应对下一个事件。 对于所提到的平台类型,如果同时处理两个事件并不重要。
拥有自己的计时器和 回调机制可能适合这种决策。 权衡是代码复杂性和维护与可能的节能。
If you have low priority intermittent operations, don't use specific timers to wake up to deal with them, but deal with when processing other events.
Use logic to avoid stupid scenarios where your app might go to sleep for 10 ms and then have to wake up again for the next event. For the kind of platform mentioned it shouldn't matter if both events are processed at the same time.
Having your own timer & callback mechanism might be appropriate for this kind of decision making. The trade off is in code complexity and maintenance vs. likely power savings.
不要民意调查。 使用事件和其他操作系统原语来等待可通知的事件发生。 轮询可确保 CPU 保持活动状态并延长电池寿命。
Do not poll. Use events and other OS primitives to wait for notifiable occurrences. Polling ensures that the CPU will stay active and use more battery life.
根据我使用智能手机的工作,我发现保持电池寿命的最佳方法是确保禁用程序在该特定点运行所需的所有内容。
例如,只在需要时才打开蓝牙,与手机功能类似,不需要时调低屏幕亮度、调低音量等。
这些功能所消耗的电量一般会远远超过其他功能所消耗的电量。你的代码。
From my work using smart phones, the best way I have found of preserving battery life is to ensure that everything you do not need for your program to function at that specific point is disabled.
For example, only switch Bluetooth on when you need it, similarly the phone capabilities, turn the screen brightness down when it isn't needed, turn the volume down, etc.
The power used by these functions will generally far outweigh the power used by your code.
避免轮询是一个很好的建议。
微处理器的功耗大致与其时钟频率及其电源电压的平方成正比。 如果您可以通过软件调整这些,则可以节省一些电量。 另外,关闭不需要的处理器部分(例如浮点单元)可能会有所帮助,但这在很大程度上取决于您的平台。 无论如何,您需要一种方法来测量处理器的实际功耗,以便您可以找出哪些有效,哪些无效。 就像速度优化一样,功耗优化也需要仔细分析。
To avoid polling is a good suggestion.
A microprocessor's power consumption is roughly proportional to its clock frequency, and to the square of its supply voltage. If you have the possibility to adjust these from software, that could save some power. Also, turning off the parts of the processor that you don't need (e.g. floating-point unit) may help, but this very much depends on your platform. In any case, you need a way to measure the actual power consumption of your processor, so that you can find out what works and what not. Just like speed optimizations, power optimizations need to be carefully profiled.
考虑尽可能少地使用网络接口。 您可能想要收集信息并批量发送,而不是不断发送。
Consider using the network interfaces the least you can. You might want to gather information and send it out in bursts instead of constantly send it.
查看编译器生成的内容,尤其是代码的热门区域。
Look at what your compiler generates, particularly for hot areas of code.
在 Linux 上,安装 powertop 来查看哪个软件唤醒 CPU 的频率。 并遵循 powertop 站点链接到的各种提示,其中一些可能也适用于非 Linux。
http://www.lesswatts.org/projects/powertop/
On Linux, install powertop to see how often which piece of software wakes up the CPU. And follow the various tips that the powertop site links to, some of which are probably applicable to non-Linux, too.
http://www.lesswatts.org/projects/powertop/
选择快速且具有小基本块和最少内存访问的高效算法。
了解处理器的缓存大小和功能单元。
不要访问内存。 如果对象或垃圾收集或任何其他高级构造将您的工作代码或数据集扩展到可用缓存之外,请勿使用它们。 如果您知道缓存大小和关联性,请布置在低功耗模式下需要的整个工作数据集,并将其全部放入 dcache(忘记一些将数据分散在单独的对象或数据中的“正确”编码实践)结构(如果这会导致缓存垃圾)。 与所有子程序相同。 如有必要,请将您的工作代码集全部放入一个模块中,以便将其全部条带化到 icache 中。 如果处理器具有多级高速缓存,请尝试尽可能适应最低级别的指令或数据高速缓存。 不要使用浮点单元或任何其他可能为任何其他可选功能单元供电的指令,除非您可以证明使用这些指令可以显着缩短 CPU 退出睡眠模式的时间。
ETC。
Choose efficient algorithms that are quick and have small basic blocks and minimal memory accesses.
Understand the cache size and functional units of your processor.
Don't access memory. Don't use objects or garbage collection or any other high level constructs if they expands your working code or data set outside the available cache. If you know the cache size and associativity, lay out the entire working data set you will need in low power mode and fit it all into the dcache (forget some of the "proper" coding practices that scatter the data around in separate objects or data structures if that causes cache trashing). Same with all the subroutines. Put your working code set all in one module if necessary to stripe it all in the icache. If the processor has multiple levels of cache, try to fit in the lowest level of instruction or data cache possible. Don't use floating point unit or any other instructions that may power up any other optional functional units unless you can make a good case that use of these instructions significantly shortens the time that the CPU is out of sleep mode.
etc.
不要轮询,睡眠
尽可能避免使用芯片的耗电区域。 例如,乘数非常耗电,如果你可以移位和相加,你可以节省一些焦耳(只要你不做太多移位和相加,实际上乘数就是胜利!)
如果你真的很认真,我会得到一个功耗感知调试器,可以将功耗与源代码关联起来。 像这样
Don't poll, sleep
Avoid using power hungry areas of the chip when possible. For example multipliers are power hungry, if you can shift and add you can save some Joules (as long as you don't do so much shifting and adding that actually the multiplier is a win!)
If you are really serious,l get a power-aware debugger, which can correlate power usage with your source code. Like this