查看原文
其他

CPU省电的秘密(一):EIST

Wolf UEFI社区 2023-12-29
点击上方“公众号” 可以订阅哦!

EIST-智能降频技术,它能够根据不同的系统工作量自动调节处理器的电压和频率,以减少耗电量和发热量。它的引入,大大节省了CPU在低工作量的能耗,受到极大欢迎,从此每一代Intel CPU上都有了它的身影。本文介绍了它的历史和工作原理

理论基础

CPU耗电量可以用下面这个公式来衡量:

很像质能方程有没有?其中C代表电容率(Capacitance),与CPU的制程和工艺等相关,在CPU出厂时就已经确定下来,是个常数(吐槽下,中文版的Wikipedia解释是错误的)。P是能耗(Power),F代表频率(frequency),V是电压(Voltage)。当CPU在很高的频率上运行时,效能很高但耗电量很大。如果我们能在CPU运算量不大时,让它降频运行,这样我们就可以减少公式中P的消耗,同时我们可以降低电压,从而更大的节约能耗,同时降低风扇等的噪音。如果这个降低不会降低用户使用体验,或者说用户几乎感觉不到,那何乐而不为呢?当然实际情况远比这个复杂,如果给定任务,更快的算完,CPU可以进入更省电的C state,而不会傻等,实际省电不会像这个近乎三次方的关系,但是在大多数情况下还是可以极大的节省耗电。这就是EIST能省电的理论基础。

历史

1

史前时代

它的由来很有一段历史了。话说,在很久很久以前,在遥远的地方,有一个古堡。。。。。咳咳,对不起,穿越了。在Intel的奔腾芯片早期时代(I, II),CPU开机就以固定频率运行,从不停歇。而人们大部分时间实际上是用不到CPU全部的算力的。因为笔记本电脑的特殊性,耗电问题尤为严重。


2

省电技术的引入

需求带来了研发的动力,在1999年后期,一项代号为Geyserville (GV)的技术被引入奔腾M系列CPU。在2000年1月,这项技术有了官方的名字:SpeedStep。从此它就开始了一段不平凡的演化之路:

·  SpeedStep (GV1.1)

最早被引入奔腾M III,也就是笔记本电脑版奔腾。原理十分简单:双模式工作--全功率模式和省电模式。插上电源时,全速工作;电池供电时,已几乎一半主频工作(当然可以手动切回全速模式)。

· Enhanced SpeedStep (GV2.1)

加入了根据工作量自动在两个主频间切换的功能。实际上CPU就可以工作在三种模式下了:省电模式,性能优先模式和自动模式。

· Enhanced SpeedStep (GV2.2)

加入了Deep Alert mode。可以已更低的电压工作在省电模式下。

·EIST(Enhanced Intel SpeedStep Technology,GV3)

这版做出了巨大的改进,从此不再是只有两种频率可以选择了,而是有一个范围可以选择,通常以100MHz为一个步进(Step)。举个例子,奔腾M 1.5GHz可以有1.5,1.4,1.3,1.2,1.1,1.0,0.9,0.8和0.7GHz可以选择。


从此EIST进入了稳定期,改进主要集中提供在更多的步进,和进入多核CPU后,降频的粒度上的改进。在后面原理部分有详细的介绍。

操作系统在接受EIST上也经历了一个过程,从最早的OS透明,全部由SMM完成(意味着延迟很大);到由硬件供应商(IHV)提供驱动;最后现代的OS已经全部自带全部支持,无需用户操心。而固件中EIST也从缺省的关闭,到缺省打开,SMM模式的EIST代码也已经从固件里面消失了。EIST功能现在不但出现在笔记本CPU中,在台式机和服务器CPU中也变成了必不可少的关键功能。

工作原理

首先我们要明白,OS主导了在整个EIST在的各个频率的切换,只有它最了解工作量。同时EIST要工作,硬件,固件和OS三方缺一不可。我们也就从这三个方面介绍它的工作原理。


1

硬件

Intel CPU是EIST可以工作的硬件基础。它通过一系列寄存器保证固件和OS可以得到足够的信息,有足够的手段控制EIST的工作模式。

2

固件

说到固件,不得不提到ACPI。ACPI全称Advanced Configuration and Power Interface,我们以后再详细介绍它,这里只需要知道它是固件和OS的电源管理接口和模型。其中ACPI规范定义了CPU的工作状态,包含S-States(这个是整个系统)、C-States和P-States三种,其中S-States(Sleeping states)指系统睡眠状态,C-States(CPU Power states)指CPU电源状态,而P-States(CPU Performance states)则指CPU性能状态。当然除了这三种外,还有G-States(全局状态)和D-States(设备状态)。整个关系如下图:



而EIST各个工作频率是通过在C0(C-states以后再介绍)下的各种P-states表现出来的。固件要支持EIST,至少需要做以下工作:


1)检测和打开/关闭EIST

固件可以通过CPUID来检测CPU是否支持EIST,如果不支持就没什么事了。如果支持的话,主要的步骤就是使用WRMSR去写IA32_MISC_ENABLES开启EIST。


2)计算各种EIST参数

当固件开启CPU EIST以后就需要计算出该CPU支持的各种参数,如MinRatio(MaxEfficiencyRatio) 、MaxRatio、RatioStepSize和NumStates,所有这些信息都可以通过CPU MSR直接或者间接的获得,其中MinRatio MaxRatio都可以从PLATFORM_INFO中获得(不同的bits),NumStates就是二者的差。CPU的工作频率 = BCLK * Ratio,旧架构的CPU BCLK通常是由clock gen给出的,通常上是100/200 MHZ。新架构下CPU clock gen是内置的,BCLK固定是100MHZ。

