WPR/WPA 實務 ── 從系統整體調查「整台 PC 變慢」

· · Windows, 效能, WPR, WPA, ETW, 效能調查, 故障調查, Windows 開發

「他們說裝了新應用之後整台 PC 就變慢。可是看工作管理員,CPU 和記憶體都還有餘裕。」「有一台 PC 開機要 3 分鐘。完全不知道哪裡不對。」── 效能諮詢真的常常是這種形狀。共通點是:只盯著特定處理程序得不到答案

處理程序層級的工具已經齊備。檔案與登錄存取可用 Process Monitor 看到,.NET 應用的 CPU 與 GC 可用 PerfView 追。但「整台 PC 變慢」或「CPU 閒著卻還是慢」這種症狀,一開始連哪個處理程序是元兇都不知道。應用 A 變慢,可能是防毒掃描、可能是另一個服務猛寫磁碟,也可能是跨好幾個處理程序的鎖鏈。你需要的是不是處理程序內部、而是把整個 OS 記在同一條時間軸上的資料

擷取並讀取那份資料的工具,就是 Windows Performance Recorder(WPR)與 Windows Performance Analyzer(WPA)。WPR 以 ETW(Event Tracing for Windows)為基礎記錄整個 OS 的活動,WPA 用圖表與表格分析那份紀錄。誰在哪個堆疊用了 CPU、執行緒在等誰、哪個處理程序對哪個檔案發出磁碟 I/O──比工作管理員再往下一兩層的事實,都帶著時間戳留下來。

本文以中小企業的 IT 人員與 Windows 應用開發者為對象,依 2026 年 8 月的一手資料,整理用 WPR 擷取的實務,以及怎麼讀 WPA──尤其是調查「CPU 很高」與「CPU 很低卻還是慢」的差異。

1. 先講結論

  • 「整台 PC 變慢」調查的首選是擷取並讀取整個 OS 的 ETW 追蹤的 WPR/WPA。處理程序層級工具(工作管理員、Procmon、PerfView)釘不住的問題,只要把每個處理程序與核心放在同一條時間軸上就能追。12
  • 擷取工具 wpr.exe 從 Windows 8.1 起就內建。不必另外安裝。GUI 版(WPRUI)與分析工具 WPA 包含在 Windows ADK 裡。12
  • 基本步驟就三行。以系統管理員執行 wpr -start GeneralProfile -filemode → 重現問題 → wpr -stop C:\temp\trace.etl。只記住這個就能開始擷取。3
  • 現場基準是拆成「在客戶現場只用 wpr.exe 擷取;閱讀在自己機器上用 WPA」。即使不能安裝軟體的伺服器也能擷取。想法和封包擷取的「用標準工具擷取、用 Wireshark 讀」一樣。1
  • 讀 WPA 從分類「CPU、等待、還是 I/O」開始。CPU 在燒就看 CPU Usage (Sampled);CPU 閒著卻還是慢就做 CPU Usage (Precise) 的等待分析;懷疑磁碟就看 Disk Usage──路徑一開始就分叉。45
  • CPU Usage (Sampled) 以大約每 1 毫秒的取樣,顯示「哪個函式用了 CPU」。可以把工作管理員那個「50%」從處理程序 → 執行緒 → 堆疊 → 函式拆開。6
  • CPU Usage (Precise) 是內容切換的完整紀錄,告訴你「執行緒在等誰」。走 Waits(等待時間)、ReadyingProcess(誰叫醒它)、ReadyThreadStack(叫醒者的堆疊),是本文最想傳達的手法。47
  • 讀堆疊需要符號設定。WPA 預設會參照 Microsoft 的公開符號伺服器。要看到自己應用的函式名稱,請加上自己的 PDB 路徑。8
  • ETL 檔含有處理程序名稱與檔案路徑等系統內部資訊。擷取只做到必要的最小量,並在擷取前決定若帶出公司要怎麼處理。

2. 工具各司其職 ── WPR 擷取,WPA 讀

Windows Performance Toolkit(WPT)是 Windows ADK(Windows Assessment and Deployment Kit)裡的效能調查工具組;核心是 WPR 與 WPA 這一對。2 角色分得很清楚。

  • WPR(Windows Performance Recorder)=擷取。它把一組 ETW 提供者捆成稱為「設定檔」的單位,開始與停止記錄,產出 ETL 檔。命令列版 wpr.exe 從 Windows 8.1 起就內建,不必另外安裝。GUI 版(WPRUI.exe)包含在 ADK 裡。1
  • WPA(Windows Performance Analyzer)=分析。它開啟 ETL 檔,用圖表與表格分析。需要安裝 ADK。2

換句話說,客戶現場什麼都不必放。用 OS 標準的 wpr.exe 擷取,把 ETL 檔帶回來,在自己的 PC 上用 WPA 讀──和封包擷取的「用 pktmon 擷取、用 Wireshark 讀」是同一種拆法。

用 WPR 擷取、用 WPA 讀的分工在客戶現場用 OS 標準的 wpr.exe 記錄並產出 ETL 檔;帶回來在自己已透過 ADK 安裝 WPA 的 PC 上分析自己的 PC(經 ADK 的 WPA)客戶 PC(不必另外安裝)帶回來分析圖表與表格ETL 檔wpr start → 重現 → stop

