Spokes.wiki Search About
Tech Article T3 stable source ↗ source url
Published
Created
Updated

Arm Cortex-A76 Software Optimization Guide

Arm's own instruction-timing tables for the Cortex-A76 (PJDOC-466751330-7215, version 8.0, 46 pages, marked Non-Confidential and "Final, that is for a developed product"). Read for the ARM half of coverage edge 6 — the half uops-info explicitly said it could not cover.

Tier: T3, and the grade is the point. These are latency and throughput figures for Arm's own core, published by Arm, measured by nobody else. Under the load-bearing-claim rule that is the maker describing how well its product works, which is what T3 means — the same branch that puts a maintainer's own benchmark at T3 however reputable the venue. It is worth sitting beside uops-info, which is T2 because Abel and Reineke measure other people's silicon. So this spoke now knows x86 bit instructions from an independent measurement and ARM bit instructions from the vendor, and that asymmetry is not a filing detail: uops.info exists precisely because vendor tables and hardware sometimes disagree.

The document prints a 2019 copyright and a version number and states no publication date, so published: records the year only.

What the columns mean

The definitions are given, and they are not the same quantity uops.info reports:

"Exec Latency is defined as the minimum latency seen by an operation dependent on an instruction in the described group."

"Execution Throughput is defined as the maximum throughput (in instructions per cycle) of the specified instruction group that can be achieved in the entirety of the Cortex-A76 microarchitecture."

Throughput here is instructions per cycle — bigger is better — where uops.info reports cycles per instruction, where smaller is better. Reading one table against the other without flipping that will invert every comparison.

The numbers

AArch64, from the integer and ASIMD tables:

Instruction group Instructions Exec latency Throughput Pipelines
Count leading CLS, CLZ 1 3 I
Reverse bits/bytes RBIT, REV, REV16, REV32 1 3 I
ASIMD count CLS, CLZ, CNT 2 2 V
ASIMD bit reverse RBIT 2 2 V
ASIMD arith, reduce, 4H/4S ADDV, SADDLV, UADDLV 3 1 V1
ASIMD arith, reduce, 8B/8H ADDV, SADDLV, UADDLV 5 1 V1, V
ASIMD arith, reduce, 16B ADDV, SADDLV, UADDLV 6 1/2 V1

Popcount is not one instruction here

This is the finding, and it changes the shape of the comparison this spoke has been making.

CNT counts set bits per byte lane, leaving sixteen separate counts in a 128-bit register. Getting the one number a POPCNT returns takes a horizontal reduction as well, and the reduction is the expensive half: ADDV over 16 byte lanes is 6 cycles of latency at one instruction every two cycles, against CNT's 2 and 2. Three times the latency and a quarter of the throughput, for the step that x86 does not need at all.

(My arithmetic, not the guide's claim: CNT + ADDV over one 128-bit register is 8 cycles of dependent latency and is issue-limited to one such pair every two cycles. uops-info measures VPOPCNTQ zmm at 3 cycles, one per cycle — for 512 bits. The per-cycle bit rate differs by more than an order of magnitude, and almost none of the gap is the counting.)

The reduction cost also scales with lane count in a way the table makes legible: 3 cycles across 4 lanes, 5 across 8, 6 across 16. That is a tree, and its depth is the log of the lane count. Which suggests the obvious structural answer for a real kernel — accumulate CNT results across many registers with cheap pairwise adds and pay ADDV once at the end, rather than per register — though this document prices instructions and does not discuss kernels, so that remains a reading rather than a sourced claim.

Trailing zeros, by way of leading zeros

CLZ is here at latency 1 and throughput 3, alongside RBIT at the same cost. This guide's integer tables list no trailing-zero count at all — there is a count-leading instruction and a bit-reverse instruction and nothing between them. The standard AArch64 idiom is therefore RBIT then CLZ, which these figures price at 2 cycles of dependent latency, two instructions on the same pipeline group. x86 spends one instruction (TZCNT) where AArch64 spends two, and the two are cheap enough that the difference is small. That is the opposite of the popcount result, so the two should not be generalised from each other.

Scoped carefully: this says what the Cortex-A76 optimization guide's tables list. Later architecture versions add scalar bit-counting instructions, and nothing in this corpus sources that yet.

What it does not settle

One core, one generation, 2019, and the whole set is vendor-stated. Nothing here covers the wider Neoverse and Cortex-X cores, Apple's implementations, or SVE — where the vector length is not fixed and the reduction question changes shape. And no independent party has measured any of it. The equivalent of uops-info for AArch64 is the thing this spoke still lacks.

uops-info · population-count · hamming-distance · bit-manipulation · branchless-programming · swar