问题背景

最近往一个armv7板子的bootloader中移植了解压算法,移植本身还比较顺利,但移植完了发现,功能是正常的,但效率大打折扣。解压同样的数据,耗时大约是uboot的10倍。

初步定位

从这个10倍的量级上,比较怀疑是Cache相关,但其他怀疑的因素也要先确认了下。先确认下直接相关的DDR和CPU。

DDR的驱动是完全一样的,所以DDR先排除。

CPU的话,芯片上电后时钟是固化在芯片中的BootROM设定的,默认比较低,但看代码CPU时钟是调整过了,已经提高到1G了。为了确认改动是生效的,尝试将CPU频率设定降低了些,发现速度确实随之变慢了,那就说明CPU时钟配置确实生效了。退一步讲,CPU的设置即使没成功,也不应该造成十倍的性能差距。

那么目光就落在了Cache身上。从代码上看,MMU,DCache和ICache是都打开了的。那么既然使能了,得想个办法确认是否确实起作用了,一个简单的办法就是,故意不使能它,看性能是否有变化。

修改代码,分别测试了不使能DCacne和不使能ICache的解压时间,从结果看出ICache起作用了,而DCache没起作用,开关DCache对解压时间没什么影响。那问题肯定就在DCache上。

Cache设定

到了这一步,我想到之前解决的另一个Cache不起作用的问题,最终是查到必须设置smp bit,于是加上对应的设置代码,但加上后问题并没解决。

继续google,查阅了一些Cache的资料后,目光转向了mmu的page table设置。

简单来说,在启用mmu时,需要给出一个page table告知mmu,虚拟地址和物理地址如何映射,在这个page table中,每一项还有若干功能位,包括了权限,Cache等设置。
对于一些寄存器相关的地址,一般就不使能Cache,这样读写寄存器不会受Cache影响。而对于其他正常的地址,一般会启用Cache以提高效率。而启用Cache还需要具体配置Cache的模式,可以配置为write-through(写通/写穿) 或 wrike-back(写回)。对于write-through,数据会既写到Cache又写到主存,Cache和主存的数据总是一致的。对于write-back,数据只写到Cache,并标记为dirty,当Cache被换出时才写到主存。

对照实际的page table,发现设置的是write-through。write-through每次都需要实际写到主存,速度自然是慢的,赶紧修改为write-back测试下。果然解压速度获得了质的飞跃。

本次问题中,我的代码本身是运行在Sram上,而需要解压的源数据,以及解压后的数据则是在Dram上。在将Dram对应地址的设置改为write-back之后,速度获得了大约3倍的提升。进一步将Sram对应的地址也设置为write-back之后,速度再次获得约10倍的提升。累计提升约28倍,令人不仅赞叹Cache果然是个好东西。

顺便提一句,最开始加的smp bit确实是需要的,各位如果发现DCache没起作用,可以检查下这个设置,之前在另一个问题上也是坑了我好几天才从uboot中揪出这个配置。

Cache回刷

改完之后,解压速度杠杠的,但也带来了一些其他的问题,例如我的系统启动不了了,bootloader跳转过去就直接挂了。想了下,应该是改为write-back后Cache和主存的数据存在不一致导致的。
如果是在主系统中,那对Cache就得精细化控制,该回刷就回刷该无效就无效,但在这个问题中我的场景比较简单,bootloader一穷二白,就简单些吧,再移植一段刷Cache的代码,直接刷全部DCache。然后在几个关键的地方调用了下,果然,启动流程恢复正常了。