圖 1: 在客戶現場用 OS 標準的 wpr.exe 記錄並產出 ETL 檔;帶回來在自己已透過 ADK 安裝 WPA 的 PC 上分析。

和相近工具的差異,也值得先整理。

  Process Monitor PerfView WPR + WPA
它回答的問題 哪個處理程序對哪個路徑做了什麼、發生了什麼 .NET 應用的 CPU、GC、配置看起來如何 整個 OS 上,時間消失在哪裡
範圍 檔案、登錄、處理程序啟動的操作紀錄 以受控程式碼為主 系統整體的 CPU、等待、磁碟、檔案 I/O、電源等
適合的症狀 設定沒被讀到、ACCESS DENIED 只有自己的 .NET 應用變慢或記憶體問題 整台 PC 變慢、CPU 閒著卻還是慢、不知道元兇處理程序
文章 Procmon 實戰指南 PerfView 實務入門 本文

若 Procmon 是「做了什麼」的操作紀錄、PerfView 是「.NET 裡面發生了什麼」,WPA 就是跨每個處理程序稽核「時間消失在哪裡」的工具。ETW 本身的機制、以及怎麼為自己的應用加上 ETW 檢測,寫在〈Windows 事件記錄・ETW 入門〉。若自己的應用發出 ETW 事件,應用的檢查點會記在同一份追蹤裡,對齊起來就容易得多。不過 WPR 只記錄你選的記錄設定檔所啟用的提供者事件。GeneralProfile 不含自己的提供者,若要混進來,請準備啟用自己提供者的自訂記錄設定檔(.wprp),並用 wpr -start GeneralProfile -start MyApp.wprp!MyAppProfile 組合,用 ! 指定 .wprp 檔內的設定檔名稱3

3. 擷取實務(WPR)── start、重現、stop

在系統管理員終端機裡的基本步驟。

:: List of built-in profiles you can use
wpr -profiles

:: 1. Start capture (general-purpose profile, file mode)
wpr -start GeneralProfile -filemode

:: 2. Reproduce the issue (check capture status with wpr -status)

:: 3. Stop and save (you can attach a description of the problem).
::    Create the destination folder in advance (without it, -stop fails to save)
mkdir C:\temp 2>nul
wpr -stop C:\temp\slow-pc.etl "Reproduced the issue where the whole PC becomes slow while starting App X"

:: To abandon without saving
wpr -cancel

傳給 -start 的是設定檔,一捆調查所需的 ETW 提供者。3 只記住常用的就夠。9

設定檔 它記錄什麼 何時使用
GeneralProfile 含 CPU 取樣、內容切換、磁碟 I/O 的通用組合 從這裡開始。不知道哪裡不對時的第一手
CPU 詳細的 CPU 使用 已經知道 CPU 在燒時
DiskIO 磁碟 I/O 活動 懷疑磁碟時
FileIO 檔案 I/O 活動 想追哪個檔案正在被存取時

可以連續寫幾個 -start 一次指定多個設定檔(例如 wpr -start GeneralProfile -start FileIO -filemode)。3

WPR 擷取流程與模式怎麼選當場能重現的問題用檔案模式短而可靠地擷取;時機不明的問題用預設的記憶體模式環形緩衝區等待。開機或登入時的問題用開機追蹤。無論哪種,start/重現/stop 的步驟相同當場時機不明開機或登入何時發生?檔案模式:短擷取記憶體模式:等待(3.1)開機追蹤(第 8 章)start → 重現 → stop

圖 2: 當場能重現的問題用檔案模式短而可靠地擷取;時機不明的問題用預設的記憶體模式環形緩衝區等待。開機或登入時的問題用開機追蹤。無論哪種,start/重現/stop 的步驟相同。

3.1. Memory 模式與 File 模式 ── 能重現,還是要等

WPR 有兩種記錄目的地模式;預設是 Memory 模式(記憶體內的環形緩衝區)。它是從最舊事件開始覆寫的環形緩衝區,適合讓擷取持續跑、等時機不明的問題發生、發生時再停。加上 -filemode 就切到 File 模式,一切寫進連續檔案。這個不會被覆寫掉;上限只剩剩餘磁碟空間,檔案會無限成長。10

Memory 模式與 File 模式怎麼記錄Memory 模式寫入記憶體內的環形緩衝區;較舊的事件被覆寫、只留下最近的,因此適合等待。File 模式把一切留在檔案裡,但上限只剩剩餘磁碟空間,因此適合短而可靠的重現ETW 事件Memory 模式:環形緩衝區File 模式:讓檔案成長等時機不明的問題短而可靠的重現

圖 3: Memory 模式寫入記憶體內的環形緩衝區;較舊的事件被覆寫、只留下最近的,因此適合等待。File 模式把一切留在檔案裡,但上限只剩剩餘磁碟空間,因此適合短而可靠的重現。

