PC Optimization #CapFrameX#PresentMon#benchmarking

Game Performance Profiling with CapFrameX and PresentMon

Capture frame times, analyze 1% and 0.1% lows, identify CPU vs GPU bottlenecks, and compare test runs using CapFrameX and PresentMon.

7 min read

Average FPS is the most commonly cited performance metric, and also one of the least informative. A game averaging 144 FPS with occasional 50 ms frame spikes feels worse to play than one averaging 110 FPS with perfectly consistent 9 ms frames. Profiling game performance properly means capturing frame time data, understanding percentile statistics, and identifying whether the bottleneck is your CPU or GPU. CapFrameX and PresentMon are the two tools purpose-built for this work.

Why Frame Times Matter More Than Average FPS

Every rendered frame has a delivery time measured in milliseconds. At 144 FPS, the target frame time is 6.94 ms (1000 ms ÷ 144). A “144 FPS” session might have:

  • 90% of frames delivered in 6.5–7.5 ms (smooth)
  • 5% of frames at 15–20 ms (noticeable micro-stutter)
  • 0.5% of frames above 50 ms (jarring hitches)

The 1% low represents the frame time at the 99th percentile — only 1% of frames were slower than this. The 0.1% low represents the 99.9th percentile, capturing the worst spikes. These numbers, expressed in FPS equivalent, are what determine whether a game feels smooth under pressure.

PresentMon: The Foundation

PresentMon is an open-source tool from Intel (github.com/GameTechDev/PresentMon) that hooks into the Windows graphics present path and records per-frame timing data. It captures:

  • msBetweenPresents — wall-clock time between successive frames (what you experience)
  • msInPresentAPI — time the CPU spent in the Present call
  • msBetweenDisplayChange — actual display refresh intervals (requires ETW elevated permissions)
  • GPU busy and wait times (with elevated access)

PresentMon is command-line driven. A typical capture session:

PresentMon64-2.x.x.exe --output_file C:\bench\session1.csv --process_name game.exe --timed 120

This captures 120 seconds of frame data from the process named game.exe and saves the CSV. The output includes a row per frame with all timing fields.

CapFrameX: The Analysis Powerhouse

CapFrameX (capframex.com) wraps PresentMon with a full graphical interface for capture and analysis. It is the tool most enthusiasts use because it handles data collection and visualization in one application.

Installation: Download the installer from capframex.com. Run as administrator — PresentMon’s ETW capture requires elevated permissions. Allow CapFrameX to install the PresentMon service when prompted.

Basic capture workflow:

  1. Launch CapFrameX before starting the game.
  2. Click the Capture tab and configure:
    • Capture hotkey (default: F12, may conflict with Steam — change to F11 or NumPad 0)
    • Capture time in seconds (60–120 seconds is typical for a benchmark run)
    • Recording directory for CSV output
  3. Launch the game, navigate to your test scene, and press the hotkey.
  4. The capture runs for the defined duration and saves automatically.
  5. Return to CapFrameX and click the Analysis tab to load the recording.

Reading the Analysis Tab

CapFrameX’s analysis view shows:

Frame time graph — A line chart where each point is a single frame’s delivery time. Smooth runs show a nearly flat line with minor variation. CPU hitches appear as tall spikes; GPU limitation shows as a consistently elevated baseline.

FPS percentiles: CapFrameX displays:

  • Average FPS
  • P1 low (1% percentile FPS) — what your “bad frames” look like
  • P0.1 low (0.1% percentile FPS) — your worst outliers
  • P99.9 frame time — the complement of P0.1 low in milliseconds

A healthy run has P1 low at 70% or more of average FPS. If your average is 100 FPS but your P1 low is 45 FPS, you have significant stutter that will be perceptible.

Frame time distribution histogram — Shows how frames cluster. A narrow distribution centered near the target frame time indicates consistent pacing. A bimodal distribution (two peaks) indicates alternating fast and slow frames, often caused by double buffering or shader compilation stutter.

Identifying CPU vs GPU Bottlenecks

This is where CapFrameX and PresentMon earn their place. The key metrics are:

GPU-limited: GPU time > CPU time consistently. Frame times are elevated but stable. Reducing graphics settings or resolution reduces frame time proportionally. GPU usage in HWiNFO or Task Manager is at or near 100%.

CPU-limited: CPU frame time exceeds GPU time. Frame times are irregular with frequent spikes. Reducing graphics settings has little effect on frame time — only reducing CPU workload (lower simulation quality, fewer entities, lower resolution with CPU-heavy effects) helps. GPU usage is below 90% despite slow frames.

In PresentMon’s CSV output, examine the msGPUActive column. If this regularly exceeds msBetweenPresents, frames are being dropped because the GPU cannot finish in time. If msGPUActive is consistently below msBetweenPresents but frames are still slow, the bottleneck is CPU preparation or OS scheduling.

CapFrameX’s Sensor tab integrates with HWiNFO64 (which must be running with its sensor server enabled on port 27042) to overlay CPU and GPU load, temperatures, and clocks on the same timeline as frame time data — making bottleneck identification visual and precise.

Comparing Test Runs

CapFrameX’s Comparison tab allows loading multiple recordings side by side. This is essential for objective evaluation of optimization changes:

  1. Run a baseline capture with your current settings.
  2. Make one change (e.g., disable HPET, change power plan, update driver).
  3. Run an identical capture in the same game location.
  4. Load both in the Comparison tab.

The overlay shows percentile FPS for each run as a bar chart, and overlays both frame time graphs. Statistical significance matters: if the difference between two runs is within run-to-run variance (typically ±3–5% for 1% lows), the change had no meaningful effect. Only differences outside variance are worth acting on.

For rigorous testing, run each condition three times and average the percentile metrics. Single runs can be misleading due to background process variation, dynamic game events, or shader cache differences.

Profiling this way transforms optimization from guesswork into data-driven decision-making — and often reveals that the “magic tweak” from a forum post made no measurable difference on your specific hardware.

#FPS analysis #frame time #benchmarking #PresentMon #CapFrameX