Files
TheRock/rocm-systems/experimental/perf-dkms/docs/user_guide_dimensions.md
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

542 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# User Guide: Dimension-Aware Performance Monitoring
This guide explains how to use the dimension-aware performance monitoring features of the amdgpu_pmu driver to monitor specific parts of your AMD GPU hardware.
## Table of Contents
1. [Quick Start](#quick-start)
2. [Understanding GPU Hardware Dimensions](#understanding-gpu-hardware-dimensions)
3. [Event Syntax](#event-syntax)
4. [Common Use Cases](#common-use-cases)
5. [Counter Reference](#counter-reference)
6. [Troubleshooting](#troubleshooting)
## Quick Start
### Prerequisites
- Linux system with AMD GPU (GFX12 or compatible)
- amdgpu_pmu kernel module loaded
- perf tool installed
### Basic Examples
```bash
# Monitor shader engine 0
perf stat -e amdgpu_pmu/sq_waves,se=0/ -a sleep 1
# Monitor specific shader array within SE 1
perf stat -e amdgpu_pmu/sq_waves,se=1,sa=0/ -a sleep 1
# Monitor full dimension path
perf stat -e amdgpu_pmu/sq_waves,se=2,sa=1,wgp=3/ -a sleep 1
```
### Verify Installation
```bash
# Check module is loaded
lsmod | grep amdgpu_pmu
# List available events
perf list amdgpu_pmu
# Check format attributes
ls /sys/bus/event_source/devices/amdgpu_pmu/format/
```
## Understanding GPU Hardware Dimensions
### Hardware Hierarchy
AMD GPUs are organized in a hierarchical structure. Understanding this hierarchy helps you target the right hardware component:
```
GPU (1)
│
└─── XCC - eXtended Compute Core (1)
│
└─── SE - Shader Engine (4 typical)
│
└─── SA - Shader Array (2 per SE)
│
└─── WGP - Work Group Processor (4 per SA)
│
└─── CU - Compute Unit (distributed)
```
### Example: GFX12 Architecture
A typical GFX12 GPU has:
- **1 XCC** (index 0)
- **4 Shader Engines** (SE 0, 1, 2, 3)
- **2 Shader Arrays per SE** (SA 0, 1)
- **4 WGPs per SA** (WGP 0, 1, 2, 3)
- **64 Compute Units total**
Total addressable units: 4 SE × 2 SA × 4 WGP = 32 unique SE/SA/WGP combinations
### What Each Level Represents
**Shader Engine (SE)**:
- Top-level parallel compute unit
- Independent rasterizers and geometry processors
- Typically 4 SEs on modern GPUs
- Workloads are distributed across SEs for parallelism
**Shader Array (SA)**:
- Subdivision within a Shader Engine
- Contains multiple WGPs
- Usually 2 SAs per SE
- Shares L1 cache within SA
**Work Group Processor (WGP)**:
- Basic unit of compute scheduling
- Contains multiple Compute Units
- Work groups (wavefronts) are scheduled to WGPs
- Usually 4 WGPs per SA
**Compute Unit (CU)**:
- Individual SIMD execution unit
- Executes shader instructions
- Multiple CUs per WGP
### Finding Your GPU's Dimensions
```bash
# Method 1: Check kernel log
dmesg | grep "dimension limits"
# Method 2: Using rocminfo (if ROCm installed)
rocminfo | grep -E "Shader Engine|Compute Unit"
# Method 3: Try monitoring and check for errors
# If you get "dimension out of range", you exceeded the limit
perf stat -e amdgpu_pmu/sq_waves,se=10/ -a sleep 1
# Error indicates SE must be < 10
```
## Event Syntax
### Named Parameter Syntax
The recommended way to specify dimensions is using named parameters:
```bash
# Single dimension
-e amdgpu_pmu/sq_waves,se=N/
# Multiple dimensions
-e amdgpu_pmu/sq_waves,se=N,sa=M/
-e amdgpu_pmu/sq_waves,se=N,sa=M,wgp=P/
# All parameters
-e amdgpu_pmu/COUNTER,xcc=X,se=N,sa=M,wgp=P,cu=C/
```
**Available Parameters**:
- `xcc=N` - XCC index (usually 0)
- `se=N` - Shader Engine index (0-3 typical)
- `sa=N` - Shader Array index (0-1 typical)
- `wgp=N` - Work Group Processor index (0-3 typical)
- `cu=N` - Compute Unit index (0-63 typical)
### Raw config1 Encoding
Advanced users can use raw config1 values:
```bash
# SE=1 (bits 8-15): 0x0100
perf stat -e amdgpu_pmu/sq_waves,config1=0x0100/ -a sleep 1
# SE=2, SA=1: 0x00010200
perf stat -e amdgpu_pmu/sq_waves,config1=0x00010200/ -a sleep 1
```
**config1 Bit Layout**:
```
Bits 0-7: xcc
Bits 8-15: se
Bits 16-23: sa
Bits 24-31: wgp
Bits 32-39: cu
Bit 40: aggregate (future)
```
**Default Behavior**:
When dimensions are not specified (no se=/sa=/wgp= parameters), the driver operates in broadcast mode: it reads all hardware instances and aggregates the results.
When you specify dimensions, unspecified sub-dimensions default to 0:
- `se=2` means `se=2,sa=0,wgp=0,cu=0`
- `se=2,sa=1` means `se=2,sa=1,wgp=0,cu=0`
### Combining Multiple Events
Monitor multiple dimensions simultaneously:
```bash
# Compare all 4 shader engines
perf stat \
-e amdgpu_pmu/sq_waves,se=0/ \
-e amdgpu_pmu/sq_waves,se=1/ \
-e amdgpu_pmu/sq_waves,se=2/ \
-e amdgpu_pmu/sq_waves,se=3/ \
-a sleep 5
# Monitor different counters on different SEs
perf stat \
-e amdgpu_pmu/sq_waves,se=0/ \
-e amdgpu_pmu/sq_insts_valu,se=0/ \
-e amdgpu_pmu/ta_busy,se=0/ \
-a ./my_gpu_app
```
## Common Use Cases
### Use Case 1: Load Balancing Analysis
Check if GPU workload is balanced across shader engines:
```bash
#!/bin/bash
# measure_balance.sh
echo "Measuring SE load balance during GPU workload..."
perf stat -e amdgpu_pmu/sq_waves,se=0/ \
-e amdgpu_pmu/sq_waves,se=1/ \
-e amdgpu_pmu/sq_waves,se=2/ \
-e amdgpu_pmu/sq_waves,se=3/ \
-a ./my_gpu_workload
# Ideal: All SEs show similar counts
# Problem: One SE much higher than others (imbalanced)
```
**Interpreting Results**:
```
1,234,567 amdgpu_pmu/sq_waves,se=0/
1,245,890 amdgpu_pmu/sq_waves,se=1/
1,238,234 amdgpu_pmu/sq_waves,se=2/
1,241,098 amdgpu_pmu/sq_waves,se=3/
```
✅ Good: Values are similar (±5%) - well balanced
```
2,456,789 amdgpu_pmu/sq_waves,se=0/
234,567 amdgpu_pmu/sq_waves,se=1/
245,890 amdgpu_pmu/sq_waves,se=2/
238,234 amdgpu_pmu/sq_waves,se=3/
```
⚠️ Problem: SE0 is doing 10x more work - investigate workload distribution
### Use Case 2: Hotspot Detection
Find which shader engine is most active:
```bash
# Continuously monitor and identify hotspot
perf record -e amdgpu_pmu/sq_waves,se=0/ \
-e amdgpu_pmu/sq_waves,se=1/ \
-e amdgpu_pmu/sq_waves,se=2/ \
-e amdgpu_pmu/sq_waves,se=3/ \
-a sleep 10
perf report --stdio
```
### Use Case 3: Memory Hierarchy Analysis
Monitor cache behavior at different levels:
```bash
# L2 cache hits/misses per Shader Array
perf stat \
-e amdgpu_pmu/gl2c_hit,se=0,sa=0/ \
-e amdgpu_pmu/gl2c_miss,se=0,sa=0/ \
-e amdgpu_pmu/gl2c_hit,se=0,sa=1/ \
-e amdgpu_pmu/gl2c_miss,se=0,sa=1/ \
-a ./memory_intensive_app
# Calculate hit rate per SA
```
### Use Case 4: Comparing Workload Patterns
Run different GPU applications and compare their dimension usage:
```bash
# Workload A
perf stat -e amdgpu_pmu/sq_waves,se=0/ \
-e amdgpu_pmu/sq_waves,se=1/ \
-a ./workload_a > results_a.txt
# Workload B
perf stat -e amdgpu_pmu/sq_waves,se=0/ \
-e amdgpu_pmu/sq_waves,se=1/ \
-a ./workload_b > results_b.txt
# Compare results
diff results_a.txt results_b.txt
```
### Use Case 5: Debugging Compute Kernels
Isolate performance issues to specific hardware units:
```bash
# Monitor specific WGP where kernel is running
# (You need to know which WGP your kernel uses - from profiler)
perf stat \
-e amdgpu_pmu/sq_waves,se=1,sa=0,wgp=2/ \
-e amdgpu_pmu/sq_insts_valu,se=1,sa=0,wgp=2/ \
-e amdgpu_pmu/sq_insts_salu,se=1,sa=0,wgp=2/ \
-a ./kernel_test
```
## Counter Reference
### Which Counters Support Which Dimensions?
| Counter Group | Supported Dimensions | Example Counters |
|--------------|---------------------|------------------|
| **Global** | None | `grbm_count`, `grbm_busy`, `grbm_gui_active` |
| **SQ (Sequencer)** | SE, SA, WGP | `sq_waves`, `sq_insts_valu`, `sq_insts_salu`, `sq_busy_cycles` |
| **TA (Texture Addressing)** | SE, SA, WGP | `ta_busy`, `ta_total_wavefronts` |
| **GL2C (L2 Cache)** | SE, SA | `gl2c_hit`, `gl2c_miss`, `gl2c_req` |
### Discovering Counter Support
Trying to use dimensions on a global counter will result in an error:
```bash
$ perf stat -e amdgpu_pmu/grbm_count,se=0/ -a sleep 1
Error: counter 'grbm_count' does not support requested dimensions
```
### Most Useful Dimension-Aware Counters
**SQ Counters** (Shader Sequencer):
```bash
# Wave occupancy per SE
-e amdgpu_pmu/sq_waves,se=N/
# VALU instruction throughput
-e amdgpu_pmu/sq_insts_valu,se=N,sa=M/
# SALU instruction throughput
-e amdgpu_pmu/sq_insts_salu,se=N,sa=M/
# Busy cycles (utilization)
-e amdgpu_pmu/sq_busy_cycles,se=N/
```
**TA Counters** (Texture Unit):
```bash
# Texture unit busy
-e amdgpu_pmu/ta_busy,se=N,sa=M,wgp=P/
# Wavefront count
-e amdgpu_pmu/ta_total_wavefronts,se=N,sa=M/
```
**GL2C Counters** (L2 Cache):
```bash
# Cache hit rate per SA
-e amdgpu_pmu/gl2c_hit,se=N,sa=M/
-e amdgpu_pmu/gl2c_miss,se=N,sa=M/
-e amdgpu_pmu/gl2c_req,se=N,sa=M/
```
## Troubleshooting
### Error: "dimension out of range"
```bash
$ perf stat -e amdgpu_pmu/sq_waves,se=5/ -a sleep 1
Error: dimension out of range: se=5 (max: 3)
```
**Solution**: Your GPU only has SEs 0-3. Use a valid SE index.
### Error: "counter does not support requested dimensions"
```bash
$ perf stat -e amdgpu_pmu/grbm_count,se=0/ -a sleep 1
Error: counter 'grbm_count' does not support requested dimensions
```
**Solution**: This is a global counter. Remove dimension parameters or use a different counter that supports dimensions (like `sq_waves`).
### No Events Counted (All Zeros)
```bash
$ perf stat -e amdgpu_pmu/sq_waves,se=0/ -a sleep 1
Performance counter stats for 'system wide':
0 amdgpu_pmu/sq_waves,se=0/
1.000567890 seconds time elapsed
```
**Possible Causes**:
1. No GPU activity during measurement period
2. Try with an actual GPU workload
3. SE index correct but no work scheduled to that SE
**Solution**:
```bash
# Run with actual GPU workload
perf stat -e amdgpu_pmu/sq_waves,se=0/ -a rocm-smi --showuse &
sleep 2
killall rocm-smi
# Or use a compute application
perf stat -e amdgpu_pmu/sq_waves,se=0/ -a ./my_gpu_app
```
### Module Not Loaded
```bash
$ perf list amdgpu_pmu
List of pre-defined events (to be used in -e):
(empty)
```
**Solution**:
```bash
# Load the module
sudo modprobe amdgpu_pmu
# Verify
lsmod | grep amdgpu_pmu
perf list amdgpu_pmu
```
### Format Attributes Missing
```bash
$ ls /sys/bus/event_source/devices/amdgpu_pmu/format/
ls: cannot access '/sys/bus/event_source/devices/amdgpu_pmu/format/': No such file or directory
```
**Solution**:
1. Module not loaded properly
2. Check dmesg for errors: `dmesg | tail -50 | grep amdgpu_pmu`
3. Reload module: `sudo rmmod amdgpu_pmu && sudo modprobe amdgpu_pmu`
### Permission Denied
```bash
$ perf stat -e amdgpu_pmu/sq_waves,se=0/ sleep 1
Error: Permission denied
```
**Solution**:
```bash
# Either run as root
sudo perf stat -e amdgpu_pmu/sq_waves,se=0/ -a sleep 1
# Or use -a flag for system-wide monitoring (requires CAP_PERFMON or root)
perf stat -e amdgpu_pmu/sq_waves,se=0/ -a sleep 1
```
### Checking Dimension Limits
To find your GPU's maximum dimension indices:
```bash
# Check kernel messages at module load
dmesg | grep "amdgpu_pmu.*dimension limits"
# Example output:
# amdgpu_pmu: Dimension limits: XCC=0 SE=3 SA=1 WGP=3 CU=63
```
This means valid ranges are:
- XCC: 0
- SE: 0-3
- SA: 0-1
- WGP: 0-3
- CU: 0-63
## Advanced Topics
### Scripting and Automation
Create scripts to automate dimension monitoring:
```bash
#!/bin/bash
# monitor_all_dimensions.sh
# Monitor all SE/SA combinations
NUM_SE=4
NUM_SA=2
for se in $(seq 0 $((NUM_SE-1))); do
for sa in $(seq 0 $((NUM_SA-1))); do
echo "Monitoring SE=$se SA=$sa"
perf stat -e amdgpu_pmu/sq_waves,se=$se,sa=$sa/ \
-a -o results_se${se}_sa${sa}.log sleep 5 &
done
done
wait
echo "All measurements complete"
```
### Continuous Monitoring
Use perf record for continuous sampling:
```bash
# Record events continuously
perf record -e amdgpu_pmu/sq_waves,se=0/ \
-e amdgpu_pmu/sq_waves,se=1/ \
-a sleep 60
# Analyze recording
perf report
perf script
```
### Combining with CPU Events
Monitor GPU dimensions alongside CPU performance:
```bash
perf stat \
-e amdgpu_pmu/sq_waves,se=0/ \
-e cpu-cycles \
-e instructions \
-a ./gpu_cpu_app
```
## Best Practices
1. **Start Broad, Then Narrow**: Begin with SE-level monitoring, then drill down to SA/WGP if needed
2. **Compare Against Broadcast**: Always measure broadcast mode (no dimensions) first to establish baseline
3. **Use Consistent Duration**: Keep measurement periods consistent for valid comparisons
4. **Account for Noise**: Run multiple iterations and average results for statistical significance
5. **Understand Your Workload**: Know which SEs your application uses before targeting specific dimensions
6. **Check GPU Topology**: Verify dimension limits for your specific GPU before scripting
## Getting Help
- Check kernel logs: `dmesg | grep amdgpu_pmu`
- Review module parameters: `modinfo amdgpu_pmu`
- Test scripts provided: `test/load_test.sh`, `test/perf_test.sh`
- Report issues with full error messages and GPU model
## Summary
Dimension-aware monitoring enables fine-grained GPU performance analysis by targeting specific hardware units. Use named parameters (`se=N,sa=M`) for readability, validate dimension support for each counter, and compare results across dimensions to identify load imbalances and performance bottlenecks.