Android 性能優化系列 - 02 理解 systrace

上篇文章中簡單介紹了 systrace 的使用,以及如何簡單地分析 systrace 生成的 trace.html 文件了,但是如何更深刻地理解 trace.html 文件呢?

catalog.png

一. 概述

在上篇文章中已經介紹過了,systrace 本質上是對其他工具的封裝,包括 PC 端的 atrace 和設備端的 ftrace,ftrace 是 Linux 內核中的主要跟蹤機制。systrace 使用 atrace 開啟追蹤,然后讀取 ftrace 的緩存,并且把它重新轉換成HTML格式。

有一個概念是使用 systrace 分析性能的基礎概念,十分重要,需要大家理解:因為 systrace 是基于 ftrace 的,ftrace 是運行在 CPU 之上的,ftrace 緩沖區是用于記錄硬件變化情況的,所以 CPU 上的變化情況也會寫入 ftrace 緩沖區中。這也就意味著,如果你想知道顯示柵欄發生變化的原因,則可以查看對應時間點上 CPU 上運行了哪些線程,發生了哪些活動,這些線程的活動就是顯示柵欄發生變化的原因。

二. 示例:工作幀

這個示例介紹了一個正常 UI 管道(UI pipeline)的 systrace 工作流程,請先下載好 trace 文件,點這里下載

對于一個持續的、周期性的工作負載 workload(比如:TouchLatency app),它的 UI 管道包括以下幾步

  1. SurfaceFlinger 中的 EventThread 喚醒 app 的 UI Thread,表明是時候渲染新幀了

  2. App 進程通過使用 CPU、GPU 資源,在 UI Thread、RenderThread 和 hwuiTask 中完成了一幀的渲染,然后通過 binder 將渲染好的幀發送到 SurfaceFlinger 中,將該幀壓入到幀緩沖隊列 queueBuffer 中。App 中的線程在執行完自己的工作以后便返回到休眠狀態。UI 渲染的大部分工作都在這一步中

  3. SurfaceFlinger 中的第二個 EventThread 將喚醒 SurfaceFlinger 觸發構圖,并將最終幀提交到顯示輸出部分

    • SurfaceFlinger 通過 HWC/HWC2 或 GL 處理構圖,HW/HW2 處理構圖的速度更快且功率更低,但是存在一些取決于 SOC 的限制

    • 這一步通常需要約 4~6ms 的時間,但是這一步可以和第二步同時進行,因為在 Android 應用始終會進行三重緩沖(雖然 Android 應用中始終是三重緩沖的,但是在 SurfaceFlinger 中可能只存在一個待處理幀,所以看起來和雙重緩沖很像)

    • 如果 SurfaceFlinger 確定沒有任何任務需要執行,則會返回休眠狀態

  4. SurfaceFlinger 通過供應商驅動程序將最終輸出部分調度到顯示部分,然后返回休眠狀態,等待下一次 EventThread 的喚醒

下面將結合 systrace_tutorial.html 文件具體分析一下上面幾個步驟

2.1 EventThread 喚醒 App 的 UI Thread

如下圖所示,在 15409.744 ms 處,可以看到在 Kernel CPU0 上運行了一個 EventThread 線程,從底部的描述信息可知 tid:6843,與此同時,在 com.prefabulated.touchlatency 應用中的 UI Thread 有一小段藍色部分。

在 systrace 中線程是具有顏色的,不同的顏色代表此時線程處于不同的狀態,各個顏色及狀態說明如下:

  • 灰色:Sleeping,處于休眠狀態
  • 藍色:Runnable,線程可以運行,但是調度器 scheduler 尚未調度讓它運行
  • 綠色:Actively running,調度器 scheduler 認為它目前正處于運行狀態
  • 紅色:Uninterruptible sleep,不可中斷的休眠狀態,通常處于內核中休眠鎖定狀態(generally sleeping on a lock in the kernel),一般是正在進行 I/O 操作,紅色狀態時通常對于性能調試非常有用
  • 橙色:Uninterruptible sleep due to I/O load,由于 I/O load 而不可中斷的休眠狀態
systrace1.png

如下圖所示,如果選中 com.prefabulated.touchlatency 應用中 UI Thread 最開始的一小段藍色狀態,可以看到此時 UI Thread State 是 Runnable 的(可運行狀態,但是未被 調度器 scheduler 調度到 CPU 上執行),在下面的描述信息中可以看到 "wakeup from tid:6843",正是由上圖中所示的 EventThread 喚醒的

systrace2.png

從上面兩幅圖可以看出,在 EventThread 執行時 com.prefabulated.touchlatency 應用中的 UI Thread 變成了 Runnable 的狀態了,正是第一步 SurfaceFlinger 中的 EventThread 喚醒 app 應用中的 UI Thread,使其處于 Runnable 的狀態,表明是時候開始渲染新幀了。

2.2 App 進程開始渲染新的一幀并通過 Binder 發送數據到 SurfaceFlinger 中

