Skip to content

Performance Measurement

Linus Jungemann edited this page Aug 31, 2026 · 1 revision

Performance Measurement

FINN+ reports how fast a design is at four increasing levels of fidelity and cost. Use the cheapest one that answers your question.

Level Cost Tells you
Estimates seconds Predicted cycles and resources, per layer
RTL simulation minutesโ€“hours Real throughput and latency, cycle-accurate
Synthesis reports hours Actual resources, timing, power
On hardware needs a board End-to-end throughput, latency, bandwidth

Note

For the analysis-pass API behind the estimates, see Analysis Passes; for the simulation machinery, Simulation Internals.

Estimates

An estimates-only build takes seconds and writes into <output_dir>/report/:

File Contents
estimate_layer_cycles.json Predicted cycles per sample, per layer
estimate_layer_resources.json LUT / BRAM / URAM / DSP per layer, plus a total
estimate_layer_config_alternatives.json Resources per resType / ram_style alternative
estimate_network_performance.json Whole-network throughput and latency
op_and_param_counts.json MAC and parameter counts

This is where all folding exploration should happen. The largest entry in estimate_layer_cycles.json is your bottleneck.

Note

estimate_network_performance.json is not produced for MLO designs. Per-layer estimates still work.

RTL simulation

step_measure_rtlsim_performance writes measured โ€” not predicted โ€” numbers into report/rtlsim_performance.json. Each entry reports the initiation interval in cycles and a derived throughput_fps that already accounts for synth_clk_period_ns.

Note

This step is in the default step list and runs whenever it is reached. Despite the name, the rtlsim_performance entry in generate_outputs does not control it โ€” that value is currently unused. To skip the measurement, remove step_measure_rtlsim_performance from steps.

This is the number to trust before committing to synthesis. A large gap between the estimate and the measured interval usually means FIFO starvation rather than a folding mistake.

Important

Size your FIFOs first. The measurement reads each layer's configured FIFO depths. A depth of 2 is the unconfigured default and triggers a warning that the simulation may deadlock. Run FIFO sizing or supply a fifo_config_file before measuring.

For diagnosing where a pipeline stalls, verify_save_rtlsim_waveforms: true writes report/rtlsim_perf_trace.wdb with per-layer visibility, including FIFO count signals.

Synthesis reports

Estimates rank configurations well, but the authoritative resource and timing numbers come from the tools, after out_of_context_synth or a full bitfile build.

Power

generate_outputs: [..., out_of_context_synth]
vivado_power_simulate_activity: true          # default
vivado_power_simulation_type: functional      # or "timing"

Power estimation requires out-of-context synthesis and fails with Vivado power estimation needs OOC synth otherwise. Simulating switching activity is considerably more accurate than assuming defaults.

On hardware

The generated PYNQ driver measures a deployed accelerator:

driver.run_throughput_test(report_dir="...")   # writes report_throughput_test.json
Metric Meaning
runtime[ms], throughput[images/s] Wall-clock performance for the configured batch size
DRAM_in_bandwidth[MB/s], DRAM_out_bandwidth[MB/s] Achieved hostโ†”accelerator bandwidth
DRAM_extw_<name>_bandwidth[MB/s] Per-stream bandwidth for external weights
fclk[mhz] Actual clock, read back from the platform

Because it reports DRAM bandwidth, this measurement reveals when a design is I/O-bound rather than compute-bound โ€” a case no amount of folding will fix.

Isolating the accelerator

throughput_test includes host and DMA overhead. To measure the accelerator itself, enable the hardware instrumentation wrapper:

enable_instrumentation: true
instrumentation_avg_n: 64        # averaging window, in frames
instrumentation_no_dma: false    # true to exclude the DMA from the measurement

The design then generates its own input stream and counts cycles on-chip. The driver reports:

Field Meaning
min_latency, latency, avg_latency Latency in cycles, averaged over avg_n frames
interval, avg_interval Initiation interval in cycles โ€” the hardware counterpart of the rtlsim figure
checksum, frame Per-frame checksum and frame counter
overflow_err, underflow_err Stream over/underflow flags

The error flags are the fastest check that a design is keeping up with its input stream. The driver's throttle_interval lets you sweep the input rate to find true saturation throughput rather than just the free-running figure.

Warning

Instrumentation is Zynq-only. Enabling it on an Alveo/Vitis build fails with Instrumentation is not yet implemented for Alveo/Vitis flow.

Checksum hooks

A related facility for correctness rather than speed: FINN+ can insert checksum nodes after selected layers, computing a running checksum over the stream without altering it. This answers "at which layer does the hardware start disagreeing with the reference?" when a design passes simulation but fails on the board.

Set the output_hook node attribute to "checksum" on the layers of interest (via your folding config).

Suggested workflow

  1. Iterate on folding using estimates alone.
  2. Size FIFOs, then confirm the design hits its predicted interval in rtlsim.
  3. Synthesize for real resource, timing and power numbers.
  4. On hardware, use the throughput test for end-to-end numbers, and instrumentation when you need the accelerator isolated from host overhead.

See also

FINN+ Wiki

๐Ÿ  Home

๐Ÿ“– User Guide

Using FINN+ to compile a network.

Getting started

Building

Tuning

Checking

Reference


๐Ÿ› ๏ธ Developer Guide

Working on the FINN+ compiler itself.

Getting started

Extending FINN+

Compiler internals

Testing

Reference


๐Ÿ”— External Links

Clone this wiki locally