Compiler construction 有谁知道有哪种编译器可以优化嵌入式设备的能耗代码?

Compiler construction 有谁知道有哪种编译器可以优化嵌入式设备的能耗代码?,compiler-construction,computer-architecture,energy,Compiler Construction,Computer Architecture,Energy,一般认为,更快的代码将消耗更少的电力,因为您可以将CPU置于空闲状态更长的时间,但当我们谈论能耗时,有以下一种可能性: 假设有一个指令序列在1ms内执行,在执行过程中,平均电流消耗为40mA。你的Vdd是3.3V 所以总能量消耗=V*I*t=3.3*40*10^-3*1*10^-3焦耳=13.2*10^-6焦耳 在另一种情况下,有一个指令序列在2ms内执行,在执行过程中,平均电流消耗为15mA。Vdd为3.3V 所以总能量消耗=V*I*t=3.3*15*10^-3*2*10^-3焦耳=9.9*1

一般认为,更快的代码将消耗更少的电力,因为您可以将CPU置于空闲状态更长的时间,但当我们谈论能耗时,有以下一种可能性:

假设有一个指令序列在1ms内执行,在执行过程中,平均电流消耗为40mA。你的Vdd是3.3V

所以总能量消耗=V*I*t=3.3*40*10^-3*1*10^-3焦耳=13.2*10^-6焦耳

在另一种情况下,有一个指令序列在2ms内执行,在执行过程中,平均电流消耗为15mA。Vdd为3.3V

所以总能量消耗=V*I*t=3.3*15*10^-3*2*10^-3焦耳=9.9*10^-6焦耳

所以问题来了。是否有任何架构具有不同的指令集,用于以不同的电流消耗执行相同的任务


如果有……那么有没有编译器考虑到这一点并生成一个节能的代码?

据我所知,没有一个编译器是节能的,但我认为这应该可以使用类似LLVM的编译器框架,通过调整指令调度程序的加权算法来实现


编辑:在FOSDEM上有一个讨论。

在单个指令级别,像移位而不是乘法这样的事情肯定会降低电流,从而降低能耗,但我不确定我是否同意你的例子,即使用两倍的时间,但使用一半的电流(对于给定的时钟频率)。将乘法替换为移位和加法(使时间加倍)真的需要一半的电流吗?CPU中有太多其他的东西(只是芯片上的时钟分配需要电流),我认为背景电流的使用占主导地位

降低时钟频率可能是降低功耗所能做的最大的一件事。尽可能多地并行工作是降低时钟频率的最简单方法。例如,在显式中断上使用DMA允许算法处理在更少的周期内完成。如果您的CPU有奇怪的寻址模式或并行指令(我在看您,TMS320),如果您不能将紧循环的执行时间减半,以使电流降低一倍,从而实现净节能,我会感到惊讶。在Blackfin系列CPU上,降低时钟可以降低核心电压,从而显著降低功耗。我想在其他嵌入式处理器上也是如此

在时钟频率之后,我打赌功耗主要由外部I/O访问控制。在低功耗环境中,缓存未命中之类的事情会对您造成两次伤害—一次是在速度上,一次是在进入外部内存时。例如,循环展开可能会使事情变得更糟,因为它会使乘法所需的指令数加倍

所有这一切都意味着,创造性的系统架构可能比告诉编译器偏爱一组指令而不是另一组指令对电源的影响更大。但是我没有数字来支持这一点,我会很好奇地看到一些。我没有编译器的第一手经验。但网站上的描述表明,可以生成节能代码。

事实上,编译器完成的任何“代码优化”都是“节能”的,它比未优化的代码计算速度更快。(正如另一张海报所观察到的,避免缓存未命中是一个巨大的胜利)。因此,真正的问题是,“哪些优化明确旨在节约能源,而不是减少执行时间?”(注意:一些“优化”减少了代码占用空间大小(通过将代码序列抽象为子例程等);这实际上可能会消耗更多能源)

一个我在任何编译器中都没有见过的不寻常的例子是改变数据的表示形式。事实证明,存储/传输零位的成本不同于存储一位的成本。(我对TTL和CMOS的经验是,“零”更昂贵,因为它们在硬件中通过来自电源的电阻器作为一种“主动下拉”实现,导致电流流动从而发热,而“零”是通过让信号通过相同的下拉“浮高”实现的)。如果存在偏差,则应实现程序代码和数据,以最大化一位的数量,而不是零位

对于数据,这应该是相对简单的。有关内存中发现的值的非常好的调查和分析,请参阅;它包含一些非常精彩的图表。一个常见的主题是,大量内存位置被一小组不同值的成员占用。事实上,只有非常少的值(最多8个)占据了48%的内存位置,通常是非常小的数字(论文显示,对于某些程序,数据传输的很大一部分是针对小值的,例如0到4,零基本上是最常见的值)。如果零的存储/传输成本确实比1高,那么较小的公共值建议以其1补码格式存储值。这是一个非常容易实现的优化。假设这些值并不总是最小的N个自然值,可以用N替换内存中第N个最频繁的值,并存储N的补码,查找更接近处理器的实际值。(论文作者建议使用硬件“值重用”缓存,但这不是编译器优化)

这对于程序代码来说有点难组织,因为指令集决定了你能说什么,并且通常指令集是独立于任何能量测量而设计的。然而,人们可以选择不同的指令序列(优化器就是这么做的),并在指令流中最大化一位。我怀疑这在传统指令集操作码上是否非常有效。