一、引言

计算机的世界里,CPU任务分为CPU bound和IO bound。而实际场景下往往是两者混合型任务。针对性能的优化,普遍关注点都在CPU上(不论是CPU的频点和CPU的选核), 往往忽略对IO bound的任务的优化。而DDR作为SOC芯片代码运行空间和数据缓存空间,在不同应用状态下,SOC对DDR访问的带宽需求不一样。譬如听音乐时访问带宽需求较小,此时DDR工作在较低的频率,而通过网络信号观看高清视频时,则对带宽需求较大。DDR则需要提高工作频率。由此可见,SOC需要根据系统的运行情况动态调整DDR的总线工作频,以提高CPU工作效率,并降低系统在运行状态的功耗,达到性能功耗的平衡。

二、BUS DCVS

什么是BUS DCVS?

BUS DCVS,其 Bus Dynamic Clock and Voltage Scaling 的缩写,它是一种总线频率选择的算法,用于在动态的工作负载间选择最佳的频率点,以满足性能和功耗的平衡。

先来看看现代SOC架构,对于DDR这个slave而言,其对应的master会很多,例如 CPU,GPU,NPU,DISPLAY,CAMERA 等等。每隔一段时间各个master就会给你自己对带宽的需求,最终由RPM汇总仲裁后设定最终的DDR频率。

本文主要介绍主流平台CPU的BUS DCVS策略

以上图所示架构,BUS DCVS主要是根据L2->L3,L3->system cache,System 和cache->DDR 等路径上对带宽的需求,选择最合适的频点以达到功耗和性能的平衡。

Bus DCVS 提供了2种调频策略

1. bw_hwmon (bandwidth hardwaremonitor)

基于CPU到cache 和 cache 到 DDR 的流量带宽调整cache 和 DDR的频率

2. memlat(memory latency)

基于 cache和 DDR 的 CPU 相关统计数据来调整相应频率。

三、BUS DCVS 软件架构

BUS DCVS分为3个大部分

  1. User space (用户空间)

表现形式为sysfs 节点。路径为/sys/class/devfreq/socddr-bw和/sys/class/devfreq/socddr-lat(分别对应2种不同的策略方式)。当然还有devfreq的标准节点,min_freq/max_freq/cur_freq。用户空间的软件可以通过访问对应的文件获取当前master 对 DDR的带宽需求。如果具有某些权限,设置可以通过设置相应的参数来控制当前master 对 DDR 带宽需求的策略

  1. Kernel space(内核空间)

CPU 的BUS DCVS与其他的非CPUFreq调频的外设一样,是基于devfreq 框架的一套机制。其核心为devfreq framework,设备的抽象为bimc-bwmon 和arm-memlat-mon,策略的抽象为governor bw_hwmon 和 memlat。

  1. RPM OS

其主要作用是手机各个master voted的ddr 带宽,最终设定DDR的频率到LPDDR的硬件上。

四、bw_hwmon策略

1. 源码路径

a) drivers/devfreq/devfreq_devbw.c

b) drivers/devfreq/bimc-bwmon.c

c) driver/devfreq/governor_bw_hwmon.c

d) arch/arm64/boot/dts/vendor/qcom/

2. bw_hwmon软件框图

bw_hwmon策略涉及到的模块大致分为 devbw,bimc-bwmon,和devfreq framework。

a)  bimc-bwmon:其代表代表 BIMC带宽监视器的设备,可用于测量来自 BIMC 主端口的读/写流量的带宽。

b) devbw:master对ddr slave的带宽需求

c) devfreq framework:非 CPU 设备的通用动态电压和频率缩放 (DVFS) 框架bw_hwmon调频策略的触发时机

d) 根据时间片轮询查看单位时间窗口的平均带宽

e) 根据配置带宽上升下降的阈值作为触发点,一旦在单位时间内上升或者下降过快,则触发中断通知更新频率

基于上述的触发时机,bimc-bwmon收到硬件监测到的带宽信息,根据软件的计算规则,预估需要调整的带宽,将其下发至devbw匹配OPP表,将需要的频率通过RPM驱动发送到RPM core,根据多个master对带宽的需求最终决策DDR需求的频率。

3. 初始化流程

a) bimc-bwmon驱动通过设备名”qcom,bimc-bwmon[0-4]”匹配到对应的devicetree中的硬件信息,获取中断号,获取控制器的版本,针对不同功能的控制器进行初始化。然后调用register_bw_hwmon初始化devfreq_governor类,并赋值其函数指针get_target_freq和event_handler,最终通过devfreq_add_governor注册到devfreq framework。

