Skip to main content
Resume
← All projects

Embedded signal processing

Embedded 8×8 DCT

A fixed-point Loeffler 8×8 discrete cosine transform optimized for an ARM Cortex-A15 target.

Lenna test image reconstructed after block-based discrete cosine transformation
320 × 320 test image processed through the 2D DCT path.
Status Completed · 2025
Technologies
  • Embedded C
  • ARMv7-A
  • ARM Cortex-A15
  • NEON SIMD
  • Q17 fixed point
  • CMake
  • QEMU

Overview

The project implements Loeffler’s separable 8×8 DCT in C for an ARMv7-A Cortex-A15 target. It replaces floating-point work with Q17 fixed-point arithmetic and evaluates each optimization with the same nanosecond-per-call benchmark.

A two-dimensional image path applies the one-dimensional transform across rows and columns, with a 320 × 320 input used to check the complete block-processing flow.

Problem and context

An embedded DCT must reduce compute time without changing the transform structure or relying on floating-point hardware. Optimizations also have to account for the cost of moving values into SIMD lanes, not only the number of arithmetic instructions.

The work therefore compared a sequence of explicit variants rather than presenting one final implementation without a baseline.

Technical approach

The baseline routine was progressively transformed through function inlining, macros, local register use, and several NEON arrangements. Each version remained available in the benchmark so its contribution could be measured independently.

NEON was retained where four parallel first-stage operations mapped cleanly to vector lanes. Later stages remained scalar because lane shuffles and memory traffic outweighed their arithmetic benefit.

Key engineering details

Fixed-point representation

Q17 constants replace floating-point coefficients while preserving sufficient intermediate precision for the integer transform.

Stepwise variants

Routine, Inline, Macro, Register, NeonS1, NeonReflect, NeonFull, and Optimized builds make performance changes directly comparable.

Selective SIMD

The best implementation uses NEON in stage one but avoids full vectorization where rearrangement overhead makes the measured result slower.

Repeatable benchmark

The executable emits CSV timing data per variant and also includes the full two-dimensional image transform path.

Results and outcomes

The optimized implementation averaged 81.42 ns per call versus 373.60 ns for the baseline routine.

That is a measured 78.2% reduction in execution time. The full-NEON variant was slower than the selective implementation, demonstrating the cost of lane movement and memory traffic.