beginner

The List That Got Slower Than Its Complexity

Read the counters before the options. Nothing here is labelled with the answer.

The report

We swapped a vector for a linked list so insertions in the middle would be cheap. Insertions did get cheaper. But the nightly aggregation pass, which just walks the whole thing and sums a field, went from about 40 ms to nearly 400 ms on the same data. Nobody changed the loop.

The aggregation pass, unchanged across both versions
// before: contiguous storage
total = 0
for i in 0 .. n-1:
    total += items[i].value

// after: node-per-element, allocated as records arrived
total = 0
node = head
while node != null:
    total += node.value
    node = node.next
CountersSIMULATED
instructions≈ 1.02× the vector versionAlmost exactly the same number of instructions is retired in both versions.
cycles≈ 9.4× the vector versionThe same instruction count takes roughly nine times as many cycles.
IPC0.11 (vector version: 1.02)Very few instructions retire per cycle compared with the vector version.
L1-dcache-load-misses31.8% of loads (vector: 2.1%)Roughly one load in three misses the first-level cache.
LLC-load-misses24.6% of loads (vector: 0.4%)Most of the L1 misses go all the way to memory.
branch-misses0.4% of branchesBranch prediction is essentially perfect in both versions.
What is the hardware doing?