記一次uboot中gunzip解壓速度慢的問題排查

背景

在項目中須要用到解壓功能,以前還記錄了下,將uboot解壓代碼移植到另外的bootloader中時,碰到的效率問題。最終查明是cache的配置致使的。html

http://www.javashuo.com/article/p-hbbebjxu-gv.htmllinux

優化前速度是uboot的十分之一,優化後速度達到uboot的兩倍多。函數

沒想到風水輪流轉,最近在uboot中用瞭解壓功能,結果最終在進行啓動速度優化時,發現解壓速度很慢,性能

不只比不上移植到另外一個bootloader中的解壓速度,並且比以前測到過的uboot解壓速度要慢得多。優化

一樣的數據量,在另外一個bootloader中解壓耗時低於200毫秒,而記憶中的以前測到的uboot中耗時爲數百毫秒,最新數據測得是接近2秒。code

cache

最開始仍是懷疑cache,一頓操做一無所得,通過確認cache是確實使能了的,類型也是write-back,沒有問題。爲了確認還故意將其配置爲write-through,測得性能進一步下降了,這才確認此路不通。htm

watchdog

繼續排查,最終才性能問題是一個watchdog配置項引入的,打開了watchdog以後解壓耗時就從數百毫秒增長到了接近2秒,足足三倍。blog

watchdog怎麼就影響到了解壓速度呢?原來uboot在不少地方預置了watchdog的喂狗的鉤子,當適配了watchdog驅動並使能以後,這些鉤子就會生效,自動喂狗。ip

如今的問題就出在,zlib庫中也被預置了喂狗的鉤子,這就致使watchdog使能以後,解壓的循環中會不停喂狗,多出了很多開銷。get

考慮到咱們實際這塊板子的watchdog超時時間長達16s,而解壓的耗時在百毫秒級別,根本不須要考慮在解壓過程喂狗,所以解決方式簡單粗暴,將zlib中的喂狗操做所有去除便可。

指定解壓後長度

搞定了watchdog以後速度提高很多,但仍是比以前移植到另外一個bootloader的解壓慢,這個也不正常,因而進一步排查。

最終發現,問題出在咱們本次在uboot中調用gunzip時偷懶了,沒有去解析解壓先後文件的大小,直接將src_len和dst_len指定爲~0UL。

這是從unzip命令的實現中學的,默認 src_len = ~0UL, dst_len = ~0UL; 是否指定解壓後文件大小是可選的

本想簡單些,讓解壓庫自行處理,反正咱們已經分配了足夠的大小,確定不會越界,沒想到不指定還會帶來效率問題。

解決方法,從壓縮包的尾部讀出壓縮前的原始文件大小,解壓時做爲參數傳給gunzip函數。

下面是直接在控制檯調用unzip命令,使用minicom的時間戳,來演示帶長度和不帶長度的區別

只指定源地址和目的地址,則耗時約430ms

[2019-11-25 09:59:43.014] => version;unzip 40901000 40000000
[2019-11-25 10:00:10.359] U-Boot 2018.05 (Nov 25 2019 - 09:20:58 +0800) Allwinner Technology
[2019-11-25 10:00:10.385] 
[2019-11-25 10:00:10.385] arm-linux-gnueabi-gcc (Linaro GCC 7.2-2017.11) 7.2.1 20171011
[2019-11-25 10:00:10.385] GNU ld (Linaro_Binutils-2017.11) 2.28.2.20170706
[2019-11-25 10:00:10.815] Uncompressed size: 6553388 = 0x63FF2C

指定源地址和目的地址,同時指定長度,則耗時約170ms

[2019-11-25 10:00:10.831] => version;unzip 40901000 40000000 0x63FF2C
[2019-11-25 10:00:30.486] U-Boot 2018.05 (Nov 25 2019 - 09:20:58 +0800) Allwinner Technology
[2019-11-25 10:00:30.486] 
[2019-11-25 10:00:30.486] arm-linux-gnueabi-gcc (Linaro GCC 7.2-2017.11) 7.2.1 20171011
[2019-11-25 10:00:30.487] GNU ld (Linaro_Binutils-2017.11) 2.28.2.20170706
[2019-11-25 10:00:30.646] Uncompressed size: 6553388 = 0x63FF2C

本文連接 http://www.javashuo.com/article/p-gzppcclh-ez.html

相關文章
相關標籤/搜索