记一个bootloader的cache问题的更多相关文章

  1. 记一个社交APP的开发过程——基础架构选型(转自一位大哥)

    记一个社交APP的开发过程——基础架构选型 目录[-] 基本产品形态 技术选型 最近两周在忙于开发一个社交App,因为之前做过一点儿社交方面的东西,就被拉去做API后端了,一个人头一次完整的去搭这么一 ...

  2. 一个Netfilter nf_conntrack流表查找的优化-为conntrack添加一个per cpu cache

    独悲须要忍受.快乐须要分享对Linux协议栈多次perf的结果,我无法忍受conntrack的性能,然而它的功能是如此强大,以至于我无法对其割舍,我想自己实现一个高速流表.可是我不得不抛弃依赖于con ...

  3. 记一个http-proxy-middleware 代理访问nginx映射的接口不通过的问题(connection close)

    工作过程中遇见一个问题,使用Vue-cli 搭建了一个工程,由于跨域的问题 使用了自带的dev-server Express Server(A后台) http-proxy-middleware 去访问 ...

  4. 记一个常见的ms sql server中取第N条记录的方法

    前言 好好学习,天天向上. 正文 好像也是一个不难的问题,刚视频里看到的,就记一下吧. 下面是表中原始的数据结构,做了一个倒叙排序: select * from Employee order by S ...

  5. Python实现的一个简单LRU cache

    起因:我的同事需要一个固定大小的cache,如果记录在cache中,直接从cache中读取,否则从数据库中读取.python的dict 是一个非常简单的cache,但是由于数据量很大,内存很可能增长的 ...

  6. salesforce零基础学习(一百一十五)记一个有趣的bug

    本篇参考:https://help.salesforce.com/s/articleView?language=en_US&type=1&id=000319486 page layou ...

  7. 记一个mvn奇怪错误: Archive for required library: 'D:/mvn/repos/junit/junit/3.8.1/junit-3.8.1.jar' in project 'xxx' cannot be read or is not a valid ZIP file

    我的maven 项目有一个红色感叹号, 而且Problems 存在 errors : Description Resource Path Location Type Archive for requi ...

  8. 记一个简单的sql查询

    在我们做各类统计和各类报表的时候,会有各种各样的查询要求.条件 这篇主要记录一个常见的统计查询 要求如下: 统计一段时间内,每天注册人数,如果某天没有人注册则显示为0 现在建个简单的表来试试 建表语句 ...

  9. Entity Framework学习笔记——记一个错误解决方式及思路

    继续之前设定的学习目标前,先来一篇小小的外篇.按照第一篇里的配置方式配置好的工程前两天还能正常工作,昨天却突然无法通过Add-Migration命令进行数据库的升级.错误信息如下: System.Da ...

随机推荐

  1. Java基础(二十)集合(2)Collection接口

    1.Collection接口通常不被直接使用.但是Collection接口定义了一些通用的方法,通过这些方法可以实现对集合的基本操作,因为List接口和Set接口都实现了Collection接口,所以 ...

  2. foreach数组并直接改变数组内容

    <?php $arr = array(1, 2, 3, 4); foreach ($arr as &$value) { $value = $value * 2; } // $arr is ...

  3. node-批量上传文件

    很多项目可能都会涉及到的业务是关于多文件上传的,那么需要使用到redis或者第三方库(使用redis)来实现任务队列,甚至需要控制并发量和分包(一次请求传多个文件),这样每次都会以实现功能来完成,但是 ...

  4. Scrapy 实现爬取多页数据 + 多层url数据爬取

    项目需求:爬取https://www.4567tv.tv/frim/index1.html网站前三页的电影名称和电影的导演名称 项目分析:电影名称在初次发的url返回的response中可以获取,可以 ...

  5. Flink中接收端反压以及Credit机制 (源码分析)

    先上一张图整体了解Flink中的反压   可以看到每个task都会有自己对应的IG(inputgate)对接上游发送过来的数据和RS(resultPatation)对接往下游发送数据, 整个反压机制通 ...

  6. Mokia(三维偏序)P4390

    提到cdq,就不得不提这道该死的,挨千刀的题目了. 极简题面: 给定一个二维平面,在ti时刻会在(xi,yi)放一个点,会在tj时刻查询一个方框里面的点的数量 看道题就是二维线段树乱搞啊,这么水??? ...

  7. day 2 上午 消失之物 背包

    #include<iostream> using namespace std; long long n,m; ]; ]; ]; int main() { cin>>n>& ...

  8. 奇怪的道路——状压DP

    题目描述 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外. 考古学家已经知道,这个文明在全盛时期有n座城市,编号为1..n.m条道路连接在这些城市之间,每条道路将两个 ...

  9. vscode react自动补全html标签

    第一步:点击上图左下角设置,找到Settings,搜索includeLanguages 第二步:如上图点击图中红色区域,settings.json 第三部:把代码加入,如上图红色选择区域. " ...

  10. linux shell脚本语法笔记

    1.&,&&,|,|| &:除了最后一个cmd,前面的cmd均已后台方式静默执行,执行结果显示在终端上,个别的cmd错误不影响整个命令的执行,全部的cmd同时执行 &a ...