一般來說,我們發(fā)現(xiàn)程序卡頓,排除其他程序問題和硬件問題,那一定是自身程序中某個(gè)位置運(yùn)行時(shí),消耗的時(shí)間過長導(dǎo)致。
性能問題分析方式
要找到耗時(shí)的代碼段,才能有針對性的進(jìn)行優(yōu)化,那第一個(gè)問題就是如何找到耗時(shí)的代碼段。
首先我們能想到,在程序中可能存在問題的地方,加入計(jì)算時(shí)間差的代碼,然后不斷縮小范圍,找到最終耗時(shí)的點(diǎn)。
#includeuint64_tGetTimeStampUS() { structtimevaltv; gettimeofday(&tv,NULL); returntv.tv_sec*1000000+tv.tv_usec; } ..... voidFuncA() { uint64_tt1=GetTimeStampUS(); FuncB(); uint64_tt2=GetTimeStampUS(); FuncC(); uint64_tt3=GetTimeStampUS(); printf("FuncBcost:%llu,FuncCcost:%llu ",t2-t1,t3-t2); }
這種方式最終也能解決問題,但是會(huì)有一些缺點(diǎn):
①對于大型項(xiàng)目來說,要經(jīng)過大量的【編譯,執(zhí)行驗(yàn)證,添加代碼】迭代,消耗大量時(shí)間。
②排查到問題后,需要把測試代碼刪除,下次排查時(shí)又要重新添加代碼。
③通過查看文本 log 方式分析,不直觀。 下面我們看看如何使用 bytrace 來分析問題。
在OpenHarmony中使用 Bytrace
①在 BUILD.gn 中添加對 bytrace 的依賴:
external_deps=[ "bytrace_standard:bytrace_core", ]
②添加頭文件:
#include
③添加打點(diǎn)代碼:
voidFuncA(){ StartTrace(BYTRACE_TAG_GRAPHIC_AGP,"funcB"); funcB(); FinishTrace(BYTRACE_TAG_GRAPHIC_AGP); }
代碼部分完成了,編譯更新到開發(fā)板,然后使用下面命令來抓取 log:
hdcshellbytrace-t10-b8192graphic>~/logs/log.ftrace參數(shù)說明: -t 10:從運(yùn)行命令行開始,抓取 10 秒時(shí)間(非必要參數(shù),默認(rèn) 5 秒) -b 8192:使用 8192kb(8M) 內(nèi)存來緩存數(shù)據(jù)(非必要參數(shù),默認(rèn) 2048kb) graphic:抓取 graphic 類型的 trace,對應(yīng)上面代碼中的 BYTRACE_TAG_GRAPHIC_AGP 最后把抓取的結(jié)果保存到 log.ftrace 這個(gè)文件中(文件后綴名非限定,txt 也行),通過文本編輯器打開查看。 到目前為止,看起來跟加入時(shí)間差代碼的方式差不多,還是打點(diǎn)看 log,接著往下看。
優(yōu)化打點(diǎn)
把 bytrace 的打點(diǎn)代碼封裝起來,xtrace.h:
#include#include"bytrace.h" classXTrace { public: XTrace(std::stringfname); ~XTrace(); };
xtrace.cpp:
XTrace::XTrace(std::stringfname) { StartTrace(BYTRACE_TAG_ZCAMERA,fname); } XTrace::~XTrace() { FinishTrace(BYTRACE_TAG_ZCAMERA); }
這樣我們用起來就更方便了:
voidFuncB(){ XTracetrace1(__func__); } voidFuncA(){ { XTracetrace1(__func__); FuncB(); { XTracetrace2(__func__); FuncC(); } }函數(shù)開始,創(chuàng)建 XTrace 對象時(shí),構(gòu)造函數(shù)調(diào)用 StartTrace。函數(shù)結(jié)束或離開作用域,棧中的對象會(huì)自動(dòng)釋放,析構(gòu)函數(shù)調(diào)用 FinishTrace。 當(dāng)然這種方式也可以用于時(shí)間差打點(diǎn)。
可視化看 log
鏈接如下:
https://ui.perfetto.dev
這個(gè)網(wǎng)站需要科學(xué)方法訪問,首次訪問后有了緩存,后續(xù)就可以離線訪問了。
我這邊把網(wǎng)頁保存下來了,在本地開 web 服務(wù),通過 127.0.0.1 也可以使用。 首先點(diǎn)擊左上角 Open trace file 打開 log.ftrace,右邊會(huì)顯示出函數(shù)調(diào)用的火焰圖,點(diǎn)擊其中一個(gè)函數(shù),在下方可以看到準(zhǔn)確的執(zhí)行時(shí)間。
基本操作:
鍵盤 w,s:時(shí)間軸縮放
鍵盤 a,d:左右移動(dòng)
可視化看時(shí)間軸就非常直觀了,橫條越長,消耗時(shí)間越多。
OpenHarmony 對bytrace 的集成
我們在 OpenHarmony 使用 bytrace,除了以上的便利以外,最重要的是 OpenHarmony 的代碼中已經(jīng)大量使用了 bytrace。
下面是我整理的已經(jīng)集成 bytrace 的模塊:
對于以上模塊的性能問題,我們就能直接使用對應(yīng) tag 來抓取。
其他
對于一個(gè)較大的模塊代碼,我們需要理解他的執(zhí)行流程,函數(shù)調(diào)用關(guān)系,會(huì)比較頭疼。
所以我編寫了一個(gè)腳本,掃描所有的 .cpp 文件,在所有函數(shù)開頭自動(dòng)添加:
XTracexxx(__func__);在可視化界面分析 log,可以清晰的看到函數(shù)執(zhí)行的,不同的線程,函數(shù)的調(diào)用棧,能快速的梳理代碼的執(zhí)行流程。 第四點(diǎn)中的圖,是我對 foundation/ace/ace_engine/frameworks 這個(gè)目錄下 2000 個(gè)左右 cpp 文件中的函數(shù)全部添加 XTrace 后,得到的應(yīng)用啟動(dòng)流程火焰圖。
審核編輯:湯梓紅
-
程序
+關(guān)注
關(guān)注
117文章
3792瀏覽量
81162 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5081瀏覽量
97699 -
代碼
+關(guān)注
關(guān)注
30文章
4802瀏覽量
68743 -
編輯器
+關(guān)注
關(guān)注
1文章
806瀏覽量
31209 -
OpenHarmony
+關(guān)注
關(guān)注
25文章
3728瀏覽量
16400
原文標(biāo)題:OpenHarmony上使用火焰圖
文章出處:【微信號(hào):gh_834c4b3d87fe,微信公眾號(hào):OpenHarmony技術(shù)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論