效能監視器 Unit(PMU) 事件可用來測量 CPU 效能,並瞭解工作負載 CPU 特徵。 每個 CPU 廠商,例如 Arm、Intel 和 AMD,在其平臺上都有可用 PMU 事件的詳細技術參考手冊。 您可以在 ETW 事件上收集 PMU 事件,例如 CSwitch,或在計數器中斷上取樣它們,每當執行期間發生事件溢位時。
列舉系統中支援的PMU事件
您可以使用WPR.exe或Xperf.exe來列舉可用的 PMU 事件。 根據預設,CPU 廠商檔中只有一小部分的 PMU 事件會在 Windows HAL 中實作。 不過,WPR 提供一種方式來擴充未公開為可用配置檔來源的 PMU 事件。 下列命令列出執行中系統上支援的 PMU 事件。
wpr -pmcsources or xperf -pmcsources
命令輸出會顯示可用的 PMU 事件、其預設間隔、間隔範圍,以及目前使用事件的記錄器號碼。
PMU 事件會對應至 效能監視器 計數器 (PMC)。 不過,根據 CPU 的實作,對應不一定是 1 到 1。 此外,大部分 CPU 都會提供一定數目的 效能監視器 計數器 (PMC),以收集特定 PMU 事件。 例如,某些 CPU 提供四個泛型可程式化計數器和三個固定計數器。 結尾為 『Fixed』 的事件名稱適用於固定計數器。 請確定您在系統中啟用正確的 PMU 事件計數。
收集 ETW 事件上的 PMU 事件
CPU 有多個可計算 PMU 事件的計數器 (PMC) 效能監視器。 每當選取的 ETW 事件引發時,您就可以記錄這些計數器值。
若要使用 Windows Performance Recorder (WPR) 以 ETW 事件記錄 PMC 值,請使用 <HardwareCounter>
元素在自訂配置檔中新增計數器和 ETW 事件。 此範例會定義 PMU 事件;TotalCycles 和 InstructionRetired,並在 CSwitch 事件上收集它們。
<SystemProvider Id="SystemProvider_General_Mobile">
<Keywords>
<Keyword Value="ProcessThread" />
<Keyword Value="Loader" />
<Keyword Value="CSwitch" />
</Keywords>
</SystemProvider>
<HardwareCounter Id="HC_PerfWorkloads.Base" Base="" Strict="true">
<Counters>
<Counter Value="TotalCycles"/>
<Counter Value="InstructionRetired" />
</Counters>
<Events>
<Event Value="CSwitch"/>
</Events>
</HardwareCounter>
下列 wpr 設定檔 xml 元素示範如何參考 <HardwareCounter>
中 <SystemCollectorId>
上述定義的 。
<SystemCollectorId Value="SystemCollector">
<SystemProviderId Value="SystemProvider_General_Mobile" />
<HardwareCounterId Value="HC_PerfWorkloads.Base"></HardwareCounterId>
</SystemCollectorId>
若要使用 Xperf.exe 記錄 PMC 值,請使用 -pmc 選項。 下列範例會啟動一個系統會話,收集 CSWITCH 事件上的 InstructionRetired 和 TotalCycles,以及另一個事件會話。
Xperf.exe -on <tracing_flags> -pmc counters events [strict]
Ex>
xperf.exe -on BASE+CSWITCH+POWER+PROC_THREAD+LOADER+MEMINFO+MEMINFO_WS -pmc InstructionRetired,TotalCycles CSWITCH strict -start PMUPerfLogger -on ca92de02-0d94-43a3-9694-d60eb94f2f7d+Microsoft-Windows-Kernel-Pep+Microsoft-Windows-Kernel-Processor-Power:0xC2:4 -BufferSize 1024 -MinBuffers 32 -MaxBuffers 512
如果您使用 InstructionRetired 進行追蹤,特別是 CSwitch 事件上的 TotalCycles 計數器,以及適當的 SystemProvider 關鍵詞,例如 ProcessThread、Loader 和 CSwitch,最新的 Windows 效能分析器 將會顯示每個指令數據表的迴圈。
PMC Overflow 的取樣
除了一般取樣分析的時間取樣(週期計數)之外,您也可以取樣 PMU 事件的頻率,例如分支錯誤預測、快取遺漏或 TLB 遺漏。
若要在 WPR 中取樣 PMU 事件,請在 <SampledCounters>
元素中使用 <HardwareCounter>
。 下列範例會設定在 InstructionRetired 硬體事件上分析的硬體計數器。 Interval 是該類型的事件數目。
<SystemProvider Id="SystemProvider_General_Mobile">
<Keywords>
<Keyword Value="ProcessThread" />
<Keyword Value="Loader" />
<Keyword Value="PmcProfile" />
</Keywords>
</SystemProvider>
<HardwareCounter Id="HC_Sampling.Base" Base="" Strict="true">
<SampledCounters>
<SampledCounter Value="InstructionRetired" Interval="100000"/>
</SampledCounters>
</HardwareCounter>
以下的 WPR 設定檔 xml 元素示範如何參考 <HardwareCounter>
中 <SystemCollectorId>
上述定義的 。
<SystemCollectorId Value="SystemCollector_General_Mobile">
<SystemProviderId Value="SystemProvider_General_Mobile" />
<HardwareCounterId Value="HC_Sampling.Base"/>
</SystemCollectorId>
若要使用 Xperf.exe 來取樣 PMU 事件,請使用 -pmcprofile
選項。 下列範例會啟動一個在 InstructionRetired 上取樣的系統會話。
xperf -on proc_thread+loader+cswitch+dpc+interrupt+pmc_profile -pmcprofile instructionretired -stackwalk pmcinterrupt
設定擴充 PMU 計數器組態
除了您可以透過 命令列舉的架構 PMU 事件 (-pmcsources),您也可以透過 WPR 自定義設定檔或登錄設定來設定非架構 PMU 事件。 這項功能已新增至 Win10 版本 1903。 您可以在數據工作表中找到自定義 PMU 事件描述,或硬體廠商共用。 這些計數器通常是針對所使用的確切處理器模型所特有。
使用 WPRP 自訂設定檔進行設定
下列範例示範如何在自定義配置檔中定義這類計數器。 請注意,Architecture 屬性值全都是大寫和區分大小寫。 不過,如果您忘記,WPR 會以確切的錯誤訊息提醒您。
<MicroArchitecturalConfig Id="CounterConfig_Mine" Base="">
<ProfileSources Architecture="ARM64" Family="8" Model="211" Description="Qualcomm Snapdragon 820">
<ProfileSource Name="SomeCustomCounter" Event="0x3C" Interval="0x02000003" AllowsHalt="false" Persist="false"/>
</ProfileSources>
<ProfileSources Architecture="ARM64" Description="Some Generic Arm counter">
<ProfileSource Name="SomeOtherCustomCounter" Event="0x3D" Interval="0x02000003" AllowsHalt="false" Persist="false"/>
</ProfileSources>
</MicroArchitecturalConfig>
然後使用 MicroArchitecturalConfigId> 中的<擴充計數器組態,就像內建架構計數器一樣。
<HardwareCounter Id="HC_PerfWorkloads.Base" Base="" Strict="true">
<MicroArchitecturalConfigId Value="CounterConfig_Mine"></MicroArchitecturalConfigId>
<Counters>
<Counter Value="SomeCustomCounter"/>
<Counter Value="InstructionRetired"/>
<Counter Value="L3CacheAccess"/>
</Counters>
<Events>
<Event Value="CSwitch"/>
</Events>
</HardwareCounter>
HardwareCounter 中的 strict 旗標會判斷註冊失敗時 WPR 是否會發生硬式錯誤。 如果未指定 strict,工具會以無訊息方式忽略錯誤並繼續。 如果註冊失敗,且其中一個使用未註冊的事件,則稍後仍會失敗。 這允許彈性,因為登錄設定等其他舊版工具可以註冊計數器。 如果現有的事件數據具有相同的值,註冊具有相同名稱的 PMU 事件將會成功。 如果新的程式設計與舊程式設計發生衝突,新的註冊將會失敗,讓舊的註冊就地離開。
針對 Arm,其中一個會依 Event 指定自定義計數器,而 AllowsHalt 是選擇性的。 這些值位於 Arm 的核心系列數據工作表中,或處理器製造商(例如 Qualcomm) 特定處理器數據工作表。 針對 AMD 和 Intel 處理器,其中一個會指定事件和單位,如其數據工作表中所指定。 針對 Intel 除了事件和單位之外,還有一些擴充位可供使用。 這些 ExtendedBits 是 “CMask CMaskInvert AnyThread EdgeDetect”,每兩位數都是不帶正負號的字元。 此欄位是選擇性欄位,因此,如果您不需要特殊位,可以省略它。 例如;
<ProfileSource Name="L1D_PEND_MISS.PENDING_CYCLES_ANY" Event="0x48" Unit="0x01" Interval="0x02000003" ExtendedBits="01000100" />
使用登錄進行設定
您也可以使用登錄設定來設定非原型計數器。 下列登錄範例會設定 Intel 架構的非原型計數器。 這些機制也適用於其他 CPU 實作,並參考廠商的技術參考手冊。
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WMI\ProfileSource\<Model>]
"Architecture"=dword:00000002
"Family"=dword:00000006
"Model"=dword:0000002D
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WMI\ProfileSource\<Model>\BR_INST_EXEC.NONTAKEN_CONDITIONAL]
"Event"=dword:00000088
"Unit"=dword:00000041
"Interval"=dword:00200003
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WMI\ProfileSource\<Model>\BR_INST_EXEC.TAKEN_CONDITIONAL]
"Event"=dword:00000088
"Unit"=dword:00000081
"Interval"=dword:00200003