问题背景

最近往一个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. django-URL匹配(二)

    1.新建django项目 django-admin startproject newwebsite 2.建立app 在newwebsite目录下:python manage.py startapp b ...

  2. Flutter学习笔记--Dart基础

    前言 Flutter使用Dart语言开发, Dart是面向对象编程语言, 由Google2011年推出, 目前最新版本是2.4.0. 工欲善其事,必先利其器. 为了更好的开发Flutter应用, 我们 ...

  3. 数据存储之非关系型数据库存储----MongoDB存储

    MongoDB存储----文档型数据库 利用pymongo连接MongoDB import pymongo client = pymongo.MongoClient(host='localhost', ...

  4. 一个自动管理项目的Makefile(C语言)

    Linux 是所有嵌入式软件工程师绕不过去的坎, makefile 是在Linux系统中绕不过去的坎. 花了几天时间初步学习和了解了makefile 的作用以及功能,并且制作了一个通用型的makefi ...

  5. NOIP模拟 24

    连续爆炸的开端. 从这一场开始我没状态了 T1 star way to heaven 受强降雨boboQQQ影响,我一直认为这是一道和凸包有关的计算几何题 很快就弃了,除了期望没做过带实数的题,所以吓 ...

  6. Laravel用户认证

    前期准备 Laravel的权限配置文件位于 config/auth.php,Laravel的认证组件由"guards"和"providers"组成, Guard ...

  7. 使用Typescript重构axios(十四)——实现拦截器

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  8. Java高性能反射工具包ReflectASM

    ReflectASM 使用字节码生成的方式实现了更为高效的反射机制.执行时会生成一个存取类来 set/get 字段,访问方法或创建实例.一看到 ASM 就能领悟到 ReflectASM 会用字节码生成 ...

  9. Abp vNext 自定义 Ef Core 仓储引发异常

    问题 在使用自定义 Ef Core 仓储和 ABP vNext 注入的默认仓储时,通过两个 Repository 进行 Join 操作,提示 Cannot use multiple DbContext ...

  10. 易初大数据 2019年11月13日 Linux 王庆超

    ★安装Red Hat Enterprise Linux7.41 ◆1通过键盘的方向键选择“lnstall Red Hat Enterprise Linux7.4”选项来直接安装Linux 系统. ◆2 ...