ASPLOS'26 Tutorial: RAIC
RESNET-50 · 53 CONVOLUTIONS · PYNQ ZCU104

FEATHER vs. Xilinx DPU

A replay of measured per-layer convolution latency, drawn with each engine's real dataflow.

Both accelerators ran every convolution of ResNet-50 on the same ZCU104 board. The DPU took 280.65 ms in total, FEATHER 62.42 ms, a ratio of 4.50×. The replay below spends that measured time layer by layer, slowed down so the dataflow can be followed: each panel animates the layer at its true size, kernel and stride, with the parallelism of the engine that ran it.

What was measured, and how. Each engine was timed with its own original per-layer notebook, 100 repetitions per layer, averaged. The DPU (B1152, 300 MHz) ran one compiled model per layer, timed around VART execute_async + wait. FEATHER (16×9 PEs, 100 MHz) was timed around the flexDataflow library's run_workload_on_fpga: start the kernel and poll until idle, with no activations fed in. 1×1 layers on FEATHER use the library's folded mapping. The two timers wrap different kinds of call, so read these as per-layer convolution latency under each flow, not pure on-chip cycles, and not whole-network classification speed.
01 / THE RACE

53 convolutions, replayed

measured · replayed
playback align
Xilinx DPUB1152 · 300 MHz
0.00ms
—
—
layers done
FEATHER : DPU
FEATHER16×9 PEs · 100 MHz
0.00ms
—

Time plays both engines at the same rate, so the faster one gets ahead: the race exactly as measured, with the divider counting layers done. Layer starts both on every layer together; whichever finishes first waits at a barrier, and the divider shows that layer's DPU ÷ FEATHER ratio. Pause (or Space) freezes the race while the close-up keeps looping.

02 / DATAFLOW

What each engine does in one cycle

per cycleloop ordersource
FEATHER1 output pixel, its whole 3×3 window, 9 input × 16 output channels = 1,296 MACsoutput-channel tile → input-channel tile → every output pixelHLS DPE_ARRAY, SushiAccel_K16_C9
DPU B11524 output pixels, one kernel tap, 12 input × 12 output channels = 576 MACsnot published; the drawn order is illustrativeXilinx B1152 configuration

FEATHER's kernel is compiled for 3×3. For 1×1 layers the flexDataflow library folds 9 input channels into each PE's 9 multipliers; the 7×7 stem runs as 3×3 sub-layers. A layer is millions of cycles, so when one sweep of the output map would last under a few frames the panel shows whole passes instead and says so.

03 / READING THE PANELS

Terms used in the animation

Maps and sheets

Left is the input feature map, right the output. The sheets behind each map are the channel tile handled per cycle: 9 in / 16 out on FEATHER, 12 / 12 on the DPU.

Pixel and window

An output pixel is one position of the output map; its window is the k×k patch of input it reads. FEATHER fills one window per cycle; the DPU outlines its 4 windows.

Tap

One position inside the k×k kernel, so a 3×3 kernel has 9 taps. FEATHER does all 9 at once; the DPU does one tap per cycle for its 4 pixels, so a 7×7 window takes it 49 cycles.

Strip

The DPU's unit of work: 4 neighbouring output pixels in a row, computed together.

Out-tile and pass

Channels are processed one tile at a time. A pass is one sweep of the whole output map for one input-tile and output-tile pair; the output map darkens as passes complete.

Channel bars and array

Below the maps, the bars show the current input and output channel tile, hatched where the array carries padding the layer lacks. The array picture lights the multipliers doing real work, with the fraction kept busy.

One cycle, up close

The inset loops a few cycles slowly, whatever the playback speed, so the two dataflows can be compared directly.