記錄 CPU 效能追蹤記錄

簡介

CPU 效能監視器追蹤供應器可讓使用者透過 Fuchsia 追蹤系統存取 CPU 內建的效能計數器。

目前僅支援 Intel 晶片組。

在 Intel 上,效能監視器會為使用者提供 CPU 的多個面向統計資料。如需可用於 (例如)如需 Skylake 晶片的相關資訊,請參閱 Intel 第 3 卷第 19.2 章「第 6 和第 7 代處理器的效能監控事件」。目前並非所有事件 (或「計數器」) 都可使用,雖然有很多事件(!),但目前可能還是有一些實用的事件。

以下是一些例子:

  • 快取命中/遺漏次數,針對 L1、L2、L3 各個層級
  • 因快取遺漏而停滯的週期
  • 分支版本預測錯誤
  • 已淘汰的操作說明

追蹤系統會使用「類別」讓使用者指定要收集哪些追蹤資料。Cpuperf 會使用這些類別,簡化要啟用的硬體/軟體事件規格。您可以在這個目錄的 .inc 檔案中找到完整的類別組合。以下列舉幾個代表性類別。

如要收集追蹤記錄資料,請在主機上執行 ffx trace start,或直接在 Fuchsia 裝置上執行 trace

範例:

$ categories="gfx"
$ categories="$categories,cpu:fixed:unhalted_reference_cycles"
$ categories="$categories,cpu:fixed:instructions_retired"
$ categories="$categories,cpu:l2_lines,cpu:sample:10000"
$ ffx trace start --buffer-size 64 --duration 2 --categories $categories

在電腦上取得 .fxt 檔案後,您可以將該檔案載入 Perfetto 檢視器

基本操作

效能資料收集的基本作業是為每個 CPU 的追蹤記錄分配緩衝區,然後在發生預先指定的事件數量後,設定 (每個 CPU 上的) 計數器,以便觸發中斷。這個中斷稱為 PMI 中斷 (效能監視器中斷)。在 Intel 上,中斷會在計數器溢位時觸發,此時中斷服務例行程序會將各種資訊 (例如時間戳記和程式計數器) 寫入追蹤緩衝區,並在事件數量達到預先指定的數字後重設計數器,並傳回。

追蹤停止時,緩衝區會由 Cpuperf 追蹤供應工具讀取,並轉換為 Trace Manager 使用的追蹤格式。

緩衝區填滿時,追蹤記錄也會停止。請注意,系統會使用內部緩衝區,因此 (目前) 不支援循環和串流模式。可收集的追蹤記錄資料量取決於以下因素:

  • 追蹤時間長度
  • 緩衝區空間
  • 取樣頻率
  • 計數器溢位的頻率
  • 是否將程式計數器資訊寫入緩衝區

資料收集類別

如先前所述,Fuchsia 追蹤系統會使用「類別」來讓使用者指定要收集的資料。針對 CPU 追蹤,您可以使用類別指定要啟用的計數器、是否要追蹤作業系統、使用者空間或兩者,以及指定取樣頻率。

如要進一步瞭解各個效能計數器,請參閱 Intel 說明文件。本文件不會嘗試提供每個計數器的詳細資訊。

取樣率

系統會以使用者指定的頻率收集每個計數器的資料。未來將可指定隨機費率。在此期間,我們支援下列費率:

  • cpu:sample:100
  • cpu:範例:500
  • cpu:sample:1000
  • cpu:sample:5000
  • cpu:sample:10000
  • cpu:sample:50000
  • cpu:sample:100000
  • cpu:sample:500000
  • cpu:sample:1000000

獨立取樣

根據預設,每個計數器都會獨立取樣。舉例來說,如果有人要求「cpu:fixed:instructions_retired」和「arch:llc」(Last Level Cache - L3),且取樣率為 10000,則系統會每 10000 個「instruction retired」事件取樣退休指令,每 10000 個「LLC」事件取樣 LLC 作業,前者的發生頻率遠高於後者。系統會透過每個樣本收集時間戳記,讓一個樣本知道所需時間,例如淘汰 10000 指令。

以時間為依據的取樣

您可以使用幾個計數器做為「時間基底」。在時間基準模式中,系統會使用一個計數器來驅動所有計數器的資料收集作業,而非以各自的速率收集各個計數器的資料。這樣一來,您就能更一致地掌握實際情況。另一方面,這樣做代表我們放棄收集每個事件的統計性 PC 資料 (因為我們只有時間基準事件的 PC 值)。除了時間基準計數器外,您也必須提供取樣率。

請參閱下文,瞭解截至本文撰寫時的時間基準計數器組合,以及目前組合的來源樹狀結構中的 src/performance/cpuperf_provider/intel-timebase-categories.inc

計數模式

計數模式是取代取樣模式的簡單做法,在這個模式中,系統會在整個追蹤記錄執行期間收集每個事件的計數,然後回報。

