Linux内核的cpufreq(变频)机制.docx_第1页
Linux内核的cpufreq(变频)机制.docx_第2页
Linux内核的cpufreq(变频)机制.docx_第3页
Linux内核的cpufreq(变频)机制.docx_第4页
Linux内核的cpufreq(变频)机制.docx_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Linux内核的cpufreq(变频)机制linux低功耗研究也有一段时间了,基本把低功耗的实现方式想清楚了(主要分成机制和策略),这段时间的工作主要在机制上。暂时想实现的主要的机制有:cpu级,设备驱动级,系统平台级。管理颗粒度不断递增,形成三驾马车齐驱的形势。cpu级:主要实现比较容易的在系统处于目标在于频繁发生、更高粒度的电源状态改变,主要的实现方式为idle,包括今天的主要想讲的动态主频。设备驱动级:主要实现对单个设备驱动的管理(suspend,resume等),通过系统监测将闲置的设备,通过从用户态对sys文件目录动态进行单个驱动设备的管理,置于省电模式。系统平台级:目标在于管理较大的、非常见的重大电源状态改变,用于减少产品设备在长时间的空闲之后,减少电源消耗。主要实现方式是依托linux内核所支持的apm技术,实现整个系统的睡眠/恢复(sleep)这几个层次其实并不是相互独立的,都是相互交叉的,比如系统平台级的睡眠不可避免会涉及到cpu的sleep模式和设备驱动的挂起,而动态主频的实现除了cpu本身的支持也需要外围驱动随着主频变化做出相应的适应活动。因此这里的分级只是一种粗范围的,逻辑上的分层。前段时间还调研了一下IBM和Monta Vista搞得那套DPM(Dynamic Power Management)机制,看了不少论文和观点,总的感觉就是太过复杂而且也不是很实用,感觉噱头大过实际功效,(因此这套机制始终还不能进入内核的mainline),言归正传,还是重点讲述下cpufreq技术。一、为什么要cpufreq?关于要不要实现cpufreq技术,我也纠结过,一个原因是:当时对内核如何提供这么一套动态变频的机制还不了解,只觉得应该非常麻烦,因为涉及到外围驱动的参数更新,另外一个原因是:在SEP4020这种体量的处理器上跑linux,即使运行在最高频率时的处理能力可能也不是很富余,我再给它降频还有没有意义?挣扎之后还是觉得要实现它,我也给自己列了这么几条原因:1. 虽然cpu在板级中已不是主要的耗电源,但是仍然占着举足轻重的位置,功耗机制到最后就是几毫安几毫安的扣了,降频肯定能在一定程序上节约功耗那我为什么不采用?2. 细化功耗管理的颗粒度,为应用程序提供更多的功耗节省机制3. 对普通的应用,系统可以运行在维持平台运作的最低频率,在有处理任务时,变频机制会自动切换到合适的高主频,并且在任务结束时重回省电的低主频,这样就解决了我之前的第二个疑惑。 SEP4020在运行在88M时板级功耗为:222mA SEP4020在运行在56M时板级功耗为:190mA,降低14% SEP4020在运行在32M时板级功耗为:160mA,降低28%4.实现的一些工作是我们一直需要去做但是一直没有动力做的 变频会涉及到大量模块的参数的重新配置,作为cpu原厂,我们需要把这些参数彻底掌握 对这些参数的充分理解,能对现有系统进行优化,提升整体系统的效率,比如使用发现一些参数还是太过保守(sdram,nand),我们的通用配置在系统降为32M时仍能正常工作。5. 可行性论证没有问题:偶然看到armkiller同志提供的nand驱动代码中有变频的实现(这里非常感谢armkiller),网上这方面的文章很少,于是翻阅了linux内核源码中自带的/documentation/cpufreq后,对这种机制大概有一定的了解(linux中的documentation是个好东东),也看到了一些处理器厂商为自己的cpu已经实现了的代码,如sa1100,pxa系列。二、内核所提供的这种cpufreq技术的机制1. 目的:变频技术是指CPU硬件本身支持在不同的频率下运行,系统在运行过程中可以根据随时可能发生变化的系统负载情况动态在这些不同的运行频率之间进行切换,从而达到对性能和功耗做到二者兼顾的目的。2. 来源:虽然多个处理器生产厂家都提供了对变频技术的支持,但是其硬件实现和使用方法必然存在着细微甚至巨大的差别。这就使得每个处理器生产厂家都需要按照其特殊的硬件实现和使用方法向内核中添加代码,从而让自己产品中的变频技术在Linux中得到支持和使用。然而,这种内核开发模式所导致的后果是各个厂家的实现代码散落在Linux内核代码树的各个角落里,各种不同的实现之间没有任何代码是共享的,这给内核的维护以及将来添加对新的产品的支持都带来了巨大的开销,并直接导致了cpufreq内核子系统的诞生。3. 管理策略:Linux内部共有五种对频率的管理策略userspace,conservative,ondemand,powersave和performance performance:CPU会固定工作在其支持的最高运行频率上; powersave:CPU会固定工作在其支持的最低运行频率上。因此这两种governors都属于静态governor,即在使用它们时CPU的运行频率不会根据系统运行时负载的变化动态作出调整。这两种governors对应的是两种极端的应用场景,使用performance governor体现的是对系统高性能的最大追求,而使用powersave governor则是对系统低功耗的最大追求。 Userspace:最早的cpufreq子系统通过userspace governor为用户提供了这种灵活性。系统将变频策略的决策权交给了用户态应用程序,并提供了相应的接口供用户态应用程序调节CPU运行频率使用。(可以使用Dominik等人开发了cpufrequtils工具包) ondemand:userspace是内核态的检测,效率低。而ondemand正是人们长期以来希望看到的一个完全在内核态下工作并且能够以更加细粒度的时间间隔对系统负载情况进行采样分析的governor。 conservative:ondemand governor的最初实现是在可选的频率范围内调低至下一个可用频率。这种降频策略的主导思想是尽量减小对系统性能的负面影响,从而不会使得系统性能在短时间内迅速降低以影响用户体验。但是在ondemand governor的这种最初实现版本在社区发布后,大量用户的使用结果表明这种担心实际上是多余的,ondemand governor在降频时对于目标频率的选择完全可以更加激进。因此最新的ondemand governor在降频时会在所有可选频率中一次性选择出可以保证CPU工作在80%以上负荷的频率,当然如果没有任何一个可选频率满足要求的话则会选择CPU支持的最低运行频率。大量用户的测试结果表明这种新的算法可以在不影响系统性能的前提下做到更高效的节能。在算法改进后,ondemand governor的名字并没有改变,而ondemand governor最初的实现也保存了下来,并且由于其算法的保守性而得名conservative。Ondemand降频更加激进,conservative降频比较缓慢保守,事实使用ondemand的效果也是比较好的。4. Cpufreq在用户态所呈现的接口: cpuinfo_max_freqcpuinfo_min_freq:分别给出了CPU硬件所支持的最高运行频率及最低运行频率, cpuinfo_cur_freq则会从CPU硬件寄存器中读取CPU当前所处的运行频率。 Governor在选择合适的运行频率时只会在scaling_max_freq和scaling_min_freq所确定的频率范围内进行选择 scaling_cur_freq返回的是cpufreq模块缓存的CPU当前运行频率,而不会对CPU硬件寄存器进行检查。 scaling_available_governors会告诉用户当前有哪些governors可供用户使用 scaling_driver则会显示该CPU所使用的变频驱动程序 Scaling_governor则会显示当前的管理策略,往这个上echo其他类型会有相应的转变。 scaling_setspeed:需将governor类型切换为userspace,才会出现,往这个文件echo数值,会切换主频以下是将governor切换为ondemand后生成的ondemand文件夹下出现的配置文件。(conservative就不说了,不准备使用) sampling_rate:当前使用的采样间隔,单位:微秒 sampling_rate_min:允许使用的最短采样间隔 sampling_rate_max:允许使用的最长采样间隔 up_threshold:表明了系统负载超过什么百分比时ondemand governor会自动提高CPU的运行频率 ignore_nice_load:ignore_nice_load文件可以设置为0或1(0是默认设置)。当这个参数设置为1时,任何具有“nice”值的处理器不计入总处理器利用率。在设置为0时,所有处理器都计入利用率。 sampling_down_factor:5. 使用方法:cd sys/devices/system/cpu/cpu0/cpufreq/目录echo 32000 scaling_min_freq设置最小工作频率(khz,3200088000)/若想使用userspace策略# echo userspace scaling_governor切换工作方式为userspaceecho 64000 scaling_setspeed设置成想要的工作频率(khz)/若想使用ondemand策略# echo ondemand scaling_governor切换工作方式为ondemand三、如何实现?首先需要干一些杂活,修改kconfig makefile把系统屏蔽的cpufreq打开,对于我们来说主要的核心有两部分:系统相关:主要有cpu,timer(变了频率一定要更新系统timer,否则系统时间就不准了),sdram等。主要就是实现下面这个结构体:static struct cpufreq_driver sep4020_driver =.flags= CPUFREQ_STICKY,.verify= sep4020_verify_speed,.target= sep4020_target,.get= sep4020_getspeed,.init= sep4020_cpu_init,.name= SEP4020 Freq,;代码还是很简陋,很多细节都没考虑,所以具体的暂时先不讲了,大家可以先参考pxa和sa1100的实现。然后就是收频率影响的驱动:简单的来说就是:系统在变化cpu主频的时候会调用cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);函数,响挂载在这个cpu上所有的驱动发出一个信号,驱动接收到这个信号则调用相应的处理函数。这里把串口部分的实现简化,如下:#ifdef CONFIG_CPU_FREQstatic int sep4020_serial_cpufreq_transition(struct notifier_block *nb, unsigned long val, void *data)/printk(in the serial cpufreq_transitionn);int pmcr_pre;unsigned long cpu_clk,baud,baudh,baudl;pmcr_pre = *(volatile unsigned long*)PMU_PMCR_V;if(pmcr_pre 0x4000)cpu_clk = (pmcr_pre-0x4000)*8000000;elsecpu_clk = (pmcr_pre)*4000000;baud = cpu_clk/16/115200;baudh = baud 8;baudl = baud&0xff;*(volatile unsigned char*)UART0_LCR_V |= (0x80);*(volatile unsigned char*)UART0_DLBL_V= baudl;*(volatile unsigned char*)UART0_DLBH_V= baudh;*(volatile unsigned char*)UART0_LCR_V &= (0x80);printk(in the serial cpufreq_transitionn);return 0;static inline int sep4020_serial_cpufreq_register(void)sep4020_serial_freq_transition.notifier_call = sep4020_serial_cpufreq_transition;return cpufreq_register_notifier(&sep4020_serial_freq_transition,CPUFREQ_TRANSITION_NOTIFIER);static inline void sep4020_serial_cpufreq_deregister(void)cpufreq_unregister_notifier(&sep4020_s

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论