第二步主要是在應用進程中,通過 CPU 和 GPU 資源,在 UI Thread、RenderThread 和 hwuiTask1 中渲染幀,最后通過 binder 將渲染幀數據發送到 SurfaceFlinger 中。

如下圖所示,com.prefabulated.touchlatency 進程中 UI Thread、RenderThread 和 hwuiTask1 中渲染幀,最后調用了 binder,這一步是幀渲染中執行時間很長的一步


systrace3.png

我們選中上圖小紅框中的 binder_transaction,可以在下面的描述信息中看到如下所示的信息,Destination Process 6832 Calling PID 9579Calling tgid 9564,表明此時 RenderThread 正在和 ProcessId 是 6832 進程進行 binder 通信,如下圖所示

systrace4.png

我們看一下 SurfaceFlinger 進程中,此時正在運行的 Binder:6832_1,如下圖所示


systrace5.png

我們選中 Binder:6832_1 中的 binder replay,可以在底部看到 Destination Process: 9564,Destination Thread:9579,Calling PID:6836,Calling tgid:6832,顧名思義,binder replay 正在響應剛才 RenderThread 的發出的 binder_transaction,Destination Process 是 9564,也正是 com.prefabulated.touchlatency 的 processId


systrace6.png

在 SurfaceFlinger 進程中,通過 binder 接收到的 frame 幀數據被壓入到 queueBuffer 中,從下圖中可以看到,在 binder_reply 執行前后 com.prefabulated.touchlatency 中緩沖的幀由 1 個變成了 2 個。

下圖表示了三重緩沖,在緩沖隊列中存在兩個已緩沖的幀,應用程序將很快開始渲染第三幀


systrace6.png

在 com.prefabulated.touchlatency 進程通過 CPU 和 GPU 資源在 UI Thread、RenderThread 和 hwuiTask1 中計算好渲染幀以后,通過 binder 將渲染幀發送到 SurfaceFlinger 進程中,然后就返回了休眠狀態,如下圖所示的三個紅色的框,表示的是灰色的,就是指此時線程正在休眠狀態,直到下一時刻被喚醒,重新渲染下一幀


systrace7.png

2.3 SurfaceFlinger 鎖定緩沖區中的幀觸發構圖并提交最終幀到顯示輸出

接下來將開始第三步的工作,SurfaceFlinger 被第二個 EventThread 喚醒,并從緩沖區中鎖定較早的一幀,觸發構圖,并將最終幀提交到顯示輸出部分。

如下圖所示,在 15430.345 ms 處執行第二個 EventThread,喚醒 SurfaceFlinger,使其處于可運行的狀態(Runnable,藍色的),從底部的描述信息中可以看到其 tid:6845


systrace8.png

我們再選中 SurfaceFlinger 中可運行的部分(Runnable,藍色的),如下圖所示,可以看到描述信息 "wakeup from tid: 6845",說明 SurfaceFlinger 此時確實是被上圖中所示的 EventThread 喚醒的

systrace9.png

之后 SurfaceFlinger 便鎖定緩沖區中較早的一幀并觸發構圖,然后將最終幀提交給顯示輸出部分。

如下圖所示,在 15413.169 ms 處,通過 acquireBuffer 方法鎖定緩沖區中較早的一幀,queueBuffer 中緩沖幀的數量也由兩個,變成了一個

systrace10.png

如下圖所示,在鎖定緩沖區中較早的一幀以后,便通過 doComposition 方法觸發了構圖,并且在 15433.787 ms 處通過 ATOMIC_COMMIT 操作將最終幀提交到顯示輸出

systrace11.png

2.4 驅動程序將最終輸出部分調度到顯示部分

緊接著 mdss_fb0 線程被喚醒,如下圖所示,mdss_fb0 線程是顯示管道的內核線程,用于將渲染過的幀輸出到顯示部分

systrace12.png

如下圖所示,可以看到 mdss_fb0 的執行情況,mdss_fb0 的具體執行信息需要查看相關的驅動程序文檔了。

systrace13.png

三. 總結

上述內容是自己對 Understanding Systrace 部分內容的翻譯(其實已經有官方的翻譯 了解 Systrace,但是我覺得翻譯的并不好,層次感也不夠強 ),經過自己消化理解輸出的,也算是自己的學習。

通過本文有兩點收獲

  • 分析 systrace 生成的 trace.html 更加得心應手,比如對一些快捷鍵的使用更熟練、更深刻的理解了底部的文字描述信息
  • 對 Android 中每一幀 Frame 的渲染流程更加熟悉,對幀 Frame 的渲染流程有了直觀 & 完整的理解

希望本文也可以幫助到更多的朋友。

四. 參考

了解 systrace
Understanding Systrace
Systrace 的工作原理以及如何分析

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,716評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,746評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,706評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,036評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,203評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,725評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,451評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,677評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,857評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,407評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,643評論 2 380

推薦閱讀更多精彩內容