您可以透過「cpu:tally」類別啟用計數模式,而非「cpu:sample:*」類別。

範例:

$ categories="cpu:l2_summary"
$ categories="$categories,cpu:fixed:unhalted_reference_cycles"
$ categories="$categories,cpu:fixed:instructions_retired"
$ categories="$categories,cpu:mem:bytes,cpu:mem:requests"
$ categories="$categories,cpu:tally"
$ ffx trace start --buffer-size 64 --duration 2 --categories $categories

選項

  • cpu:os - 收集核心空間中執行程式碼的資料。

  • cpu:user - 收集在使用者空間執行的程式碼資料。

  • cpu:pc - 收集與每個事件相關的電腦資料

舉例來說,如果想知道快取遺漏通常發生在哪裡 (從統計角度來說,取決於取樣率),這項功能就很實用。追蹤記錄輸出內容包含每個樣本的位址空間和程式計數器。不過,這樣做會使每個追蹤記錄的大小加倍,因此必須權衡利弊。

固定計數器

Intel 架構提供三個「固定」計數器:

  • cpu:fixed:instructions_retired

  • cpu:fixed:unhalted_core_cycles

  • cpu:fixed:unhalted_reference_cycles

這些計數器是「固定」的,因為它們不會使用可程式設計的計數器。共有三個,每個都有固定用途。這類函式的優點是不會使用可程式化的計數器:有數十個計數器,但視模型而定,一次最多僅能使用四個計數器。

可程式化計數器

Skylake (和 Kaby Lake) 晶片上有數十個可程式設計的計數器。如需完整清單,請參閱 Intel 第 3 卷第 19.2 章「第 6 和第 7 代處理器的效能監控事件」。如需目前支援的清單,請參閱來源樹狀結構中的 zircon/system/ulib/zircon-internal/include/lib/zircon-internal/device/cpu-trace/intel-pm-events.inczircon/system/ulib/zircon-internal/include/lib/zircon-internal/device/cpu-trace/skylake-pm-events.inc

為簡化可程式設計計數器的指定作業,這些計數器已分組為來源樹狀結構中的 src/performance/cpuperf_provider/intel-pm-categories.incsrc/performance/cpuperf_provider/skylake-pm-categories.inc 所定義的類別。請參閱這些檔案,瞭解完整清單。

一次只能指定其中一個類別。[稍後我們會提供更多控管選項,讓您決定要收集哪些資料。]

以下是幾個實用的類別:

  • cpu:arch:llc

    • 最後一層快取 (L3) 參照
    • 最後一級快取 (L3) 失敗
  • cpu:arch:branch

    • 分支指令已淘汰
    • 分支指令預測錯誤
  • cpu:skl:l1_summary

    • 每個週期未處理的 L1D 遺漏數
    • 此處理器核心上任何邏輯執行緒的未完成 L1D 遺漏數
    • 帶入 L1 資料快取的行數
  • cpu:skl:l2_summary

    • 未達 L2 的廣告需求要求
    • 所有未達 L2 的要求
    • 所有傳送至 L2 的需求資料讀取要求
    • 所有傳送至 L2 的要求
  • cpu:skl:l3_summary

    • 來自核心的請求,該核心參照 L3 中的快取列
    • 參照 L3 的快取遺漏條件
  • cpu:skl:offcore_demand_code

    • 將 SQ 中未核心的未核心需求程式碼讀取交易次數增加至未核心
    • 循環中至少有 1 個離核心的未完成需求代碼讀取交易,從 SQ 傳送至 uncore
  • cpu:skl:offcore_demand_data

    • 將 SQ 中非核心待處理的資料讀取交易數量,在每個週期內遞增至非核心
    • 在 SQ 中至少有 1 項未核心需求資料讀取交易到未核心的週期
    • 循環中至少有 6 個離核心未完成的 Demand Data Read 交易,從 SQ 傳送至 uncore
  • cpu:skl:l1_miss_cycles

    • 在 L1 資料缺少需求負載時的週期
    • 處理第 1 級資料遺失需求負載時執行停滯
  • cpu:skl:l2_miss_cycles

    • 在 L2 缺少需求負載時週期
    • 執行程序停滯,但 L2 缺少需求載入仍未完成
  • cpu:skl:l3_miss_cycles

    • 在 L3 缺少需求負載時的週期
    • 執行停滯,還有 L3 遺漏需求負載
  • cpu:skl:mem_cycles

    • 記憶體子系統仍有未加負載時的循環
    • 執行階段停滯,而記憶體子系統有未完成的負載

時間基準計數器

這些計數器可做為時間基底。我們會在適當時候新增更多國家/地區。

  • cpu:timebase:fixed:instructions_retired

    • 與 cpu:fixed:instructions_retired 相同的計數器
  • cpu:timebase:fixed:unhalted_reference_cycles

    • 與 cpu:fixed:unhalted_reference_cycles 相同的計數器