最近往一个armv7板子的bootloader中移植了解压算法,移植自己还比较顺利,但移植完了发现,功能是正常的,但效率大打折扣。解压一样的数据,耗时大约是uboot的10倍。算法
从这个10倍的量级上,比较怀疑是Cache相关,但其余怀疑的因素也要先确认了下。先确认下直接相关的DDR和CPU。性能
DDR的驱动是彻底同样的,因此DDR先排除。测试
CPU的话,芯片上电后时钟是固化在芯片中的BootROM设定的,默认比较低,但看代码CPU时钟是调整过了,已经提升到1G了。为了确认改动是生效的,尝试将CPU频率设定下降了些,发现速度确实随之变慢了,那就说明CPU时钟配置确实生效了。退一步讲,CPU的设置即便没成功,也不该该形成十倍的性能差距。google
那么目光就落在了Cache身上。从代码上看,MMU,DCache和ICache是都打开了的。那么既然使能了,得想个办法确认是否确实起做用了,一个简单的办法就是,故意不使能它,看性能是否有变化。it
修改代码,分别测试了不使能DCacne和不使能ICache的解压时间,从结果看出ICache起做用了,而DCache没起做用,开关DCache对解压时间没什么影响。那问题确定就在DCache上。table
到了这一步,我想到以前解决的另外一个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中揪出这个配置。
改完以后,解压速度杠杠的,但也带来了一些其余的问题,例如个人系统启动不了了,bootloader跳转过去就直接挂了。想了下,应该是改成write-back后Cache和主存的数据存在不一致致使的。 若是是在主系统中,那对Cache就得精细化控制,该回刷就回刷该无效就无效,但在这个问题中个人场景比较简单,bootloader一贫如洗,就简单些吧,再移植一段刷Cache的代码,直接刷所有DCache。而后在几个关键的地方调用了下,果真,启动流程恢复正常了。