選擇的經驗法則如下。

  • 當場能重現 → File 模式。重現前一刻開始、剛結束就停,把擷取控制在幾分鐘內
  • 時機不明 → 用 Memory 模式(預設)等待。一發生就 wpr -stop
  • 即使只是幾分鐘的 GeneralProfile,也可能產出數百 MB 到 GB 級的 ETL。檔案太大時 WPA 可能無法分析,所以「擷取得愈久愈好」會適得其反1011

要用 GUI 擷取,啟動 WPRUI,選設定檔與 Logging mode,再 Start/Save。官方 How-to 整理了步驟。11 若請客戶現場窗口擷取,上面三條指令可以直接寫進程序。

4. 讀 WPA 的基礎 ── 圖表、表格金科玉律、縮小時間範圍

把擷取到的 ETL 在 WPA 開啟後,左側的 Graph Explorer 會依 System Activity、Computation、Storage、Memory 等分類列出圖表縮圖。12 把想看的圖表拖到右側 Analysis 頁籤,上方出現圖、下方出現表。先掌握這三件事。

  1. 表格的金科玉律──欄位順序決定分組。WPA 表格有金、藍兩條垂直線,金線左側的欄位依該順序把資料階層化(分組),藍線右側的欄位是彙總13 排成 Process → Stack 就得到依處理程序的堆疊彙總;Stack → Process 就得到使用同一堆疊的每個處理程序的彙總──拖曳欄位重新排序本身就是分析操作。懂這一點,每張 WPA 表格都用同一種讀法。
表格的金科玉律──兩條線與欄位角色金線左側的欄位依該順序把資料階層化;金線與藍線之間是顯示欄;藍線右側是彙總。拖曳欄位重新排序本身就是分析操作金線左側:分組金線兩線之間:顯示藍線藍線右側:彙總拖曳欄位來分析

圖 4: 金線左側的欄位依該順序把資料階層化;金線與藍線之間是顯示欄;藍線右側是彙總。拖曳欄位重新排序本身就是分析操作。

  1. 縮小時間範圍。在圖上拖曳選範圍,再右鍵「Zoom」,彙總就只切到該區間。效能調查原則上永遠只看「問題正在發生的區間」(第 9 章)。
  2. 設定符號。要用函式名稱讀堆疊,從選單執行 Trace > Load Symbols14 預設會參照 Microsoft 的公開符號伺服器(msdl.microsoft.com),所以有網路連線就能解析 Windows 自己的堆疊。要看到自己應用的函式名稱,在 Trace > Configure Symbol Paths 加上自己應用的 PDB 資料夾。8 PDB 是什麼、為什麼即使 Release 組建也該一律保留,整理在〈PDB(程式資料庫)是什麼〉。對 .NET Framework 的 NGen 原生映像,WPR 在擷取時會產生 NGen PDB(.ngenpdb)並放在追蹤旁邊的資料夾,WPA 會自動參照。8 這只是 NGen 映像的機制,一般自己的 JIT .NET 應用程式碼不在範圍內。從 JIT 程式碼位址到函式名稱的對應,是從 CLR 發出的 JIT 事件解析的,因此調查 .NET 應用時,請準備啟用 CLR 提供者(Microsoft-Windows-DotNETRuntime 與對應的 Rundown)的記錄設定檔(.wprp),並用和第 3 章自己的提供者相同的方式組合,wpr -start GeneralProfile -start MyDotNet.wprp!profile-name,讓 CLR 事件進追蹤(可用 wpr -profiles 確認本機 WPR 提供哪些內建設定檔)。除此之外,保留組建產生的 PDB 以便對應到原始碼行,並加到上面的符號路徑。
用函式名稱讀堆疊的符號解析執行 Trace Load Symbols 後,Windows 本身從 Microsoft 公開符號伺服器解析,自己的應用從加到符號路徑的組建 PDB 解析。NGen 映像使用 WPR 產生的 NGen PDB;JIT .NET 程式碼從追蹤裡的 CLR JIT 事件加上組建 PDB 解析Trace > Load SymbolsWindows:公開符號自己的應用:組建 PDBNGen:WPR .ngenpdbJIT:CLR 事件 + PDB

圖 5: 執行 Trace Load Symbols 後,Windows 本身從 Microsoft 公開符號伺服器解析,自己的應用從加到符號路徑的組建 PDB 解析。NGen 映像使用 WPR 產生的 NGen PDB;JIT .NET 程式碼從追蹤裡的 CLR JIT 事件加上組建 PDB 解析。

準備好之後,從下一個分支進入。在那個區間,CPU 是高還是低?高就第 5 章(Sampled);低卻還是慢就第 6 章(Precise)。

依症狀選擇 WPA 圖表的分支縮放到問題區間;CPU 高就到 CPU Usage Sampled;低卻還是慢,先確認是否單核/單執行緒釘住,再做 CPU Usage Precise 的等待分析;懷疑磁碟就看 Disk Usage 與 File IO低卻還是慢懷疑磁碟縮放到問題區間該區間的 CPU?第 5 章:Sampled單核/單執行緒釘住?第 6 章:Precise第 7 章:磁碟/檔案 I/O

圖 6: 縮放到問題區間;CPU 高就到 CPU Usage Sampled;低卻還是慢,先確認是否單核/單執行緒釘住,再做 CPU Usage Precise 的等待分析;懷疑磁碟就看 Disk Usage 與 File IO。

