实际上,任何由编译器完成的“代码优化”,比未优化的代码计算答案更快,都是“节能”。(正如另一位发帖人所观察到的,避免缓存未命中是一大胜利)。所以真正的问题是,“哪些优化明确旨在节省能源,而不是减少执行时间?” (注意:一些“优化”减少了代码占用空间的大小(通过将代码序列抽象为子例程等);这实际上可能会消耗更多的能量)。
一个我在任何编译器中都没有见过的不寻常的方法是改变数据的表示。事实证明,存储/传输零位的成本与存储一位的成本不同。(我对 TTL 和 CMOS 的经验是“零”更昂贵,因为它们在硬件中实现为一种通过电源电阻的“有源下拉”,导致电流流动从而发热,而“一”是通过相同的下拉让信号“浮动高”来实现)。如果存在偏差,那么应该实现程序代码和数据以最大化 1 位的数量,而不是 0 位。
对于数据,这应该相对简单。有关内存中发现的价值的非常好的调查和分析,请参阅本文;它包含一些非常精彩的图表。一个常见的主题是大量内存位置被一小组不同值的成员占用。事实上,只有极少数的值(最多 8 个)占用了高达 48% 的内存位置,通常是非常小的数字(论文显示,对于某些程序,很大一部分数据传输是针对小值的,例如, 0 到 4,其中 0 基本上是最常见的值)。 如果 0 确实比 1 存储/传输更昂贵,那么小的常见值建议以它们的补码格式存储值. 这是一个非常容易实现的优化。鉴于这些值并不总是最小的 N 个自然值,可以用 N 替换内存中第 N 个最频繁的值并存储 N 的补码,查找更接近处理器的实际值。(该论文的作者建议使用硬件“值重用”缓存,但这不是编译器优化)。
这对于程序代码来说有点难以组织,因为指令集决定了你能说什么,而且通常指令集是独立于任何能量测量而设计的。然而,人们可以选择不同的指令序列(这就是优化器所做的)并最大化指令流中的一位。我怀疑这对传统的指令集操作码非常有效。一旦肯定可以将变量放置到地址具有大量一位的位置,并且更喜欢使用具有更高数字而不是更低数字的寄存器(在 x86 上,EAX 是二进制寄存器编号 000,EDI 是寄存器编号 111)从而根据指令执行频率设计指令集,为频繁执行的指令分配更多位的操作码。