这里需要特别说明,在打开Turbo Mode(官方名字:睿频或智能加速技术,Intel Turbo Boost Technology),最高频率(即P0)要留给Turbo Mode。CPU会自动判断该使用什么样的频率。关于睿频和它的原理,不在本文的范围内。


3)填充各种ACPI的table


l.  _OSC & _PDC

_0SC(Operating System Details) & _PDC(Processor Driver Capabilities)在功能上比较接近,基本上供OSPM(

Operating System-directed configuration and Power Management,操作系统电源管理模块 )和OS驱动调用和固件传递一些关于P-state是否支持和实现方式的一些设定;另外关于_PSD Coordination Type也是有_PDC提供的。

II .  _PSS

Performance Supported States用于回报OSPM 该平台所支持的Processor Performance States的数量 并且通过一个packaged list的形式回报出该P-State的internal CPU core frequency、typical power dissipation、control register values、status register values。第0个package表示该平台所支持的最高的P-state,第n个package表示最低的P-state。Packaged lists的格式如下所示,其中需要说明的是关于Control和Status这两个参数,其中Control表示要写到 MSR IA32_PERF_CTRL中的值,Status用于当OSPM通过WRMSR 写完IA32_PERF_CTR之后再读取IA32_PERF_STATUS中的值并和Status做比较 以确定P-state切换是否已经完成。

前面部分已经提到如何计算MinRatio、MaxRatio、RatioStepSize、NumStates的值了,我们就可以将这些值填入_PSS packaged lists之中了。下面是一个_PSS的具体的例子,这个例子中MinRatio = 0x0c、MaxRatio = 0x10、RatioStepSize = 0x01、NumStates = 5。

Name (_PSS, Package()

      {

            Package(){1600, 21500, 10, 10, 0x0010, 0x0010},

            Package(){1500, 14900, 10, 10, 0x000F, 0x000F},

            Package(){1400, 8200,  10, 10, 0x000E, 0x000E} ,

            Package(){1300, 14900, 10, 10, 0x000D, 0x000D},

            Package(){1200, 8200,  10, 10, 0x000C, 0x000C} 

        }) // End of _PSS object

另外当该平台支持Turbo Mode时 P0将会report为Turbo Mode。

需要说明的是一般的做法是在SSDT中填入空的_PSS占位表,而当正式启动时,再根据前面的计算结果修改(Patch)入正确的值。


III._PCT

Performance Control用于将P-state MSR interface 报告给OSPM,OSPM通过_PCT 报告出来的操作切换P-states(OSPM不止运行在Intel CPU上),在过去,这里往往返回一个IO端口,用于陷入(trap)SMM,由固件来通过MSR切换不同的状态。在新近的CPU架构下_PCT通常report native mode也就是FFH的方式,然后OSPM就通过CPU 驱动(它知道要操作哪些MSR)来切换。

lV.  _PPC

 Performance Present Capabilities用于动态的告知OSPM该平台当前所支持的最高级别的P-state,它返回的值就是_PSS中的Packaged lists中的entry num,如_PPC return 0表示支持_PSS中report的所有的P-state [p0,pn]; return 1就表示支持[p1,pn]之间的P-state。


上面的逻辑通过程序看可能会更加直观。大家可以访问在Github上的Minnow3项目的源程序。

1)和2)的代码在https://github.com/tianocore/edk2-platforms/blob/devel-MinnowBoard3/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/PowerManagement/Dxe/PerformanceStates.c

3)的代码在https://github.com/tianocore/edk2-platforms/blob/devel-MinnowBoard3/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/AcpiTables/CpuSsdt/Cpu0Ist.asl


3

OS

如前所述,OS知道现在的工作量,由它来决定是不是要在各个P-states之间迁移。对Windows来说,其维护一个叫做电源策略管理器(power policy manager)的模块,在用户选择了不同的运行场景(可以调用powercfg.exe查看修改)情况下,根据目前工作量来调用processr.sys,这是个通用驱动,它再调用不同的CPU厂商的特有驱动来切换,Intel的EIST驱动是intelppm.sys,在Win10里你还可以找到它。需要指出的是,intelppm.sys并不是Intel产出的,他是微软为Intel CPU写的驱动,这和很多板卡驱动由硬件供应商来提供不同。Linux的支持始于Linux 2.6,由cpufreq来提供支持。

后记

所有的知识点都介绍完了,下面就是彩蛋部分了。前面提到的降频在粒度上的改进,是指每次降频的作用范围。过去一次降频需要整个Package里的所有core都进入同一频率,从而最高的可以下降的频率决定了最后频率(进入C-state的除外)。而在引入了内嵌的电压管理器后,不同的core可以进入不同的pstate(per core pstate),从而更加省电。这项技术需要固件对ACPI的Domain等做一些调整,而对OSPM是透明的。


一些有意思的分支话题我们可以深入思考一下:

1.    CPU在C0状态下有两种手段降低功耗的方法,其一是之前介绍过的P-state,另一个就是T-state。T-state全称就是Processor Throttling States,它为OSPM提供另一种降低系统负载和温度的能力,听上去可能和P-state很像,其实是有区别的,你知道是在哪里吗?

2.     AMD提供了类似技术:Cool 'n' Quiet。俗称冷又静,它和EIST的区别在哪里呢?



继续滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存