b) devbw驱动通过如下设备名”qcom,devbw*”匹配到对应的devicetree中的硬件信息,初始化devbw 设备的信息dev_data类,并将其设置为driver的私有数据。设置devfreq framework结构的devfreq_dev_profile中的target 和 get_dev_status函数及polling_ms的初始值。

同时设置设备的OPP表(OPP表的代码以DTS的形式表现)。

最终通过devfreq_add_device将devbw 设备添加到devfreq framework的devfreq list链表中。此时会与devfreq governor建立两者的联系。

c) 当event_handler收到GOV_START信号以后,start_monitor 会注册中断函数,此中断就对应上升下降阈值的触发时机。如果有设置polling_ms则会queue_delayed_work 更新频率。

4. 频率调整流程

如上图所示为devfreq framework的通用的更新外设频率的流程

updatedevfreq 为核心函数,其流程如下

1.通过get_target_freq重新评估需要的频率

2.通过get_cur_freq获取当前的频率,如果实现此接口,则使用上次的频率作为当前频率

3.最后通过target 函数指针调用设置硬件的clock

其中get_target_freq 函数指针对应的函数就是bus dcvs的策略算法实现,此处为devfreq_bw_hwmon_get_freq,其本质就是get_bw_and_set_irq函数。

5. get_bw_and_set_irq

此策略中的变量参数比较多,但是本质上最基本的计算方式如下图所示

AB:平均需求的带宽

IB:瞬时需求的带宽

a) guard_band_mbps:基于性能的目的引入guard_band,在投票之前为measured_mbps += guard_band_mbps,为了解决带宽更新不及时导致的问题

b) decay_rate:此参数的范围为0-100,如果设置为100则不考虑历史的影响。且只有在当前测量值比上一次需求带宽小的情况才生效,用于避免频率更新后的乒乓性。

c) bw_step:类似取整的参数,用于降低更新频率的频繁性。

d) io_percent:用于计算IB,CPU的执行过程是一部分时间在访存,一部分时间在执行。相当于设定访存所占时间的百分比。

五、memlat策略

1. 源码路径

a) drivers/devfreq/devfreq_devbw.c

b) drivers/devfreq/arm-memlat-mon.c

c) driver/devfreq/governor_memlat.c

d) arch/arm64/boot/dts/vendor/qcom/

2. memlat软件架构

Gover normemlat 是对 bw_hwmon机制的补充,主要对应memory latency sensitivity的任务

memlat策略涉及到的模块大致分为 devbw,memlat-mon,和devfreq framework。

  1. memlat-mon:其代表的是使用PMU来度量访存延时的设备。

  2. devbw:master对ddr slave的带宽需求。

  3. devfreqframework:非 CPU 设备的通用动态电压和频率缩放 (DVFS) 框架。

3. 初始化流程

a)   设备dts信息

qcom,target-dev:此设备对应的master。

qcom,cachemiss-ev:测量的缓存未命中事件。

qcom,core-dev-table:CPU核心频率到所需带宽投票的映射表。

operating-points-v2:从master到slave的带宽OPP表。

b) arm-memlat-mon驱动通过设备名”qcom,arm-memlat*”匹配到对应的devicetree中的硬件信息,获取miss_ev_id,并对相关结构体进行初始化。然后调用register_memlat初始化devfreq_governor类,并赋值其函数指针get_target_freq和event_handler,最终通过devfreq_add_governor注册到devfreq framework。

c) 同bw_hwmon策略一样,event_handle 收到GOV_START信号以后,调用start_hwmon对相关的events进行初始化,同时启动delayed work更新频率。

4. 频率调整流程

此策略的因子比较简单。在每次的时间周期内,统计PM Uevent获取的instructions count 和 L2miss rate,只有当inst / miss 小于ratioceil的时候才会触发更新频率。最终将需求的带宽频率调用devfreq_bw的set_bw函数设置到硬件。

六、总结

随着各大厂商对芯片性能功耗的极致优化,对于一些cpu stall的场景可以通过BUS DCVS更精细化的优化进行改善。最后祝愿各位在技术的道路上越走越远。

