A W-wide core offers W issue slots per cycle, so slots = cycles x width. Top-down attribution partitions slots, never cycles, into exclusive buckets.
The four buckets are retiring, frontend bound, bad speculation, and backend bound. Backend bound splits further into core bound and memory bound when the evidence supports it.
Percentages partition the slot total and must sum to 100 percent, stating any rounding. Overlapping contributor lists are labeled as overlapping, never as shares.
Assume a 4-wide core at 1 GHz running 1e9 cycles, hence 4.0e9 slots. Measured shares are 35 percent retiring, 20 percent frontend bound, 10 percent bad speculation, 15 percent backend core, and 20 percent backend memory.
slots total = 1.0e9 cycles x 4 = 4.0e9 slots
retiring 35% -> 1.40e9 slots
frontend 20% -> 0.80e9 slots
bad-spec 10% -> 0.40e9 slots
BE core 15% -> 0.60e9 slots
BE memory 20% -> 0.80e9 slots
sum = 35 + 20 + 10 + 15 + 20 = 100%
IPC = 1.40e9 retire slots / 1.0e9 cycles = 1.40
CPI = 1 / 1.40 = 0.714 (rounded)Backend bound totals 35 percent, and memory is 20 of those 35 points, about 57 percent of the backend. Memory is therefore the first hypothesis, not the verdict.
One counter says memory bound while another says backend idle. Resolve the conflict with one experiment that moves only one cause, such as halving the working set or pinning the frequency.
Removing every backend-memory slot would at most lift IPC to (35 + 20) / 100 x 4 = 2.20 from 1.40. That bound sizes the prize before any work starts.
IPC ceiling = (35 + 20) / 100 x 4 = 0.55 x 4 = 2.20
headroom = 2.20 - 1.40 = 0.80 IPC (upper bound, not a promise)They partition one exclusive slot total. A sum past 100 proves overlapping categories were counted twice.
0.80 IPC. The ceiling is (35 + 20) / 100 x 4 = 2.20 versus 1.40 today, an upper bound only.
A combinational slot classifier and a testbench that prove the worked split sums to 100 slots with IPC 1.4.
module topdown_classify (
input logic [2:0] code,
output logic is_retire,
output logic is_front,
output logic is_badspec,
output logic is_core,
output logic is_mem
);
always_comb begin
is_retire = 1'b0;
is_front = 1'b0;
is_badspec = 1'b0;
is_core = 1'b0;
is_mem = 1'b0;
case (code)
3'd0: is_retire = 1'b1;
3'd1: is_front = 1'b1;
3'd2: is_badspec = 1'b1;
3'd3: is_core = 1'b1;
3'd4: is_mem = 1'b1;
default: begin end
endcase
end
endmodule