|
libfreenect2 0.4
Open source driver for the Kinect for Windows v2 (K4W2) sensor
|
How to measure this library's per-frame processing cost reproducibly, what the numbers mean, and where the time actually goes.
This page covers processing throughput — how long a depth or color frame takes to decode once it has arrived. If your problem is frames not arriving at all, or arriving and being dropped, that is a USB question: see Troubleshooting and USB bandwidth and transfer tuning.
Profiling instrumentation is compiled out by default. Turn it on:
ENABLE_PROFILING accumulates a timing sample per frame per stage in memory for the process's lifetime, so it is memory-hungry on long runs and should never be enabled in a shipping build. It is listed among the build options in the README.
Protonect is the benchmark harness. The flags that matter:
| Flag | Effect |
|---|---|
| -noviewer | Skip the GL viewer, so you measure decoding rather than display |
| -frames <n> | Stop after n frames |
| -norgb / -nodepth | Isolate one stream |
| -gpu=<id> | Select a GPU when more than one is present |
| LOGFILE=/dev/null | Send library logging away from the console |
A single-pipeline run:
Repeat per pipeline you care about: cpu, gl, cl, clkde, cuda, cudakde, metal. On Linux, LIBVA_DRIVER_NAME=none forces the color path back to TurboJPEG so you can separate the depth pipeline's cost from the JPEG decoder's — otherwise VAAPI may be selected automatically and the two changes confound each other. See Runtime configuration reference for decoder selection.
Statistics are printed at process exit, one line per timed stage:
All values are milliseconds per frame. Report the median, not the mean — the distributions have long right tails from scheduling jitter, and a single stall skews the mean substantially.
A benchmark result is meaningless without its configuration. Capture:
On Linux, top -d1 in thread view (H), tree view (V), Irix mode (I) gives per-thread CPU usage, which is worth reporting alongside the per-frame times — it distinguishes "the GPU pipeline is fast" from "the GPU pipeline is fast and also leaves the CPU free."
Two costs dominate, and they are independent:
Registration and USB handling are comparatively minor but not free; in upstream's measurements registration alone accounted for up to 20% of a core.
The practical consequence: if your depth pipeline is already on a GPU, the JPEG decoder becomes the bottleneck, and vice versa. Measure both before optimizing either.
Which platforms can offload color decoding, and why the others cannot:
| Platform | Support | Notes |
|---|---|---|
| Intel on Linux (VA-API) | Good | The vaapi decoder; Ivy Bridge or newer |
| Apple (VideoToolbox) | Partial | Present, but not hardware-accelerated in practice, and off by default on Apple Silicon because it crashes there. TurboJPEG is used instead. |
| Tegra | Yes | The only NVIDIA product line with a hardware JPEG decoder |
| NVIDIA desktop (VDPAU) | No | VDPAU does not support JPEG at all |
| AMD | No | Decoding is possible via OpenCL, but it would compete with depth processing for the same GPU |
| Intel on Windows (Media SDK) | Not implemented | Technically possible through the Media Foundation MJPEG transform |
Everything else falls back to TurboJPEG on the CPU, which is fast enough to keep up with 30 Hz on any modern desktop core.
The table below is upstream's February 2016 benchmark data, preserved from the libfreenect2 wiki. Median per-frame times in milliseconds.
| Configuration | Hardware | Depth | RGB |
|---|---|---|---|
| CPU / TurboJPEG | i7-4770K | 201.4 | 13.3 |
| CPU / VAAPI | i7-4770K | 196.8 | 4.6 |
| OpenGL / TurboJPEG | i7-4770K + GTX 980 Ti | 3.7 | 13.5 |
| OpenCL / TurboJPEG | i7-4770K + GTX 980 Ti | 1.1 | 13.8 |
| CUDA / TurboJPEG | i7-4770K + GTX 980 Ti | 0.86 | 13.2 |
| CUDA / VAAPI | i7-4770K + GTX 980 Ti | 0.86 | 4.5 |
| OpenGL / TurboJPEG | i7-4600U + HD 4400 | 15.9 | 18.9 |
| OpenCL / VAAPI | i7-4600U + HD 4400 | 13.2 | 5.0 |
| CUDA / TegraJPEG | Cortex-A15 + Tegra K1 | 10.7 | 11.9 |
Treat these as shape, not as targets. They were taken on Ubuntu 14.04 with CUDA 6.5/7.5 and GCC 4.8 on hardware that is now a decade old, against an older version of the library. What survives is the ordering — CUDA ≲ OpenCL < OpenGL ≪ CPU for depth, and hardware JPEG ≈ 3× TurboJPEG for color — and the observation that 30 Hz (33.3 ms/frame) is comfortably met by every GPU configuration and not met by the CPU processor on the hardware of that era.
This fork's Metal pipeline is not represented; it postdates the data set. CI runs a Metal-versus-CPU parity test on real hardware, which checks correctness rather than speed.
Numbers from current hardware are welcome, particularly Apple Silicon with Metal. Open an issue with the configuration list above, the raw stage lines, and the Protonect invocation.