Google is committed to advancing racial equity for Black communities. See how.
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

性能測試

Android 8.0包括針對吞吐量和延遲的活頁夾和hwbinder性能測試。儘管存在許多用於檢測可感知的性能問題的方案,但是運行此類方案可能會很耗時,並且直到集成系統後才能獲得結果。使用提供的性能測試可以更輕鬆地進行開發過程中的測試,及早發現嚴重問題並改善用戶體驗。

性能測試包括以下四個類別:

  • 活頁夾吞吐量(在system/libhwbinder/vts/performance/Benchmark_binder.cpp可用)
  • 活頁夾延遲(可在frameworks/native/libs/binder/tests/schd-dbg.cpp
  • hwbinder吞吐量(在system/libhwbinder/vts/performance/Benchmark.cpp可用)
  • hwbinder延遲(在system/libhwbinder/vts/performance/Latency.cpp

關於活頁夾和hwbinder

Binder和hwbinder是Android進程間通信(IPC)基礎結構,它們共享相同的Linux驅動程序,但在質量上有以下差異:

方面黏合劑 w
目的為框架提供通用IPC方案與硬件通訊
屬性針對Android框架使用進行了優化最小開銷低延遲
更改前台/後台的調度策略沒有
參數傳遞使用Parcel對象支持的序列化使用分散緩衝區,避免了複製宗地序列化所需數據的開銷
優先繼承沒有

活頁夾和硬拷貝程序

systrace可視化器將事務顯示如下:

圖1.綁定程序流程的Systrace可視化。

在上面的示例中:

  • 四(4)個schd-dbg進程是客戶端進程。
  • 四(4)個綁定程序進程是服務器進程(名稱以Binder開頭,以序列號結尾)。
  • 客戶端進程始終與專用於其客戶端的服務器進程配對。
  • 所有客戶端-服務器進程對均由內核同時獨立調度。

在CPU 1中,OS內核執行客戶端以發出請求。然後,它會盡可能使用相同的CPU來喚醒服務器進程,處理請求,並在請求完成後上下文切換回去。

吞吐量與延遲

在客戶端和服務器進程無縫切換的完美事務中,吞吐量和延遲測試不會產生實質性的差異。但是,當OS內核正在處理來自硬件的中斷請求(IRQ),等待鎖定或只是選擇不立即處理消息時,就會形成等待時間泡。

圖2.由於吞吐量和延遲的差異而導致的延遲泡沫。

吞吐量測試會生成大量具有不同有效負載大小的事務,從而很好地估計了常規事務時間(在最佳情況下)和綁定程序可以實現的最大吞吐量。

相反,延遲測試不對有效負載執行任何操作以最小化常規事務處理時間。我們可以使用事務時間來估計綁定器開銷,進行最壞情況的統計併計算延遲滿足指定期限的事務的比率。

處理優先級倒置

當具有較高優先級的線程在邏輯上等待具有較低優先級的線程時,將發生優先級倒置。實時(RT)應用程序存在優先級反轉問題:

圖3.實時應用程序中的優先級反轉。

使用Linux完全公平調度程序(CFS)調度時,即使其他線程具有更高的優先級,一個線程也總是有機會運行。結果,具有CFS調度的應用程序將優先級反轉作為預期行為而非問題來處理。但是,在Android框架需要RT調度以保證高優先級線程的特權的情況下,必須解決優先級倒置問題。

綁定器事務期間的優先級反轉示例(在等待綁定器線程服務時,RT線程在邏輯上被其他CFS線程阻止):

圖4.優先級反轉,阻塞的實時線程。

為避免阻塞,您可以使用優先級繼承在服務於RT客戶端的請求時將Binder線程臨時升級為RT線程。請記住,RT調度的資源有限,應謹慎使用。在具有n個 CPU的系統中,當前RT線程的最大數量也是n ;如果所有CPU被其他RT線程佔用,則其他RT線程可能需要等待(因此錯過了截止日期)。

要解決所有可能的優先級倒置,可以對活頁夾和hwbinder使用優先級繼承。但是,由於活頁夾已在整個系統中廣泛使用,因此為活頁夾事務啟用優先級繼承可能會使具有過多RT線程的系統向系統發送垃圾郵件。

運行吞吐量測試

吞吐量測試是針對活頁夾/ hbbinder事務吞吐量進行的。在沒有超載的系統中,只要迭代次數足夠高,延遲氣泡就很少見,並且可以消除它們的影響。

  • 活頁夾吞吐量測試位於system/libhwbinder/vts/performance/Benchmark_binder.cpp
  • hwbinder吞吐量測試位於system/libhwbinder/vts/performance/Benchmark.cpp

檢測結果

使用不同有效負載大小的事務的吞吐量測試結果示例:

Benchmark                      Time          CPU           Iterations
---------------------------------------------------------------------
BM_sendVec_binderize/4         70302 ns      32820 ns      21054
BM_sendVec_binderize/8         69974 ns      32700 ns      21296
BM_sendVec_binderize/16        70079 ns      32750 ns      21365
BM_sendVec_binderize/32        69907 ns      32686 ns      21310
BM_sendVec_binderize/64        70338 ns      32810 ns      21398
BM_sendVec_binderize/128       70012 ns      32768 ns      21377
BM_sendVec_binderize/256       69836 ns      32740 ns      21329
BM_sendVec_binderize/512       69986 ns      32830 ns      21296
BM_sendVec_binderize/1024      69714 ns      32757 ns      21319
BM_sendVec_binderize/2k        75002 ns      34520 ns      20305
BM_sendVec_binderize/4k        81955 ns      39116 ns      17895
BM_sendVec_binderize/8k        95316 ns      45710 ns      15350
BM_sendVec_binderize/16k      112751 ns      54417 ns      12679
BM_sendVec_binderize/32k      146642 ns      71339 ns       9901
BM_sendVec_binderize/64k      214796 ns     104665 ns       6495
  • 時間表示實時測量的往返延遲。
  • CPU指示計劃進行測試的CPU的累積時間。
  • 迭代次數表示測試功能的執行次數。

例如,對於8字節有效負載:

BM_sendVec_binderize/8         69974 ns      32700 ns      21296

…活頁夾可以達到的最大吞吐量計算如下:

8字節有效負載時的最大吞吐量=(8 * 21296)/ 69974〜= 2.423 b / ns〜= 2.268 Gb / s

測試選項

要在--benchmark_format=json獲得結果,請使用--benchmark_format=json參數運行測試:

libhwbinder_benchmark --benchmark_format=json
{
  "context": {
    "date": "2017-05-17 08:32:47",
    "num_cpus": 4,
    "mhz_per_cpu": 19,
    "cpu_scaling_enabled": true,
    "library_build_type": "release"
  },
  "benchmarks": [
    {
      "name": "BM_sendVec_binderize/4",
      "iterations": 32342,
      "real_time": 47809,
      "cpu_time": 21906,
      "time_unit": "ns"
    },
   ….
}

運行延遲測試

延遲測試測量客戶端開始初始化事務,切換到服務器進程進行處理以及接收結果所花費的時間。該測試還將查找可能對事務延遲產生負面影響的已知不良調度程序行為,例如不支持優先級繼承或不支持同步標誌的調度程序。

  • 活頁夾等待時間測試位於frameworks/native/libs/binder/tests/schd-dbg.cpp
  • hwbinder延遲測試位於system/libhwbinder/vts/performance/Latency.cpp

檢測結果

結果(在.json中)顯示平均/最佳/最差延遲的統計信息以及錯過的截止日期數。

測試選項

延遲測試採用以下選項:

命令描述
-i value 指定迭代次數。
-pair value 指定進程對的數量。
-deadline_us 2500 指定我們的截止日期。
-v 獲取詳細(調試)輸出。
-trace 在最後期限到來時停止跟踪。

以下各節詳細介紹每個選項,描述用法並提供示例結果。

指定迭代

大量迭代且禁用詳細輸出的示例:

libhwbinder_latency -i 5000 -pair 3
{
"cfg":{"pair":3,"iterations":5000,"deadline_us":2500},
"P0":{"SYNC":"GOOD","S":9352,"I":10000,"R":0.9352,
  "other_ms":{ "avg":0.2 , "wst":2.8 , "bst":0.053, "miss":2, "meetR":0.9996},
  "fifo_ms": { "avg":0.16, "wst":1.5 , "bst":0.067, "miss":0, "meetR":1}
},
"P1":{"SYNC":"GOOD","S":9334,"I":10000,"R":0.9334,
  "other_ms":{ "avg":0.19, "wst":2.9 , "bst":0.055, "miss":2, "meetR":0.9996},
  "fifo_ms": { "avg":0.16, "wst":3.1 , "bst":0.066, "miss":1, "meetR":0.9998}
},
"P2":{"SYNC":"GOOD","S":9369,"I":10000,"R":0.9369,
  "other_ms":{ "avg":0.19, "wst":4.8 , "bst":0.055, "miss":6, "meetR":0.9988},
  "fifo_ms": { "avg":0.15, "wst":1.8 , "bst":0.067, "miss":0, "meetR":1}
},
"inheritance": "PASS"
}

這些測試結果顯示以下內容:

"pair":3
創建一對客戶端和服務器。
"iterations": 5000
包括5000次迭代。
"deadline_us":2500
截止時間為2500us(2.5ms);預計大多數交易將達到此值。
"I": 10000
單個測試迭代包括兩(2)個事務:
  • 按普通優先級進行一項事務( CFS other
  • 實時優先處理一筆交易( RT-fifo
5000次迭代等於10000個事務。
"S": 9352
9352的事務在同一CPU中同步。
"R": 0.9352
指示客戶機和服務器在同一CPU中一起同步的比率。
"other_ms":{ "avg":0.2 , "wst":2.8 , "bst":0.053, "miss":2, "meetR":0.9996}
普通優先級調用方發出的所有事務的平均( avg ),最差( wst )和最佳( bst )情況。兩筆交易miss最後期限,使得滿足率( meetR )0.9996。
"fifo_ms": { "avg":0.16, "wst":1.5 , "bst":0.067, "miss":0, "meetR":1}
other_ms相似,但適用於具有rt_fifo優先級的客戶端發出的事務。 fifo_ms的結果可能(但不是必須)比other_ms更好,其avgwst值較低,而meetR較高(在後台加載時,差異甚至更大)。

注意:後台負載可能會影響吞吐量測試結果以及延遲測試中的other_ms元組。只要背景負載的優先級低於RT-fifo只有fifo_ms可能會顯示相似的結果。

指定對值

每個客戶端進程與專用於該客戶端的服務器進程配對,並且每個對可以獨立地調度到任何CPU。但是,只要SYNC標誌為honor ,就不應在事務期間發生CPU遷移。

確保系統沒有過載!儘管在過載的系統中預期會有很高的延遲,但是過載系統的測試結果無法提供有用的信息。要測試壓力更高的系統,請使用-pair #cpu-1 (或謹慎使用-pair #cpu )。使用-pair nn > #cpu會使系統過載,並生成無用的信息。

指定截止日期值

經過廣泛的用戶場景測試(在合格產品上運行延遲測試),我們確定2.5ms為截止日期。對於要求更高的新應用程序(例如1000張照片/秒),此截止日期值將更改。

指定詳細輸出

使用-v選項將顯示詳細的輸出。例:

libhwbinder_latency -i 1 -v

-------------------------------------------------- service pid: 8674 tid: 8674 cpu: 1 SCHED_OTHER 0
-------------------------------------------------- main pid: 8673 tid: 8673 cpu: 1 -------------------------------------------------- client pid: 8677 tid: 8677 cpu: 0 SCHED_OTHER 0
-------------------------------------------------- fifo-caller pid: 8677 tid: 8678 cpu: 0 SCHED_FIFO 99 -------------------------------------------------- hwbinder pid: 8674 tid: 8676 cpu: 0 ??? 99
-------------------------------------------------- other-caller pid: 8677 tid: 8677 cpu: 0 SCHED_OTHER 0 -------------------------------------------------- hwbinder pid: 8674 tid: 8676 cpu: 0 SCHED_OTHER 0
  • 服務線程是使用SCHED_OTHER優先級創建的,並以pid 8674CPU:1運行。
  • 然後由fifo-caller啟動第一個事務 。為了處理該事務,hwbinder將服務器的優先級( pid: 8674 tid: 8676 )升級為99,並使用瞬態調度類(打印為??? )對其進行標記。然後,調度程序將服務器進程放在CPU:0中運行,並將其與客戶端的同一個CPU同步。
  • 第二個交易調用方的優先級為SCHED_OTHER 。服務器會自行降級,並以SCHED_OTHER優先級為呼叫者提供服務。

使用跟踪進行調試

您可以指定-trace選項來調試延遲問題。如果使用延遲測試,則在檢測到不良延遲時會停止跟踪日誌記錄。例:

atrace --async_start -b 8000 -c sched idle workq binder_driver sync freq
libhwbinder_latency -deadline_us 50000 -trace -i 50000 -pair 3
deadline triggered: halt ∓ stop trace
log:/sys/kernel/debug/tracing/trace

以下組件會影響延遲:

  • Android構建模式 。 Eng模式通常比userdebug模式慢。
  • 框架 。框架服務如何使用ioctl來配置活頁夾?
  • 活頁夾驅動程序 。驅動程序是否支持細粒度鎖定?它是否包含所有性能提升補丁?
  • 內核版本 。內核具有的實時能力越好,結果越好。
  • 內核配置 。內核配置中是否包含DEBUG配置,例如DEBUG_PREEMPTDEBUG_SPIN_LOCK
  • 內核調度程序 。內核是否具有能量感知調度程序(EAS)或異構多處理(HMP)調度程序?是否有任何內核驅動程序( cpu-freq驅動程序, cpu-idle驅動程序, cpu-hotplug等)影響調度程序?