5. CPU 很高時 ── 用 CPU Usage (Sampled) 看「誰在燒哪個函式」

CPU 被釘住時,看的是 CPU Usage (Sampled)。這是大約每 1 毫秒在每顆 CPU 上記錄「現在哪個處理程序的哪個堆疊在跑」的取樣資料,樣本數比例就是 CPU 時間的拆解。6

CPU Usage Sampled 怎麼運作大約每 1 毫秒記錄每顆 CPU 上正在跑的堆疊,彙總後的樣本比例就是 CPU 時間的拆解。從處理程序讀到執行緒、堆疊、函式。樣本之間就結束的短活動不會出現大約每 1 ms 中斷記錄正在跑的堆疊樣本比例 = CPU 拆解處理程序 → 執行緒 → 堆疊樣本之間的活動會漏掉

圖 7: 大約每 1 毫秒記錄每顆 CPU 上正在跑的堆疊,彙總後的樣本比例就是 CPU 時間的拆解。從處理程序讀到執行緒、堆疊、函式。樣本之間就結束的短活動不會出現。

  1. 從 Graph Explorer 的 Computation 把 CPU Usage (Sampled) 放到 Analysis 頁籤,選 Utilization by Process, Stack 預設。5
  2. 依 Weight(或 Count)由大到小看處理程序。工作管理員裡那個「50%」的身分,先在處理程序層級清楚起來。
  3. 展開元兇處理程序的 Stack 欄。堆疊以樹狀彙總,走分叉處數字不太掉的那條路,就會落到正在燒 CPU 的函式。符號若已解析,就是直線對到自己程式碼裡的哪個函式。
  4. 若展開樹很煩,把圖表顯示切到 Flame。寬度=CPU 時間占比,哪條呼叫路徑占主導一目了然。CPU Usage (Sampled) 也有 Flame by Process, Stack 預設。13

有一個注意。因為是取樣,樣本之間就結束的短活動不會出現6 把它記成看「整體上 CPU 用在哪裡」的工具,不是量每次呼叫精確持續時間的工具。

6. CPU 很低卻還是慢 ── CPU Usage (Precise) 與等待分析

這是本文的核心。不過在進入等待分析之前,先確認一件事。「整體 CPU 使用率低」不代表「瓶頸不是 CPU」。在 16 核 PC 上,釘在單核的序列工作(單一 UI 執行緒全力跑)整體看起來只有約 6%。先用第 5 章的 Sampled(或 CPU Usage (Precise) 的 Utilization by CPU)確認沒有特定核心或執行緒被釘住,若沒有,再到這一章──工作不是跑不了,而是在等。告訴你它在等什麼的,是 CPU Usage (Precise)

Sampled 是取樣,Precise 則是內容切換(執行緒切換)的完整紀錄。執行緒進入等待、被誰叫醒(Ready)、落到 CPU──這一趟來回每列留下一行,你可以讀以下欄位。74

欄位 意義
NewThreadStack 該執行緒在哪個堆疊進入等待(=停下時在做什麼)
Waits (us) 等了多久
Ready (us) 從被叫醒到落到 CPU,被讓它等多久(CPU 競爭)
ReadyingProcess / ReadyingThreadId 叫醒該執行緒(解除等待)的處理程序與執行緒
ReadyThreadStack 叫醒者在哪個堆疊叫醒它
一次等待來回與欄位如何對應執行緒在留在 NewThreadStack 的堆疊上進入等待,等 Waits 的時間。有人叫醒它時,那一方留在 ReadyingProcess 與 ReadyThreadStack;它再等 Ready 時間的 CPU 競爭,然後再跑進入等待有人叫醒它落到 CPU執行中等待(Waits us)Ready(CPU 競爭)再次執行NewThreadStack/ReadyingProcess

圖 8: 執行緒在留在 NewThreadStack 的堆疊上進入等待,等 Waits 的時間。有人叫醒它時,那一方留在 ReadyingProcess 與 ReadyThreadStack;它再等 Ready 時間的 CPU 競爭,然後再跑。

讀法如下。4

  1. 套用 Utilization by Process, Thread 預設,並把 NewThreadStack 與 ReadyThreadStack 加到欄位。
  2. 先找出正在執行延遲操作的執行緒(UI 執行緒、處理該請求的執行緒)。只依總 Waits 由大到小看會混亂,因為訊息迴圈或計時器這類「刻意一直在等」的執行緒會占據頂端。找到目標執行緒後,若它的 CPU Usage (ms) 很大就是第 5 章的 CPU 問題;若 Waits 占主導就是等待問題。
  3. 展開 NewThreadStack,看停下時在做什麼WaitForSingleObjectEnterCriticalSection 是鎖等待;在 ReadFile 這類同步 I/O 裡是 I/O 等待;在通訊端接收裡是在等對端回應。
  4. 接著看誰解除了等待。展開 ReadyThreadStack,檢查 ReadyingProcess / ReadyingThreadId。若是從核心的 KiTimerExpiration 叫醒,就是計時器(=睡到逾時);若是從 I/O 完成處理叫醒,就確認是 I/O 等待。4
  5. 若叫醒它的是另一個執行緒或另一個處理程序,用同一套步驟調查那個執行緒。「A 在等 B 放鎖,B 在等 C 的 RPC 回應,C 在等磁碟 I/O」──把這條鏈走到根,得到的就是延遲的關鍵路徑。7