Devfreq Bus Dcvs的更多相关文章

  1. 设备模型(device-model)之平台总线(bus),驱动(driver),设备(device)

    关于关于驱动设备模型相关概念请参考<Linux Device Drivers>等相关书籍,和内核源码目录...\Documentation\driver-model 简单来说总线(bus) ...

  2. Matlab中使用脚本和xml文件自动生成bus模块

    帮一个老师写的小工具 在一个大工程中需要很多bus来组织信号,而为了规范接口,需要定义很多BusObject,用Matlab语言手写这些BusObject比较费工夫 所以用xml配置文件来写,也便于更 ...

  3. bzoj 1537: [POI2005]Aut- The Bus 线段树

    bzoj 1537: [POI2005]Aut- The Bus 先把坐标离散化 设f[i][j]表示从(1,1)走到(i,j)的最优解 这样直接dp::: f[i][j] = max{f[i-1][ ...

  4. linux下bus、devices和platform的基础模型

    转自:http://blog.chinaunix.net/uid-20672257-id-3147337.html 一.kobject的定义:kobject是Linux2.6引入的设备管理机制,在内核 ...

  5. ACE bus

    ACE bus增加的内容: 1):5状态的cache model 2):关于coherency的additional signal 3):两个cache master访问shared cache的ad ...

  6. 利用Service bus中的queue中转消息

    有需求就有对策就有市场. 由于公司global的policy,导致对公司外发邮件的service必须要绑定到固定的ip地址,所以别的程序需要调用发邮件程序时,问题就来了,如何在azure上跨servi ...

  7. c程序中出现segment error 和 bus error 的原因

    在c程序中,经常会遇到段错误(segment error)和总线错误(bus error),这两种问题出现的原因可能如下 段错误: 对一个NULL指针解引用. 访问程序进程以外的内存空间. 实际上,第 ...

  8. Azure Service Bus 中的身份验证方式 Shared Access Signature

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  9. Windows Azure Service Bus Topics实现系统松散耦合

    前言 Windows Azure中的服务总线(Service Bus)提供了多种功能, 包括队列(Queue), 主题(Topic),中继(Relay),和通知中心(Notification Hub) ...

  10. Windows Azure Service Bus Notification Hub推送通知

    前言 随着Windows Azure 在中国的正式落地,相信越来越多的人会体验到Windows Azure带来的强大和便利.在上一篇文章中, 我们介绍了如何利用Windows Azure中的Servi ...

随机推荐

  1. Microsoft Dynamics CRM 365/2016 配置POP3/STMP邮箱(附例)

    前期准备: 必须支持pop3/stmp的邮箱 以下用网易163邮箱做的测试,注意开通了独立安全码,非邮箱登录密码 1.打开设置>>电子邮件配置 2.新建电子邮件配置 pop3/smtp 3 ...

  2. Java8 Stream流使用

    Java8 Stream 流式编程 一.Lambda表达式 Lambda表达式也可以称为闭包,它是推动Java8发布的最重要新特性,lambda允许把函数作为一个方法参数传递给方法. 在Java8之前 ...

  3. 【vue3】详解单向数据流,大家千万不用为了某某而某某了。

    总览 Vue3 的单向数据流 尽信官网,不如那啥. vue的版本一直在不断更新,内部实现方式也是不断的优化,官网也在不断更新. 既然一切皆在不停地发展,那么我们呢?等着官网更新还是有自己的思考? 我觉 ...

  4. 实现一个终端文本编辑器来学习golang语言:第二章Raw模式下的输入输出

    从第二章开始,在每个小节的最后都会有一些代码实操作业,你可以选择自己完成(比较推荐),再对照我的实现方式,当然也可以直接看我的代码实现.不过,之后的各个功能实现,我都会基于我先前的代码实现版本,在它的 ...

  5. NVIDIA的OpenUSD是什么? —— Universal Scene Description (USD)

    正如NVIDIA的老黄在2024年的技术大会上的展示一样,NVIDIA公司或许最准确的定义应该是计算机图形学公司,因为不论是NVIDIA搞GPU还是搞通用计算还是搞软件生态以至于现在搞AI搞机器人搞自 ...

  6. 【转载】 使用Python的ctypes查看内存

    =================================================================== 原文地址: https://zhuanlan.zhihu.com ...

  7. Git报错解决:OpenSSL SSL_read: Connection was reset, errno 10054 错误解决

    1.背景 最近因项目上需要,想借鉴一下spring里面的一下架构设计,在拉取spring源码是报错如下: 初步判定,估计是访问国外的网站,网速受限的原因..... 2.解决方案 打开Git命令页面,执 ...

  8. vue之循环遍历v-for

    1.背景 2.遍历数组 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  9. js 实现俄罗斯方块(三)

    我又来啦!上一篇有点水,本篇我们来干货! 嘿嘿,首先我们先搭建游戏世界------网格 所有的操作包括左移右移下移旋转都是在这个网格中 既然是使用js来写当然跑不了html啦,实现网格最简单的 方法就 ...

  10. 海豚²来了丨DolphinDB 集成 DolphinScheduler,任务调度更轻松

    DolphinDB 是一款高性能时序数据库.DolphinDB 集成了功能强大的编程语言和高容量高速度的批流一体数据分析系统,为海量数据(特别是时间序列数据)的快速存储.检索.计算及分析提供一站式解决 ...