Repository navigation
Add Runtime CGC GPU execution timing to winml perf - #1492
Merged
Qiong Wu (qiowu) (DingmaomaoBJTU) merged 8 commits intoOct 26, 2026
Merged
Conversation
Qiong Wu (qiowu) (DingmaomaoBJTU)
marked this pull request as ready for review
October 24, 2026 07:35
Qiong Wu (qiowu) (DingmaomaoBJTU)
requested a review
from a team
as a code owner
October 24, 2026 07:35
Zhipeng Wang (timenick)
approved these changes
Oct 26, 2026
Zhipeng Wang (timenick)
left a comment
Contributor
There was a problem hiding this comment.
Re-reviewed 47f166e. All three previously reported P2 issues are addressed: bounded-memory XML streaming, ETW session cleanup after log failures, and pytest-discoverable replay coverage. Focused validation: 14 tests passed, including the prior cleanup and memory reproductions; Ruff and all current-head CI checks passed. Live ETW capture was not verified locally. One non-blocking documentation correction is noted inline.
🤖 Generated with Codex
Zhipeng Wang (timenick)
approved these changes
Oct 26, 2026
Qiong Wu (qiowu) (DingmaomaoBJTU)
enabled auto-merge (squash)
October 26, 2026 07:22
Qiong Wu (qiowu) (DingmaomaoBJTU)
deleted the
codex/runtime-gpu-timing
branch
October 26, 2026 07:27
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
winml perf --runtime winml-runtime --backend cgcreports host-side feed/infer/fetch latency. That interval includes input binding, Runtime execution and output access; it cannot tell how long the GPU spends executing the inference commands.This PR adds
--etw-tracing <new-directory>. It enables the Runtime CGC GPU timestamp provider, collects its events and reports GPU inference-body time separately from the existing CPU latency statistics. The option names the collection mechanism, matching the existing--op-tracingnaming style. This initial implementation supports the Runtime CGC GPU path, not arbitrary ETW providers.Usage and output
Run from a Windows terminal with ETW permissions and a compatible development Runtime:
The trace directory must not already exist.
--iterationsand--warmupretain their existing CLI meanings; enabling tracing does not change their defaults. The example explicitly requests 1000 measured Runs and excludes the first 10 warmup Runs.The console gains a separate GPU execution time (ms; inference body) section with Mean, P50, P95, valid/expected Run counts, ETW loss and recorded-path exclusions. Existing Latency and throughput output retain their CPU-side meaning.
The regular benchmark JSON gains an optional
gpu_executionobject containing:source: runtime-cgc-etw,metric: inference-body, andunit: ms.mean_ms,median_ms,p95_ms, and per-Runsamples_ms.Without
--etw-tracing, the new JSON object is omitted and no ETW session is started.Collection and attribution
Microsoft.Windows.AI.WindowsMLRuntimeCore.GpuTimingat level 4, keyword 0x1, andMicrosoft.Windows.AI.WindowsMLRuntimeCoreat level 4, keyword 0x2.Pipeline.run()call. Warmup calls do not enter the measured-window list.-rtsand-summary.PipelineRunStartusing PID, TID and QPC. Require its successful matchingPipelineRunStop, then associate GPU submissions byRunId. Event delivery order does not determine iteration attribution.For each accepted submission, GPU body milliseconds are
(BodyEnd - BodyStart) * 1000 / TimestampFrequency. Integer timestamps are subtracted before conversion to floating point.Only replay paths 1 and 2 contribute: those timestamps bracket inference commands without surrounding upload/readback. Recorded path 0 includes transfers and is counted but excluded. Statistics summarize one measured window; this is not the Runtime comparison harness's median of per-round medians.
Evidence and failure behavior
GPU statistics are persisted only in the regular benchmark JSON (
gpu_execution). No separate GPU result JSON is written. The summary pass discards its duplicate event dump using-o NUL. The collection directory retains:trace.etlevents.xml|
summary.xml| Tracerpt text summary, including event loss ||
windows.json| Process ID and measured Python call windows ||
capture.log| logman/tracerpt output |The analyzer rejects lost events, missing samples, ambiguous Run matches, unsuccessful/missing Run stops, duplicate measured Run IDs, unknown paths, invalid timestamps/frequency, no replay samples and multiple submissions per measured Run. It does not substitute CPU latency when GPU timing is unavailable. Trace artifacts remain available for diagnosis.
Validation
--etw-tracing; the local TAEF launcher was rebuilt with the new name. The recorded hardware runs preceded this flag-only rename.git diff --checkpassed. Targeted pytest suite: 162 passed (GPU protocol and perf CLI tests). Full src/tests Ruff passed; mypy passed for the collector, analyzer, perf command and Runtime session. Latest-head CI is running.Dependencies and remaining limitations
Expanded tracing profile
The current implementation additionally enables Runtime/ORT/WIL/TIP and DxgKrnl diagnostics at verbose level with all keywords. Unavailable optional providers are recorded in the result; the core timing providers remain required. No kernel stacks or capture-state callbacks are enabled. This diagnostic profile adds CPU/memory/disk overhead and should not be compared directly with untraced baseline latency. Latest YOLO11n run received 1000/1000 samples and zero loss (716653 total ETW events).