1. 程式人生 > >記一次uboot中gunzip解壓速度慢的問題排查

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

背景

在專案中需要用到解壓功能,之前還記錄了下,將uboot解壓程式碼移植到另外的bootloader中時,碰到的效率問題。最終查明是cache的配置導致的。

https://www.cnblogs.com/zqb-all/p/11443127.html

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

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

不僅比不上移植到另一個bootloader中的解壓速度,而且比之前測到過的uboot解壓速度要慢得多。

同樣的資料量,在另一個bootloader中解壓耗時低於200毫秒,而記憶中的之前測到的uboot中耗時為數百毫秒,最新資料測得是接近2秒。

cache

最開始還是懷疑cache,一頓操作一無所獲,經過確認cache是確實使能了的,型別也是write-back,沒有問題。為了確認還故意將其配置為write-through,測得效能進一步降低了,這才確認此路不通。

watchdog

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

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

現在的問題就出在,zlib庫中也被預置了喂狗的鉤子,這就導致watchdog使能之後,解壓的迴圈中會不停喂狗,多出了不少開銷。

考慮到我們實際這塊板子的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

本文連結 https://www.cnblogs.com/zqb-all/p/11966601.h