APerf
Originally written by Annie Zhang and Sam Bai; updated by the CS 152 course staff.
APerf helps you investigate where the program spends time. It samples executing functions and presents their call stacks in a flame graph. The setup script installs it. Use profiles to choose what to investigate, and the normal benchmark timings to decide whether a change improved performance.
Collecting a Profile
From your repository root on the instance, run:
make benchmark PROFILE=1
This saves and checks your code, collects the normal timing measurements, then records APerf profiles of the saved executable. To focus on one workload:
make benchmark PROFILE=1 WORKLOAD=texture
Profiling happens after the normal timing measurements so it does not affect the reported speedups.
The command prints each report’s path, for example:
experiments/003/profiles/texture-2048x2048/report/index.html
Viewing a Report
In VS Code Remote SSH, find the printed report/ folder in the Explorer and
choose Download, or copy it to your laptop with scp -r, run on your laptop:
scp -r graviton_cs152:~/{STUDENT REPO DIRECTORY}/experiments/003/profiles/texture-2048x2048/report ./report-003-texture
Download the entire folder so the report has its scripts and data, then open
its index.html locally.
Open reports from different experiments to compare the profiles.
Start with the pgm2svg frames in the flame graph. Short or optimized workloads
may finish before the recording ends; focus on the samples from the program.
Report Sections to Examine
Flame Graphs
Under Profiling → Perf Profiling, flame graph rectangles represent sampled call stacks. Wider frames correspond to more samples; stacked frames show callers and callees. A wide frame is a candidate for investigation, not proof that an optimization will help. Samples may also include idle and runtime/OS activity.
To investigate the pipeline, focus on the call stacks for pgm2svg and follow
the expensive functions into the source. A frame includes samples in its callees,
so adding the widths of nested frames would count those samples more than once.
Compare the expensive functions with the stage timers, then read their source and form a hypothesis about the work they perform. A profile suggests where to look; it does not establish that a proposed change will help.
CPU Utilization
The CPU Utilization section shows how busy each CPU core is. Start with
Aggregate for an overview, distinguishing user (program execution), system
(kernel work), and idle. The aggregate summarizes all four instance CPUs, so a
single busy thread will still leave much of the machine idle. Inspect individual
CPUs to see differences between cores, keeping in mind that a thread can move
between CPUs during the run.
Further Investigation: PMU Events
Performance Monitoring Unit (PMU) hardware counters can help you investigate a hypothesis about why a function is expensive. They are optional diagnostic tools after you have identified an expensive function. Choose metrics relevant to your experiment. These counters describe activity on the CPUs, including work from other processes.
| Metric | Interpretation |
|---|---|
ipc |
Retired instructions per cycle; higher does not necessarily mean faster |
data-l1-mpki, l2-mpki |
Cache misses per thousand instructions, when available |
branch-mpki |
Branch mispredictions per thousand instructions |
stall-backend-pkc |
Backend stall indicator |
stall-frontend-pkc |
Frontend stall indicator |
Counters are diagnostic clues, not proof. Some PMU events are unavailable or unreliable in the VM; missing values are not zero.
Further Guidance
The Performance Engineering Reader explains how to interpret stalls, cache misses, branch behavior, and multicore scaling. For system specifications and SIMD examples, see the c7g.xlarge Crib Sheet.
Recording Details
For each selected input, the saved executable runs RUNS iterations (40 by
default) while APerf records for 10 seconds. RUNS controls both the normal
timing measurements and these profiling executions. Recording and report logs,
plus their archives, are saved under the experiment’s profiles/ directory. If profiling fails, check
the indicated log; successful benchmark results are still retained.