等待分析裡走的關鍵路徑鏈從延遲執行緒 A 的 NewThreadStack 看出停下時在做什麼,從 ReadyThreadStack 與 ReadyingProcess 找出叫醒者 B,再用同一套步驟調查 B,直到根上的磁碟 I/O鎖等待RPC 等待同步 I/O 等待完成叫醒 C回應叫醒 B放鎖叫醒 A執行緒 A(延遲的工作)執行緒 B(握著鎖)處理程序 C磁碟 I/O(根)

圖 9: 從延遲執行緒 A 的 NewThreadStack 看出停下時在做什麼,從 ReadyThreadStack 與 ReadyingProcess 找出叫醒者 B,再用同一套步驟調查 B,直到根上的磁碟 I/O。

在「我們多執行緒了卻沒變快」這種案例,這套步驟會把每個工作者都排在同一把鎖上原樣顯示出來。從設計上避開鎖競爭,寫在〈多執行緒的實務最佳實踐 .NET篇〉;不在同步 I/O 裡等待、而是依完成通知執行的 Windows 機制,寫在〈I/O 完成埠(IOCP)與 .NET 執行緒集區〉。在 WPA 裡釘下「它在等誰」,再用那些設計論點修,是一連貫的流程。

7. 磁碟與檔案 I/O ── 找出「有人在掃磁碟」

「整台 PC 變慢」的經典元兇不是 CPU 而是磁碟。用 Storage 分類裡的 Disk Usage 與 File I/O 調查。15

Disk Usage 是磁碟 I/O 的紀錄,有兩個欄位重要。Disk Service Time 是磁碟裝置實際花在處理該 I/O 的時間;IO Time 是從 I/O 進入 OS 佇列到完成的時間。IO Time 永遠至少是 Service Time 加上佇列量,所以若 IO Time 遠長於 Service Time,該 I/O 是「在佇列裡等」6 不過單憑這一點,還不能決定讓佇列堆起來的元兇是另一個處理程序,還是只有該處理程序自己的沉重 I/O 排在慢裝置上。不要在這裡下結論;用 Service Time(裝置本身的回應)以及接下來依處理程序、路徑、堆疊的拆解來定案。

接著,用 Utilization by Process, Path Name, Stack 預設,依 IO Time 或 Size 由大到小看哪個處理程序從哪個堆疊對哪個檔案發出 I/O。15 現場常出現的答案是這兩種。

  • 防毒正在掃每個檔案。在應用啟動變慢的視窗裡,看到防毒處理程序發出大量讀取。處理程序名稱、路徑、數量本身就是討論排除清單的證據。
  • 另一個處理程序正在猛寫。備份、索引器、寫太多的日誌等。寫入何時到達磁碟牽涉快取管理員,因此「你寫的那一刻」與「磁碟忙碌的那一刻」可能岔開,這一點也寫在〈快取管理員──你的 WriteFile 究竟何時送達磁碟〉。

File I/O 再上一層,是應用發出的檔案操作(Create/Read/Write 等)紀錄,Duration by Process, Thread, Type 這類預設可以依檔名與操作彙總時間。15 在檔案系統或篩選驅動程式裡花時間、還沒到磁碟的案例不會出現在 Disk Usage,因此「Disk Usage 很平靜但 File I/O 很慢」這種不一致本身就是線索。若想從同步與非同步 I/O 的機制開始,見〈同步 I/O 與非同步 I/O──OVERLAPPED 的真正含義〉。

File IO 與 Disk Usage 看到的不同層應用的檔案操作經檔案系統與篩選驅動程式,從 OS I/O 佇列走到磁碟裝置。File IO 記錄上層操作;Disk Usage 記錄到達磁碟的 I/O;IO Time 與 Disk Service Time 的差是佇列時間應用:ReadFile/WriteFile檔案系統與篩選器(File I/O)OS I/O 佇列磁碟裝置(Disk Usage)Disk Usage 看不到IO Time − Service TimeService Time = 裝置

圖 10: 應用的檔案操作經檔案系統與篩選驅動程式,從 OS I/O 佇列走到磁碟裝置。File IO 記錄上層操作;Disk Usage 記錄到達磁碟的 I/O;IO Time 與 Disk Service Time 的差是佇列時間。

「說不定是記憶體不夠在換頁」這條思路,可以在進 WPA 之前先用工作管理員與資源監視器做第一道隔離。不過不要只看認可記憶體就排除──即使認可還有餘裕,實體記憶體壓力裁切工作集、硬錯誤持續發生的情況仍可能。也要看可用實體記憶體與資源監視器的「Hard Faults/sec」。怎麼讀寫在〈Windows 的「記憶體使用量」代表什麼〉。

8. 開機與登入很慢 ── 開機追蹤的入口

「開機要 3 分鐘」這類,還沒來得及親手跑 wpr -start 就結束了。WPR 有開機追蹤,可以安排 OS 在下次開機時自動開始記錄。3

