Field Guide · concept

Also known as: DSP benchmarking, DSP profiling, throughput measurement

Benchmarking DSP is the practice of measuring how fast a signal-processing pipeline runs — its throughput in samples per second — and profiling where the CPU time goes, so you can confirm the code keeps up with the incoming sample rate and find the stages worth optimizing.1 In software radio the hard constraint is simple: to process a stream arriving at, say, 2.4 Msps in real time, the pipeline must consume more than 2.4 million samples every second, forever, or it falls behind and drops data.

CPU time per stage (profile) downconvertFIR filterdemodframing hotspot real-timebudget
A profile attributes CPU time to each stage; total time per sample must stay under the real-time budget set by the sample rate.

How it works

Benchmarking answers two different questions with two different tools. Microbenchmarks time a single function or block in isolation — run a FIR filter over a fixed buffer many times and report samples per second or nanoseconds per sample. This gives a clean, comparable number for one operation and is ideal for checking whether an optimization actually helped. Profiling runs the whole pipeline and attributes elapsed CPU time to each function, typically by statistical sampling of the call stack, so you can see which stage dominates — usually visualized as a flame graph or a sorted list of hotspots.2

The guiding principle is Amdahl’s law in practice: optimizing a stage that uses 3% of the time can never yield more than a 3% speedup, so you profile first and optimize the tall bar. In DSP that tall bar is almost always the tight per-sample inner loops — filtering, mixing, FFTs — because they touch every one of millions of samples per second, while the framing and protocol logic runs comparatively rarely.

Useful derived metrics:

  • Throughput (Msps) — samples processed per second; compare against the required input rate to get headroom.
  • Cycles or nanoseconds per sample — normalizes throughput so results are comparable across sample rates and machines.
  • Real-time factor — how many times faster than real time an offline run completes; a replay that finishes 20× faster than real time has ample margin.

In practice

Benchmarks must be run on representative input and a warmed-up machine, with enough iterations to swamp measurement noise, and ideally pinned so a background process or CPU frequency scaling does not corrupt the number. Because results are comparative, the highest-value use is regression detection: record a baseline and fail CI if throughput drops, catching a change that quietly halves performance before it ships.

Optimization then follows the hotspot. The classic DSP levers are SIMD vectorization (processing many samples per instruction), better memory access patterns to stay in cache, and multithreading to spread stages across cores. Libraries like VOLK exist precisely to supply hand-tuned, CPU-dispatched kernels for the common per-sample operations so applications inherit the speed without writing assembly.

The honest caution is to keep the benchmark faithful to reality: a microbenchmark that fits entirely in L1 cache can vastly overstate throughput compared to a real pipeline that is memory-bound, so end-to-end throughput on real data is the number that actually predicts whether the radio keeps up.

Relevance to SDR

Meeting the sample-rate budget is the defining performance problem of real-time DSP, and benchmarking is how you prove you meet it with margin to spare for bursts and scheduling jitter. It is what tells you whether a decoder will run on a Raspberry Pi or needs a desktop, and where to spend effort if it does not.

GopherTrunk is a pure-Go application, so it benchmarks with Go’s built-in benchmarking and profiling tooling rather than relying on a VOLK/GNU Radio stack, and its file-replay path doubles as a natural throughput harness: replaying a capture flat-out and measuring the real-time factor shows how much headroom the decode chain has above the live sample rate. Because the decode chain normalizes to a fixed per-protocol channel rate, the steady-state DSP cost is bounded regardless of capture rate, which keeps the performance budget predictable. GT does not use a GPU or hand-tuned SIMD kernel library; it leans on Go’s compiler and clean per-sample loops, and relates the heavier vectorization approaches to the wider ecosystem.

Sources

  1. Benchmark (computing) — Wikipedia, on measuring and comparing the performance of software components. 

  2. Profiling (computer programming) — Wikipedia, on attributing run time to code to locate hotspots worth optimizing. 

See also