:: 1. Arrange automatic recording on the next boot
wpr -boottrace -addboot GeneralProfile -filemode

:: 2. Restart (reproduce the slow boot)

:: 3. After boot, stop recording and save (the arrangement is also cleared)
mkdir C:\temp 2>nul
wpr -boottrace -stopboot C:\temp\boot.etl "Issue where boot takes 3 minutes"
開機追蹤流程用 addboot 安排下次開機自動記錄並重新啟動後,OS 在開機時自動開始記錄。登入後用 stopboot 儲存也會清除安排。要放棄,用 cancelboot 清除wpr -boottrace -addboot重新啟動(慢開機)OS 在開機時記錄登入後:-stopboot放棄:-cancelboot

圖 11: 用 addboot 安排下次開機自動記錄並重新啟動後,OS 在開機時自動開始記錄。登入後用 stopboot 儲存也會清除安排。要放棄,用 cancelboot 清除。

以前 xbootmgr 負責的開機與關機量測,在現行 WPR 也可以用 -onoffscenario Boot 這類選項跑。3 擷取到的追蹤用前面幾章同一套工具讀。在 Processes 圖上看哪個處理程序何時誕生,縮放到開機卡住的視窗,再分類 CPU、等待或磁碟──啟動應用串行等待某件事、服務啟動卡在特定 I/O 等就會看得見。開機分析本身是一門深的專長,本文只走到入口:「用手抓不到的問題,仍可用 WPR 擷取」。先用 GeneralProfile 開機追蹤掌握整體畫面。

9. 實作模式 ── 分類 → 縮放 → 堆疊,反覆做

工具清楚之後,這是調查整體的模式。

  1. 釘下現象的時間。不是「變慢了」,而是「10:23:40–10:24:10 變慢」。應用日誌、事件記錄、操作者的筆記──什麼都行。若自己的應用把檢查點寫到 ETW 或事件記錄,追蹤裡的事件就原樣成為時間樁。
  2. 只縮放到那個區間。整份追蹤的彙總會被平均掉,真正重要的異常被稀釋。WPA 分析永遠是「異常區間」對「正常區間」的比較。
  3. 先分類「CPU、等待、還是 I/O」。看 CPU Usage (Sampled);在燒就第 5 章。沒在燒就看 CPU Usage (Precise) 的 Waits(第 6 章)。若 Disk Usage 的 IO Time 膨脹,第 7 章。先走這三岔,才不會迷路。
  4. 反覆假設 → 縮放 → 堆疊。若覺得「防毒?」,縮到該處理程序再用堆疊佐證。站不住就下一個假設。在走到堆疊並佐證之前不下結論,是這類調查的紀律。
效能調查的反覆迴圈釘下現象時間、縮放到區間、分類 CPU/等待/I/O、形成假設並縮小範圍、用堆疊佐證。站得住就確認原因;站不住就用下一個假設再來站得住站不住釘下時間縮放到該區間分類 CPU/等待/I/O假設並縮小範圍用堆疊佐證原因確認

圖 12: 釘下現象時間、縮放到區間、分類 CPU/等待/I/O、形成假設並縮小範圍、用堆疊佐證。站得住就確認原因;站不住就用下一個假設再來。

最後是擷取檔的處理。ETL 檔廣泛反映系統內部:每個處理程序的名稱、開啟過的檔案路徑、載入的模組,以及(依設定檔而定)登錄機碼名稱。標準 GeneralProfile 擷取不含通訊內容這類資料本體,但若啟用了自訂提供者,該事件的承載(應用記錄的字串等)會原樣進去。確認你啟用的提供者會發出什麼之後,把它當成機密到足以帶出公司的檔案來對待。和封包擷取一樣,把必要的最小擷取、與交接對方的約定、以及保存期限與刪除寫進程序。

ETL 檔反映什麼、以及怎麼處理ETL 反映每個處理程序名稱、開啟過的檔案路徑、模組,以及依設定檔而定的登錄機碼名稱;啟用自訂提供者也會含其承載。當成機密:必要的最小擷取、與對方的約定、以及保存期限與刪除ETL 檔名稱、路徑、模組登錄機碼(部分)自訂承載當成機密對待

圖 13: ETL 反映每個處理程序名稱、開啟過的檔案路徑、模組,以及依設定檔而定的登錄機碼名稱;啟用自訂提供者也會含其承載。當成機密:必要的最小擷取、與對方的約定、以及保存期限與刪除。

10. 總結

  • 工作管理員解釋不了的「整台 PC 變慢」,用整個 OS 的 ETW 追蹤調查──用 WPR 擷取、用 WPA 讀。wpr.exe 從 Windows 8.1 起就內建,因此「在客戶現場擷取、把 ETL 帶回來、在自己機器上用 WPA 讀」這種拆法成立。
  • 擷取是 wpr -start GeneralProfile -filemode → 重現 → wpr -stop trace.etl 三步。能重現就用幾分鐘內的 File 模式;要等就用 Memory 模式(環形緩衝區)。愈長愈好並不成立。
  • 掌握三點就能開始用 WPA:表格金科玉律(金線左側=分組)、縮放時間範圍、符號設定(自己的應用需要 PDB)。
  • CPU 高,就在 CPU Usage (Sampled) 走處理程序 → 堆疊 → 函式。CPU 低卻還是慢,就在 CPU Usage (Precise) 把 NewThreadStack(停下時在做什麼)→ Waits(等了多久)→ ReadyingProcess 與 ReadyThreadStack(誰叫醒它)這條鏈走到根。
  • 對磁碟,從 Disk Usage 的 IO Time 與 Service Time 之差看出「花在佇列裡的時間」,再從 Service Time 與依處理程序、路徑、堆疊的拆解找出原因(是裝置本身慢,還是誰讓佇列堆起來)。慢開機可用 wpr -boottrace 擷取。
  • 實作模式是(1)釘下時間(2)縮放到區間(3)分類 CPU、等待或 I/O(4)反覆假設 → 縮放 → 堆疊。ETL 含內部資訊,當成機密對待。

WPA 的畫面令人卻步,每個人第一個小時都會迷路。不過一旦「金線左側是分組」與「Sampled 是燒在哪、Precise 是等誰」這兩根主軸進去,其餘就是同一套操作反覆做。下次再接到「CPU 還有餘裕卻還是慢」的諮詢,關掉工作管理員,擷取一份追蹤。

相關文章

相關諮詢領域

小村軟體有限公司承接「整台 PC 變慢、不知道為什麼」「CPU 還有餘裕、應用卻還是慢」「只有特定環境開機極慢」這類系統整體效能問題的調查。我們把 WPR/WPA 的擷取設計(在哪個環境、哪個設定檔、擷取多少)、追蹤分析,以及隨之而來的應用側與設定側修正,當成一連貫的委託來處理。

參考連結

  1. Microsoft Learn, Introduction to WPR. 關於 WPR 是以 ETW 為基礎的效能記錄工具;關於命令列版 WPR.exe 從 Windows 8.1 起就內建、不必另外安裝;它與 GUI 版 WPRUI.exe 的關係;以及記錄設定檔的想法。  2 3 4

  2. Microsoft Learn, Windows Performance Analyzer. 關於 WPA 包含在 Windows ADK,是從 WPR、Xperf 等記錄的 ETW 事件建立圖表與資料表的分析工具,可以開啟並分析任何 ETL 檔。  2 3 4

  3. Microsoft Learn, WPR Command-Line Options. 關於 wpr -start/-stop/-cancel/-status/-profiles 的語法;-filemode(預設是記憶體模式);一次指定多個設定檔;用 -boottrace 做開機追蹤(addboot/stopboot/cancelboot);以及用 -onoffscenario 記錄 Boot 這類開/關轉換。  2 3 4 5 6

  4. Microsoft Learn, CPU Analysis. 關於 CPU Usage (Precise) 圖欄位(NewThreadStack、ReadyThreadStack、ReadyingProcess、Waits 等)的定義;展開 ReadyThreadStack、沿 ReadyingProcess/ReadyingThread 走到等待根本原因的步驟;以及怎麼分辨來自 KiTimerExpiration(計時器等待)或 I/O 完成的喚醒。  2 3 4 5

  5. Microsoft Learn, Troubleshoot processes and threads by using WPR and WPA. 關於高 CPU 使用率時把 CPU Usage (Sampled) 讀成 Process→Stack,以及等待分析時使用 CPU Usage (Precise) 的 Readying Process、Readying Thread、Readying Stack 與 Wait 欄等組態;以及依症狀對應設定檔與圖表的對照表。  2

  6. Microsoft Learn, Exercise 2 - Evaluate Fast Startup Using Windows Performance Toolkit. 關於 CPU Usage (Sampled) 大約以 1 毫秒間隔取樣、樣本之間的短活動不會被記錄;走處理程序 → 執行緒 → 堆疊以找出 CPU 消耗拆解的步驟;以及 Disk Usage IO Time(含佇列時間)與 Disk Service Time(磁碟處理時間)的意義。  2 3 4

  7. Microsoft Learn, Exercise 3 - Understand Critical Path and Wait Analysis. 關於關鍵路徑分析的想法(Running/Ready/Waiting 分類);CPU Usage (Precise) 表格欄位 NewThreadStack、ReadyThreadStack、ReadyingProcess、Waits、Ready 等的意義;以及依序走叫醒者執行緒以拆開延遲鏈的步驟。  2 3

  8. Microsoft Learn, Loading Symbols. 關於 _NT_SYMBOL_PATH 未設定時 WPA 預設參照 Microsoft 公開符號伺服器(msdl.microsoft.com);為自己的元件加上 PDB 路徑;以及 WPR 為 .NET 受控符號在追蹤旁邊的 .ngenpdb 資料夾產生 PDB、WPA 自動參照。  2 3

  9. Microsoft Learn, Built-in Recording Profiles. 關於 WPR 內建記錄設定檔的清單(CPU 使用、磁碟 I/O 活動、檔案 I/O 活動、登錄 I/O 活動、網路 I/O 活動等)以及各設定檔記錄什麼。 

  10. Microsoft Learn, Logging Mode. 關於記錄模式是 File(連續檔案)與 Memory(記憶體內環形緩衝區)、預設是 Memory;關於 Memory 適合時機不明的問題、較舊事件會被覆寫;以及 File 的上限只剩剩餘磁碟空間、檔案太大時 WPA 可能無法分析。  2

  11. Microsoft Learn, WPR How-to Topics. 關於在 WPRUI 開始與停止記錄的步驟;選擇設定檔、詳細程度與 Logging mode;以及長時間記錄會讓檔案巨大、WPA 可能無法分析,因此應選 Memory 模式的注意事項。  2

  12. Microsoft Learn, Graph Explorer. 關於 Graph Explorer 視窗依 System Activity、Computation、Storage、Memory 等分類列出圖表縮圖;以及把圖表拖到 Analysis 頁籤、與表格一起顯示。 

  13. Microsoft Learn, Graphs (WPA Features). 關於 WPA 的 Flame 圖顯示;金線左側欄位是分組、藍線右側欄位是彙總的表格結構;以及 CPU Usage (Sampled) 的 Flame by Process, Stack 預設。  2

  14. Microsoft Learn, Load Symbols or Configure Symbol Paths. 關於從 WPA 的 Trace 選單用 Load Symbols 載入符號;以及在 Configure Symbol Paths 對話方塊設定與變更符號路徑的步驟。 

  15. Microsoft Learn, List of WPA Graphs. 關於 WPA 可用圖表的清單。Disk Usage 預設如 IO Time by Process, IO Type;Service Time by Process, Path Name, Stack;Utilization by Process, Path Name, Stack;以及 File I/O 預設如 Duration by Process, Thread, Type。  2 3

共用相同標籤的最新文章。能以相近的主題延伸理解。

與本文相近的主題頁面。以本文為起點,可進一步連到相關服務與其他文章。

本文連結到以下服務頁面,歡迎從最接近的入口查看。

常見問題

整理諮詢這個主題時常見的問題。

WPR 和 WPA 要去哪裡拿?不能安裝軟體的客戶現場也能用嗎?
擷取工具 wpr.exe(命令列版)從 Windows 8.1 起就內建,不必另外安裝。GUI 版 WPRUI 與分析工具 WPA(Windows Performance Analyzer)包含在 Windows ADK(Windows Assessment and Deployment Kit)裡,需要另外安裝。實務上若拆成「在客戶現場只用 OS 標準的 wpr.exe 擷取 ETL 檔,帶回來在自己的機器上用 WPA 分析」,即使不能加裝軟體的現場也能做系統整體的效能調查。
工作管理員顯示 CPU 還有餘裕,為什麼還是慢?WPA 能看到什麼?
CPU 使用率低卻仍然慢,代表工作不是用不了 CPU,而是停在「等某件事」。鎖競爭、等同步 I/O 完成、等另一個處理程序回應,都是典型情況。工作管理員只顯示結果──使用率;WPA 的 CPU Usage (Precise) 則從每次內容切換的紀錄,看出執行緒從哪開始等(NewThreadStack)、等了多久(Waits)、以及誰叫醒它(ReadyingProcess、ReadyThreadStack)。沿著讓它等待的那一方走下去,就能把「變慢的元兇」追到函式。
追蹤要擷取多久?檔案會不會變得巨大?
問題能重現時,基準是重現前一刻開始、剛重現完就停,控制在幾分鐘內。WPR 預設是 Memory 模式,寫入記憶體內的環形緩衝區;較舊的事件會被覆寫,適合等待發生時機不明的問題。加上 -filemode 的 File 模式會把一切連續寫進檔案,上限只剩剩餘磁碟空間,檔案太大時 WPA 可能無法分析。長時間等待用 Memory 模式,短而可靠的重現用 File 模式。
PerfView 和 WPA 該怎麼選?
兩種工具都處理 ETW 追蹤,但強項不同。PerfView 深懂 .NET 執行階段,擅長 GC、配置、JIT 這類受控應用特有的調查。WPA 適合跨圖表與表格讀整個 OS 的 CPU、磁碟、檔案 I/O、電源等,是「不是特定應用而是整台 PC 慢」、「牽涉多個處理程序」、或「懷疑應用外面(防毒、驅動程式、另一個處理程序)」時的首選。經驗法則是:只有自己的 .NET 應用變慢用 PerfView,整個系統變慢用 WPR/WPA。
在客戶的正式環境跑 WPR 沒問題嗎?
短時間擷取在實務上很常見,但不是無條件安全。ETW 很輕,但連同堆疊記錄大量事件仍會消耗一定的 CPU 與記憶體。把「重現步驟前一刻開始、剛結束就停」「擷取控制在幾分鐘內」「選業務影響小的時段」納入和平常變更一樣的核准流程。另外,ETL 檔含有處理程序名稱、檔案路徑、可執行檔資訊等系統內部資訊,若要帶出公司,應事先決定怎麼處理(最小化、保存期限、刪除)。

作者檔案

本文作者的個人檔案頁面。

Go Komura

小村軟體有限公司 代表

以 Windows 軟體開發、技術諮詢與故障調查為中心,在難以重現的故障調查與既有資產仍在運作的專案上具有優勢。

回到部落格一覽