Skip to content
VLSI Mentor

CXL · Module 18

Performance-Analysis Discipline

Four chapters of models are useless without a method. This chapter builds workload characterisation, Amdahl-bounded fix value, sensitivity, the regression gate, extrapolation limits, confidence, roofline classification, bottleneck ranking, and the decision record.

18.1 decomposed a latency. 18.2 found the binding ceiling. 18.3 added everything the operating system does. 18.4 scaled it across a fabric.

Four chapters of models, and none of them says which model to reach for, how far to trust it, or what to do with the answer. That is this chapter.

1. The Engineering Problem — A Number Is Not An Analysis

Six things separate an analysis somebody can act on from a measurement somebody took.

A model needs its workload characterised, and the inputs it is not given it will assume. The assumption does not appear in the answer. Section 5.

What a fix is worth is bounded by the share it addresses. A 2× speedup on half the work is a 1.33× overall gain, and no speedup on that half can ever exceed 2×. Section 6.

Only one input usually moves the answer, and an analysis that has not identified which one is spending its time on the others. Section 7.

A regression gate without a noise band fails on noise, and a gate that fails on noise is a gate people learn to ignore. Section 9.

A model is valid over the range it was fitted on, and answering outside that range without saying so is the most common way a good model produces a wrong decision. Section 10.

And a decision nobody recorded the basis of cannot be revisited when the inputs change — which they will. Section 14.

This chapter against the previous four, stated precisely. They own what to compute. This one owns whether the computation is worth acting on, and every model here takes another chapter's output as its input.

2. The One-Sentence Model

An analysis is actionable when it states what it assumed, what share it addresses, how far it can be trusted, and how confident it is — and every defect below is a number missing one of those four.

3. What This Chapter Owns

GroundOwner
Decomposing a latency18.1
Finding the binding bandwidth ceiling18.2
The software-visible cost of an access18.3
How a fabric scales18.4
Whether any of those answers is worth acting onthis chapter

Deferred:

Deferred groundOwner
Evaluating a device before purchase17.4
Placing data across tiers17.3
Statistical method beyond sample count and spreadout of scope — see §4
Security's own performance cost19.2

4. Teaching-Model Boundary

Four characterisation inputs, three bottleneck shares, a single noise band and integer percentages are far coarser than a real analysis. They are sized so every boundary is reachable and every result recomputable on paper.

What is not simplified is the structure: a model gated on having its inputs, a gain bounded by the share it addresses, a sensitivity ranked across candidate inputs, a regression compared against noise, a query compared against a fitted range, and a report gated on sample count and spread.

Three things are absent by design. Statistical method is out of scope beyond section 12's sample count and spread — a real analysis needs distributions, confidence intervals and a stated test, and this chapter models only the two properties whose absence is most common. There is no cost model — section 6 says what a fix is worth in speedup and nothing about what it costs to build. And multi-variable interaction is absent: section 7 ranks inputs independently, where real systems have inputs that only matter together.

5. RTL 1 — A Model Assumes What It Is Not Told

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// A model needs its workload characterised; the inputs it does not have it will
// assume, and the assumption is invisible in the answer.
module characterisation #(parameter int ASSUME_DEFAULTS = 0) (
  input  logic clk, rst_n,
  input  logic       model,
  input  logic       rw_known, size_known, locality_known, concurrency_known,
  output logic       characterised,
  output logic [3:0] missing_mask,
  output logic [7:0] n_models, n_assumed,
  output logic       silent_default_err
);
  assign missing_mask[0] = ~rw_known;
  assign missing_mask[1] = ~size_known;
  assign missing_mask[2] = ~locality_known;
  assign missing_mask[3] = ~concurrency_known;
  // The assuming build fills every gap with a default and reports a model.
  assign characterised = (ASSUME_DEFAULTS != 0) ? 1'b1 : (missing_mask == 4'd0);
  // Producing a model from inputs that were never supplied.
  assign silent_default_err = model && characterised && (missing_mask != 4'd0);
  // ... model counters omitted for length
endmodule

Five modelling attempts, one with everything and four each missing one input:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  characterise: models=5 assumed=4 | assuming silent defaults=4

The four inputs are exactly the four that the previous chapters need, and each one is a chapter:

InputWhich model needs it, and what is lost without it
Read/write mix18.2 §9, 17.2 §12 · the achievable rate is off by up to 2×
Access size18.3 §10, §13 · amplification and API share are both unknown
Locality18.3 §6, §9 · the TLB and NUMA terms are guesses
Concurrency18.2 §7 · Little's law has no input

Both builds count four attempts with a missing input. n_assumed is 4 in each — the assuming build knows the input was missing and produces a model anyway. The difference is entirely in characterised, which is the flag anybody downstream would read.

6. RTL 2 — What A Fix Is Worth

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// What a fix is worth is bounded by the share it addresses. Amdahl, applied to
// a bottleneck ranking.
module fix_value #(parameter int ASSUME_FULL = 0) (
  input  logic clk, rst_n,
  input  logic        evaluate,
  input  logic [7:0]  share_pct, speedup_x,
  output logic [7:0]  new_share_pct, overall_pct,
  output logic [15:0] gain_x100, ceiling_x100,
  output logic        worthwhile, overstated_err
);
  logic [31:0] ns_q, ov_q, g_q, c_q;
  logic [31:0] unfixed;
  // The part the fix does not touch.
  assign unfixed = 32'd100 - {24'd0, share_pct};
  assign ns_q = (speedup_x == 8'd0) ? {24'd0, share_pct}
                                    : ({24'd0, share_pct} / {24'd0, speedup_x});
  assign new_share_pct = ns_q[7:0];
  assign ov_q = unfixed + ns_q;
  assign overall_pct = (ov_q > 32'd255) ? 8'hFF : ov_q[7:0];
  // Overall speedup, times a hundred: the original 100 units of work over what
  // remains after the fix.
  assign g_q = (ASSUME_FULL != 0) ? ({24'd0, speedup_x} * 32'd100)
             : ((ov_q == 32'd0) ? 32'd0 : (32'd10000 / ov_q));
  assign gain_x100 = (g_q > 32'd65535) ? 16'hFFFF : g_q[15:0];
  // The ceiling: even an infinite speedup leaves the unfixed part, so no fix
  // can ever beat 100 over what it does not address.
  assign c_q = (unfixed == 32'd0) ? 32'd65535 : (32'd10000 / unfixed);
  assign ceiling_x100 = (c_q > 32'd65535) ? 16'hFFFF : c_q[15:0];
  // The bar is 1.11x rather than 1.10x because 10000/ov is never exactly 110 in
  // integer arithmetic -- ov=90 gives 111 and ov=91 gives 109 -- so a 110 bar has
  // a boundary no input can land on and no test can distinguish.
  assign worthwhile = (gain_x100 > 16'd111);
  // Claiming a gain the addressed share cannot deliver even at infinite speedup.
  assign overstated_err = evaluate && (gain_x100 > ceiling_x100);
endmodule
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  fix: share=50% speedup=2x gain=1.33x ceiling=2.00x | assuming overstated=3
Share addressed, at this speedupOverall gain, against the ceiling
50% at 2×1.33× — ceiling 2.00×
50% at 100×2.00× — exactly the ceiling
10% at 100×1.11× — and the ceiling is also 1.11×
5% at 100×1.05× — not worth building

A 2× speedup on half the work is a 1.33× overall gain, and the assuming build reports 2.00×. The gap is not an approximation — it is the half of the work the fix does not touch, which does not get faster no matter what.

The ceiling_x100 output is the part most analyses lack. A fix addressing 10% of the cost cannot deliver more than 1.11× however good it is — and knowing that before the work starts is the difference between a project and a wasted quarter.

7. RTL 3 — Which Input Moves The Answer

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Sensitivity: which input actually moves the answer, and which one an analysis
// has been spending its time on.
module sensitivity (
  input  logic clk, rst_n,
  input  logic        analyse,
  input  logic [15:0] base_ns,
  input  logic [15:0] d_latency, d_bandwidth, d_concurrency, d_placement,
  output logic [15:0] worst_delta,
  output logic [1:0]  most_sensitive,
  output logic [7:0]  worst_pct,
  output logic        flat, no_lever_err
);
  // ... selection omitted for length
  // A model where nothing moves the answer has no lever, which means the model
  // is missing the input that matters rather than the system being insensitive.
  assign flat = (worst_delta == 16'd0);
  assign no_lever_err = analyse && flat && (base_ns != 16'd0);
endmodule
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  sensitivity: worst=400ns input=0 pct=40%

Four candidate inputs against a 1000 ns base, and the sensitive one is driven to three different positions so the answer cannot be a fixed index:

Deltas — latency / bandwidth / concurrency / placementThe sensitive input, and its share of the base
400 / 50 / 120 / 80latency · 40%
60 / 50 / 500 / 80concurrency · 50%
60 / 50 / 60 / 700placement · 70%
0 / 0 / 0 / 0none — flat · 0%

The fourth row is the model's most useful output. A system where no modelled input moves the answer does not have an insensitive system — it has an incomplete model. Something is driving the cost and it is not among the four things being varied, which is a stronger and more actionable conclusion than "we found no lever".

no_lever_err requires a non-zero base, because a model of nothing is flat for the trivial reason.

8. Waveform — A Fix's Value Falling With Its Share

Transcribed from the printed trace. One stimulus stream, both builds.

An eight-cycle waveform showing the overall gain from a fix as the share of cost it addresses falls. At fifty percent share with a two times speedup the gain is 1.33x; at fifty percent with a hundredfold speedup it reaches the two times ceiling; at ten percent it is 1.11x and at five percent 1.05x. The assuming model reports the raw speedup throughout.2x on half: 1.33x2x on half: 1.33xat the ceilingat the ceiling10% share: 1.11x10% share: 1.11xnot worth itnot worth itclkshare50505050101055speedup22100100100100100100remaining7575505090909595gain133133200200111111105105ceiling200200200200111111105105assumed200200100001000010000100001000010000wortht0t1t2t3t4t5t6t7
Figure 1 — The gain row tracks the ceiling row from cycle 2 onward: past a certain speedup the share is the only thing that matters. The assumed row is the raw speedup, which at cycles 2 to 7 is claiming a hundredfold improvement on a workload whose ceiling is 1.11x.

9. RTL 4 — A Gate Needs A Noise Band

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// A performance gate: what a CI check must do to catch a regression without
// failing on noise.
module regression_gate #(parameter int NO_NOISE_BAND = 0) (
  input  logic clk, rst_n,
  input  logic        run,
  input  logic [15:0] baseline_ns, measured_ns, noise_ns,
  output logic [15:0] delta_ns, threshold_ns,
  output logic        regressed, flaky,
  output logic [7:0]  n_runs, n_failed, n_flaky,
  output logic        noise_fail_err
);
  // A regression must exceed the measurement noise before it is a regression.
  assign delta_ns     = (measured_ns > baseline_ns) ? (measured_ns - baseline_ns) : 16'd0;
  assign threshold_ns = (NO_NOISE_BAND != 0) ? 16'd0 : noise_ns;
  assign regressed    = (delta_ns > threshold_ns);
  // A delta inside the noise band that the gate called a regression.
  assign flaky        = regressed && (delta_ns <= noise_ns);
  assign noise_fail_err = run && flaky;
  // ... run counters omitted for length
endmodule

A 1000 ns baseline with 50 ns of measurement noise:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  gate: runs=4 failed=1 | no-band failed=3 flaky=2
Measured against a 1000 baselineWhat each gate says
1030 — a 30ns deltabanded: pass · no-band: fail, on noise
1050 — exactly at the bandbanded: pass · no-band: fail, on noise
1051 — one past itbanded: fail, a real regression · no-band: fail
900 — an improvementbanded: pass · no-band: pass

The no-band gate failed three of four runs and two of those were noise. A gate with that failure rate is a gate whose failures get re-run until they pass, which is the same as not having one.

The improvement case matters: delta_ns is guarded so a faster run produces a delta of zero rather than an unsigned wrap. Without the guard, every improvement is the largest regression the gate has ever seen.

A state machine showing the lifecycle of a continuous-integration performance gate. From a green state a run whose delta is inside the noise band returns to green; a run whose delta exceeds the band moves to suspect. From suspect, a repeat run that also exceeds the band confirms a regression, while one inside the band returns to green. A confirmed regression is triaged and then either fixed, returning to green, or accepted as a new baseline.GREENSUSPECTREGRESSTRIAGEREBASEinside the bandinside the banddelta exceeds itdelta exceeds itrepeat is cleanrepeat is cleanrepeat confirmsrepeat confirmsattributedattributedacceptedacceptednew baselinenew baseline
Figure 2 — The SUSPECT state is what a noise band buys. Without one, GREEN connects straight to REGRESS and every run inside the noise takes that edge — which is the no-band build failing three runs in four.

The repeat from SUSPECT is the mechanism a noise band makes affordable. A gate that fails 60% of runs cannot afford to re-run every failure; a gate that fails rarely can, and the repeat is what separates a real regression from a slow machine. Removing the band removes the SUSPECT state, and with it the only cheap way to tell the two apart.

10. RTL 5 — A Model Is Valid Where It Was Fitted

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// A model is valid over the range it was fitted on and no further.
module extrapolation #(parameter int UNBOUNDED = 0) (
  input  logic clk, rst_n,
  input  logic        query,
  input  logic [15:0] fit_lo, fit_hi, at_point,
  output logic        in_range, trustworthy,
  output logic [15:0] distance,
  output logic [7:0]  overreach_pct, n_query, n_extrap,
  output logic        extrapolation_err
);
  logic [31:0] op_q;
  logic [15:0] span;
  assign span     = fit_hi - fit_lo;
  assign in_range = (at_point >= fit_lo) && (at_point <= fit_hi);
  assign distance = in_range ? 16'd0
                  : ((at_point > fit_hi) ? (at_point - fit_hi) : (fit_lo - at_point));
  // How far outside the fitted span the query sits, as a share of that span.
  assign op_q = (span == 16'd0) ? 32'd0
              : (({16'd0, distance} * 32'd100) / {16'd0, span});
  assign overreach_pct = (op_q > 32'd255) ? 8'hFF : op_q[7:0];
  // The unbounded build answers any query as though it were fitted there.
  assign trustworthy = (UNBOUNDED != 0) ? 1'b1 : in_range;
  // Answering outside the fitted range without saying so.
  assign extrapolation_err = query && trustworthy && !in_range;
  // ... query counters omitted for length
endmodule

A model fitted between 10 and 50:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  extrapolate: queries=6 outside=3 overreach=0% | unbounded extrapolated=3
Query against a 10-to-50 fitIn range, and the overreach
30yes
10 — the lower edgeyes
50 — the upper edgeyes
9no · 2%
70no · 50% of the fitted span
90no · 100% — as far outside as the fit is wide

Both edges are inside. A model fitted from 10 to 50 is valid at 10 and at 50; excluding the endpoints throws away the two points the fit is most confident about.

overreach_pct is the share of the fitted span, which makes it comparable across models. A query 40 beyond the top of a 40-wide fit is 100% overreach — the model is being asked about a region as large as the one it knows.

11. RTL 6 — A Number Needs A Sample Count

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// A measurement without a sample count and a spread is a number, not a result.
module confidence #(parameter int SINGLE_SAMPLE = 0) (
  input  logic clk, rst_n,
  input  logic        report,
  input  logic [15:0] samples, spread_ns, mean_ns,
  output logic [7:0]  spread_pct,
  output logic        enough_samples, tight, reportable,
  output logic [7:0]  n_reports, n_weak,
  output logic        single_sample_err
);
  // ... spread share omitted for length
  assign enough_samples = (samples >= 16'd10);
  assign tight          = (spread_pct <= 8'd10);
  // The single-sample build reports anything it was handed.
  assign reportable = (SINGLE_SAMPLE != 0) ? 1'b1 : (enough_samples && tight);
  // Reporting a result from one measurement.
  assign single_sample_err = report && reportable && !enough_samples;
  // ... report counters omitted for length
endmodule
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  confidence: reports=7 weak=4 spread=6% | single-sample claims=2

Seven reports, four of them weak — and they are weak for two different reasons:

Samples and spreadReportable, and why not
50 samples, 6% spreadyes
1 sample, 6% spreadno — too few samples
exactly 10 samples, 6%yes
9 samples, 6%no — too few by one
50 samples, 30% spreadno — too loose
50 samples, exactly 10%yes
50 samples, 11%no — too loose by one

Both conditions are necessary and neither is sufficient. Fifty samples with a 30% spread is not a result, and one sample with a 6% spread is not a spread at all. The two mutations that drop either term individually are killed by different rows of that table.

single_sample_err fires only on the sample-count failure, not on the spread failure. A loose result is a weak result honestly reported; a one-sample result presented as a measurement is a different claim.

12. RTL 7 — Which Regime Is The Workload In

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Roofline: whether a workload is limited by bandwidth or by latency, and which
// of the previous three chapters therefore applies.
module roofline #(parameter int ASSUME_BW = 0) (
  input  logic clk, rst_n,
  input  logic        classify,
  input  logic [15:0] bytes_per_op, ops_per_sec_k,
  input  logic [15:0] bw_ceiling_gbps, latency_ns, outstanding,
  output logic [31:0] demand_gbps, latency_bound_gbps,
  output logic [1:0]  regime,
  output logic        bw_bound, lat_bound, misclassified_err
);
  logic [31:0] lb_q;
  assign demand_gbps = ({16'd0, bytes_per_op} * {16'd0, ops_per_sec_k} * 32'd8) / 32'd1000;
  // What the outstanding count can sustain at this latency, per 18.2 section 7.
  assign lb_q = (latency_ns == 16'd0) ? 32'd0
              : (({16'd0, outstanding} * {16'd0, bytes_per_op} * 32'd8000)
                 / {16'd0, latency_ns});
  assign latency_bound_gbps = lb_q;
  // Whichever ceiling is lower is the binding regime.
  assign bw_bound  = ({16'd0, bw_ceiling_gbps} <= latency_bound_gbps);
  assign lat_bound = (latency_bound_gbps < {16'd0, bw_ceiling_gbps});
  assign regime = (ASSUME_BW != 0) ? 2'd0 : (bw_bound ? 2'd0 : 2'd1);
  // Calling a workload bandwidth bound when concurrency is the lower ceiling.
  assign misclassified_err = classify && (regime == 2'd0) && lat_bound;
endmodule
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  roofline: demand=512 lat_bound=65536 regime=0 | assuming misclassified=1
Outstanding, at this latencyThe latency ceiling, and the regime
64 at 500 ns65,536 Gbps — bandwidth bound
2 at 500 ns2,048 Gbps — still bandwidth bound
1 at 2000 ns256 Gbps — latency bound
1 at 1280 nsexactly 400 — the tie, and bandwidth bound

The regime is the answer to "which chapter applies". A bandwidth-bound workload is 18.2's problem; a latency-bound one is 18.1's, and optimising the wrong one is work on a ceiling that is not binding.

The tie is resolved toward bandwidth, and driven exactly: one outstanding request at 1280 ns sustains precisely the 400 Gbps ceiling. Both bw_bound and lat_bound are asserted at that point, because a model where a tie satisfies both or neither has an ambiguous regime.

13. RTL 8 — Rank The Bottlenecks Completely

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Ranking bottlenecks: the order to work in, and what the second one is worth
// once the first is fixed.
module bottleneck_rank (
  input  logic clk, rst_n,
  input  logic        rank,
  input  logic [7:0]  s0, s1, s2,       // shares, percent
  output logic [7:0]  biggest_pct, second_pct,
  output logic [1:0]  first_id, second_id,
  output logic [7:0]  total_pct, unexplained_pct,
  output logic        complete, unexplained_err
);
  logic [7:0] hi, lo;
  assign hi = (s0 > s1) ? s0 : s1;
  assign lo = (s0 > s1) ? s1 : s0;
  assign biggest_pct = (hi > s2) ? hi : s2;
  // The second largest of three: the loser of the top pair, or the third value,
  // whichever is larger.
  assign second_pct  = (hi > s2) ? ((lo > s2) ? lo : s2) : hi;
  // ... identity selection omitted for length
  assign total_pct = s0 + s1 + s2;
  assign unexplained_pct = (total_pct >= 8'd100) ? 8'd0 : (8'd100 - total_pct);
  assign complete = (unexplained_pct == 8'd0);
  // A ranking that does not account for the whole cost has a term nobody named.
  assign unexplained_err = rank && (unexplained_pct != 8'd0);
endmodule
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  rank: biggest=50% (term 0) second=30% (term 1) unexplained=0%
SharesBiggest and second, and what is left
50 / 30 / 20biggest 50 (term 0) · second 30 (term 1) · nothing unexplained
20 / 30 / 50biggest 50 (term 2) · second 30 (term 1) · nothing unexplained
40 / 20 / 15biggest 40 · second 20 · 25 unexplained — a term nobody named
60 / 50 / 20biggest 60 · second 50 · nothing unexplained — but they total 130

The third row is the one that matters most. A ranking accounting for 75% of the cost has a 25% term that nobody has identified — and that unnamed term could be larger than the second-ranked one being worked on. unexplained_err exists to make that visible before anybody starts optimising.

The fourth row is the opposite failure and the model reports it honestly: shares totalling 130% leave nothing unexplained and are double counting. The guard on the subtraction is what prevents an unsigned wrap there, and the row exists to drive it.

second_pct is the second-largest of three, not the loser of the first comparison — and section 12 of 18.2 made the same mistake in a different model. The second-largest of three is the loser of the top pair or the third value, whichever is larger, and getting it wrong reports the wrong thing to work on next.

A flowchart of whether a performance analysis is actionable. An analysis is offered, then checked in turn for whether the workload is characterised, whether the cost is fully ranked, whether the model states its valid range, whether the measurement has enough samples and a tight enough spread, and whether the decision basis is recorded. Passing all five makes it actionable. Failing any one rejects it, and the failure mask names which property is missing.yesyesyesyesyesnoan analysis is offeredworkloadcharacterised?cost fullyranked?valid rangestated?enough samples,tight?basis recorded?actionablea number — the masksays why
Figure 3 — Five properties, five rejection paths. Only the fourth is about the measurement; the other four are about what surrounds it, which is why a correct measurement can still fail this chart.

14. RTL 9 — A Decision Must Be Revisitable

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// A performance decision must record what it was based on, or it cannot be
// revisited when the inputs change.
module decision_record #(parameter int RECORD_RESULT_ONLY = 0) (
  input  logic clk, rst_n,
  input  logic       decide,
  input  logic       inputs_recorded, assumptions_recorded,
  input  logic       method_recorded, range_recorded,
  output logic       revisitable,
  output logic [3:0] gap_mask,
  output logic [7:0] n_decisions, n_orphaned,
  output logic       orphan_err
);
  assign gap_mask[0] = ~inputs_recorded;
  assign gap_mask[1] = ~assumptions_recorded;
  assign gap_mask[2] = ~method_recorded;
  assign gap_mask[3] = ~range_recorded;
  // The result-only build records the answer and nothing that produced it.
  assign revisitable = (RECORD_RESULT_ONLY != 0) ? 1'b0 : (gap_mask == 4'd0);
  // A decision nobody can revisit when an input changes.
  assign orphan_err = decide && !revisitable;
  // ... decision counters omitted for length
endmodule
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  record: decisions=5 orphaned=4 | result-only orphaned=5

Four things a performance decision must record, each falsified alone:

RecordedWithout it
The inputsnobody knows what workload it was measured on
The assumptionssection 5's silent defaults are permanent
The methodthe measurement cannot be repeated
The valid rangesection 10's extrapolation limit is lost

The result-only build orphans all five decisions, including the one where everything was recorded — because it records nothing regardless of what was available. That is the honest model of a decision captured as a number in a slide: the analysis existed, and none of it survived.

This is where the chapter's models compose. A decision made on section 5's characterisation, bounded by section 6's ceiling, valid over section 10's range and confident by section 11's test is exactly the four things this model asks to be recorded.

15. RTL 10 — The Discipline Assembled

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// The analysis discipline assembled: every property an actionable performance
// claim needs.
module analysis_discipline #(parameter int NUMBER_ONLY = 0) (
  input  logic clk, rst_n,
  input  logic       assess,
  input  logic       characterised,   // the workload's inputs are known
  input  logic       ranked,          // the cost is fully attributed
  input  logic       bounded,         // the model states its valid range
  input  logic       confident,       // enough samples, tight enough spread
  input  logic       recorded,        // the decision can be revisited
  output logic       actionable,
  output logic [4:0] fail_mask,
  output logic [7:0] n_assess, n_actionable,
  output logic       bare_number_err
);
  assign fail_mask[0] = ~characterised;
  assign fail_mask[1] = ~ranked;
  assign fail_mask[2] = ~bounded;
  assign fail_mask[3] = ~confident;
  assign fail_mask[4] = ~recorded;
  // The number-only build reports a measurement and calls it an analysis.
  assign actionable = (NUMBER_ONLY != 0) ? confident : (fail_mask == 5'd0);
  assign bare_number_err = assess && actionable && (fail_mask != 5'd0);
  // ... assessment counters omitted for length
endmodule
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  discipline: assessed=6 actionable=1 | number-only actionable=5

One actionable analysis out of six, and the number-only build found five. Its four extra are characterisation, ranking, bounds and the record — every property that is about the analysis rather than about the measurement:

PropertyWhat it is about, and whether the number-only build sees it
Characterisedthe workload · missed
Rankedthe attribution · missed
Boundedthe model · missed
Confidentthe measurement · caught
Recordedthe process · missed

This is the fifth assembled model in two batches with the same structure, and the most general statement of it: a simplified model passes the gates that are visible from where it stands, and this one stands at the measurement. 17.4 stood at the datasheet, 18.1 at the bench, 18.3 at the hardware specification, and 18.4 at the switch.

A block diagram of how the four previous performance chapters feed this one. Latency anatomy, throughput, memory-access cost and fabric scaling each produce a model. Those models feed a characterisation stage, which feeds a ranking stage, which feeds a bounded and confident assessment, which produces a recorded decision. A dashed path runs from any single model straight to the decision, bypassing every stage.18.1 latencyhop decomposition18.2 throughputbinding ceiling18.3 access costthe OS terms18.4 fabricscale termscharacterisefour inputsrankshares to 100%assessbounded, confidentdecisionrecorded, revisitablea bare numberstraight to the slidea modelinputs knownsharesactionableskips all four12
Figure 4 — The four chapters on the left produce models; the three stages in the middle are what turns a model into a decision. The dashed path is the number-only build: it reaches the same decision node having passed through none of them.

16. Quantitative Reasoning

Every number is from a printed line above.

Characterisation. Five modelling attempts, four with a missing input — and the assuming build produced a model for all five.

Fix value. 2× on a 50% share is 1.33×. 100× on the same share is 2.00×, exactly the ceiling. 100× on a 5% share is 1.05×.

Sensitivity. A 400 ns delta on a 1000 ns base is 40% — and with all deltas zero the model reports no lever, not an insensitive system.

Regression gate. Four runs: the banded gate failed one, the no-band gate failed three, of which two were noise.

Extrapolation. A fit from 10 to 50: both edges inside, 70 is 50% overreach, 90 is 100% — as far outside as the fit is wide.

Confidence. Seven reports, four weak — two for too few samples and two for too loose a spread.

Roofline. 64 outstanding at 500 ns sustains 65,536 Gbps against a 400 Gbps ceiling: bandwidth bound. One outstanding at 2000 ns sustains 256latency bound.

Ranking. 40/20/15 leaves 25% unexplained — potentially larger than the second-ranked term.

Discipline. Six assessments, one actionable, against a number-only build's five.

17. Assertions

Every property is an immediate check written as cond !== 1'b1, sampled after a settle. 178 assertion sites across two testbenches.

# · modelProperty
1 · characteriseAll four inputs known
2 · characteriseSo the workload is characterised
3 · characteriseWith no silent default
4 · characteriseIn either build
5 · characteriseThe concurrency input alone is missing
6 · characteriseSo the correct build refuses to model
7 · characteriseThe assuming build models anyway
8 · characteriseWhich is a silent default
9 · characteriseAnd the correct build makes none
10 · characteriseThe read/write mix alone
11 · characteriseThe access size alone
12 · characteriseThe locality input alone
13 · characteriseFive modelling attempts
14 · characteriseFour of them with a missing input
15 · characteriseCounted identically by the assuming build
16 · characteriseThe correct build never defaults silently
17 · characteriseThe assuming build did on all four
18 · fixThe fixed half becomes a quarter
19 · fixSo 75 percent of the work remains
20 · fixA 1.33x overall gain
21 · fixAgainst a ceiling of 2.00x
22 · fixWhich is worthwhile
23 · fixThe assuming build claims the full 2.00x
24 · fixThe correct build never overstates
25 · fixA hundredfold speedup removes the share entirely
26 · fixLeaving the untouched half
27 · fixA 2.00x gain — exactly the ceiling
28 · fixWhich is not an overstatement
29 · fixThe assuming build claims a hundredfold
30 · fixWhich is
31 · fixFixing a tenth leaves ninety percent
32 · fixA 1.11x gain
33 · fixAt a ceiling of 1.11x
34 · fixWhich does not clear a 1.11x bar
35 · fixFixing a twentieth is a 1.05x gain
36 · fixWhich is well short of the bar
37 · fixThe correct model never overstates a fix
38 · fixThe assuming build overstated three times
39 · sensitivityLatency moves the answer most, by 400ns
40 · sensitivitySo latency is the sensitive input
41 · sensitivityAt 40 percent of the base
42 · sensitivityWhich is not flat
43 · sensitivitySo there is a lever
44 · sensitivityConcurrency now moves it most
45 · sensitivitySo concurrency is the sensitive input
46 · sensitivityPlacement is now the sensitive input
47 · sensitivityNo input moves the answer
48 · sensitivityWhich is flat
49 · sensitivityAnd is reported as having no lever
50 · sensitivityAn empty base is not a missing lever
51 · gateA 30ns delta
52 · gateInside a 50ns noise band is not a regression
53 · gateThe no-band build calls it one
54 · gateWhich is flaky
55 · gateAnd the banded gate is not
56 · gateA 50ns delta
57 · gateExactly at the band is not a regression
58 · gate51ns
59 · gateIs
60 · gateAnd is not flaky
61 · gateA faster run has no positive delta
62 · gateAnd is not a regression
63 · gateFour gate runs
64 · gateOne real regression
65 · gateThe no-band build failed three
66 · gateThe banded gate never fails on noise
67 · gateThe no-band build failed on noise twice
68 · extrapolate30 is inside a 10-to-50 fit
69 · extrapolateSo the answer is trustworthy
70 · extrapolateWith no distance outside
71 · extrapolateAnd no extrapolation
72 · extrapolateIn either build
73 · extrapolateThe lower edge is inside
74 · extrapolateThe upper edge is inside
75 · extrapolateOne below the lower edge is not
76 · extrapolateBy one
77 · extrapolate70 is outside the fit
78 · extrapolateBy 20
79 · extrapolateWhich is half the fitted span, not twice it
80 · extrapolate90 is outside the fit
81 · extrapolateBy 40
82 · extrapolateWhich is a hundred percent of the fitted span
83 · extrapolateSo the correct build does not trust it
84 · extrapolateThe unbounded build does
85 · extrapolateWhich is extrapolation
86 · extrapolateAnd the correct build reports none
87 · extrapolateSix queries
88 · extrapolateThree of them outside the fit
89 · extrapolateThe bounded build never extrapolates silently
90 · extrapolateThe unbounded build did on all three
91 · confidenceA 6 percent spread
92 · confidenceFifty samples is enough
93 · confidenceAnd six percent is tight
94 · confidenceSo it is reportable
95 · confidenceWith no single-sample claim
96 · confidenceIn either build
97 · confidenceOne sample is not enough
98 · confidenceSo it is not reportable
99 · confidenceThe single-sample build reports it
100 · confidenceWhich is a single-sample claim
101 · confidenceAnd the correct build makes none
102 · confidenceExactly ten samples is enough
103 · confidenceAnd nine is not
104 · confidenceA 30 percent spread
105 · confidenceWhich is not tight
106 · confidenceSo it is not reportable
107 · confidenceBut it is not a single-sample claim either
108 · confidenceExactly ten percent is tight
109 · confidenceAnd eleven is not
110 · confidenceSeven reports
111 · confidenceFour of them weak — two thin, two loose
112 · confidenceThe correct build never reports from one sample
113 · confidenceThe single-sample build did twice
114 · rooflineThe workload demands 512Gbps
115 · rooflineConcurrency could sustain 65536Gbps
116 · rooflineSo bandwidth is the lower ceiling
117 · rooflineAnd the regime is bandwidth bound
118 · rooflineWith no misclassification
119 · rooflineTwo outstanding sustains 2048Gbps
120 · rooflineWhich is still above the 400Gbps ceiling
121 · rooflineOne outstanding at 2000ns sustains 256Gbps
122 · rooflineWhich is below the bandwidth ceiling
123 · rooflineSo the regime is latency bound
124 · rooflineThe assuming build says bandwidth
125 · rooflineWhich is a misclassification
126 · rooflineAnd the correct build makes none
127 · rooflineOne outstanding at 1280ns sustains exactly 400Gbps
128 · rooflineWhich ties and counts as bandwidth bound
129 · rooflineAnd not latency bound
130 · rooflineThe correct model never misclassifies
131 · rooflineThe assuming build misclassified the latency-bound case
132 · recordAll four things recorded
133 · recordSo the decision is revisitable
134 · recordAnd is not an orphan
135 · recordThe result-only build records nothing
136 · recordSo every one of its decisions is an orphan
137 · recordThe inputs alone unrecorded
138 · recordThe assumptions alone unrecorded
139 · recordThe method alone unrecorded
140 · recordThe valid range alone unrecorded
141 · recordFive decisions
142 · recordFour of them orphaned
143 · recordThe result-only build orphaned all five
144 · recordThe correct build reported four orphans
145 · recordAnd the result-only build five
146 · rankThe largest share is 50 percent
147 · rankWhich is the first term
148 · rankThe second largest is 30
149 · rankWhich is the second term
150 · rankTotalling a hundred percent
151 · rankWith nothing unexplained
152 · rankSo the ranking is complete
153 · rankAnd nothing is unaccounted for
154 · rankThe largest is now 50 again
155 · rankBut it is the third term
156 · rankAnd the second is still 30
157 · rankThe second term
158 · rankThe shares total 75 percent
159 · rankLeaving 25 unexplained
160 · rankSo the ranking is not complete
161 · rankWhich is reported
162 · rankShares totalling 130 percent
163 · rankLeave nothing unexplained
164 · rankAnd the ranking reads as complete
165 · disciplineAll five properties present
166 · disciplineSo the analysis is actionable
167 · disciplineThe ranking alone is missing
168 · disciplineSo the correct analysis is not actionable
169 · disciplineThe number-only build still is
170 · disciplineWhich is a bare number
171 · disciplineAnd the correct analysis is not
172 · disciplineCharacterisation alone, also missed
173 · disciplineThe valid range alone, also missed
174 · disciplineThe record alone, also missed
175 · disciplineConfidence alone, seen by both
176 · disciplineSix assessments
177 · disciplineOne actionable analysis
178 · disciplineThe number-only build called five actionable

18. Mutation Testing

79 mutations, one at a time, each required to make the baseline print RESULT: FAIL.

79 of 79 were killed.

The first run killed 77 and left 2 survivors — the lowest first-run survivor count of the batch, because the lessons of the previous four chapters were applied at authoring time rather than discovered at mutation time.

ClassCount, and the fix
Boundary the arithmetic cannot reach1 · move the threshold
Boundary where two expressions coincide1 · drive a case where they do not

Both are worth stating, because neither is a testbench gap.

"Worthwhile boundary off by one" could not be killed by any stimulus. The gain is 10000 / ov in integer arithmetic, which yields 111 at ov = 90 and 109 at ov = 91 — it never produces exactly 110. A threshold of > 110 and one of >= 110 are therefore identical for every possible input, and no test can distinguish them. The fix was to move the bar to 1.11×, a value the arithmetic does produce and the 10%-share case lands on exactly.

"Overreach inverted" survived because the only outside query had distance equal to span. At a fit of 10–50 queried at 90, the distance is 40 and the span is 40, so distance × 100 / span and span × 100 / distance both give 100. Adding a query at 70 — distance 20 against a span of 40 — distinguishes 50% from 200%.

A representative sample:

MutationResult
The concurrency input is always knownKILLED
Characterisation invertedKILLED
The assuming build stops assumingKILLED
The unfixed share is the fixed shareKILLED
The speedup multiplies the shareKILLED
The overall drops the unfixed partKILLED
The ceiling is the unfixed shareKILLED
The overstatement boundary is off by oneKILLED
The first sensitivity pair takes the smallerKILLED
Never flatKILLED
No lever reported on an empty baseKILLED
The delta is unguardedKILLED
The correct gate drops the noise bandKILLED
The regression boundary is off by oneKILLED
Every regression flakyKILLED
The lower edge boundary is off by oneKILLED
The upper edge boundary is off by oneKILLED
The distance is unguardedKILLED
Overreach invertedKILLED
The sample-count boundary is off by oneKILLED
The tightness boundary is off by oneKILLED
Reportable drops the spread testKILLED
Reportable drops the sample testKILLED
The demand loses the bits-per-byte factorKILLED
A tie counted as latency boundKILLED
Misclassification without the claimKILLED
Revisitability invertedKILLED
The result-only build starts recordingKILLED
The top pair takes the smallerKILLED
The second is the loser of the top pairKILLED
The unexplained share is unguardedKILLED
The number-only build stops being number-onlyKILLED

19. Verification Strategy

Two builds, one stimulus. The parameter is the only difference.

Check that a threshold is reachable before trusting a boundary test. 10000 / ov never equals 110. A threshold placed on an unreachable value makes its own boundary untestable.

Check that a boundary case actually distinguishes the expressions. Distance equal to span makes a ratio and its inverse identical, so the "far outside" query proved nothing about the direction of the division.

Move the answer across every index. The sensitive input to three positions; the largest bottleneck to two.

Drive the case where the shortcut is correct. A fully characterised workload, a fit queried inside its range, a measurement with enough samples and a tight spread. In each, a checker that fired would fire on the good case.

Drive both failure modes of a conjunction separately. Section 11's weak reports are weak for two different reasons, and the two mutations dropping either term are killed by different rows.

Guard every unsigned subtraction and drive past the guard. An improvement in section 9; shares totalling over 100 in section 13.

20. Synthesis and Implementation Reality

None of this is hardware. These are executable specifications for a method, and their value is that the method has boundaries a document does not force you to state.

Section 11's confidence test is deliberately crude. Ten samples and a 10% spread are not a statistical test — they are the two properties whose absence is most common, and a real analysis needs a distribution, a stated hypothesis and an interval. The model is a floor, not a standard.

Section 7's sensitivity ranks inputs independently. Real systems have inputs that only matter together — a large working set matters only at high concurrency — and a one-at-a-time sweep misses interactions entirely. That is a known limitation of the method, not of the model.

Section 10's fitted range assumes the model was fitted at all. Many performance models are constructed from first principles rather than fitted, and their valid range is a judgement rather than a measured interval. The discipline is the same: state it, and refuse outside it.

Section 14's record is process, not code. Nothing enforces it. The model exists to make the four things explicit enough to put on a checklist, because a decision recorded as a number in a slide is section 14's result-only build.

21. Silicon Observability

This chapter's observables are not counters in a device — they are properties of an analysis.

ObservableWhy it matters
Which of the four workload inputs were measured, not assumedsection 5 — the assumption is invisible in the answer
The share of total cost each ranked term representssection 13 — an unexplained remainder can outrank the second term
The range the model was fitted or validated oversection 10 — nothing refuses to answer outside it
Sample count and spread on every reported numbersection 11 — both are needed and neither is sufficient
The binding regime, bandwidth or latencysection 12 — it selects which chapter applies
The measurement noise band the gate usessection 9 — a gate without one fails on noise

The first row is the one that decays fastest. A number that was correct when measured becomes wrong when an input changes, and without a record of which inputs were assumed, nobody can tell whether a given change invalidates it.

22. Debug Lab

Symptom: a performance analysis produced a decision that turned out wrong.

Check which inputs were measured and which were assumed. Section 5: an assumed concurrency figure produces a bandwidth number that is right only if the assumption was.

Check whether the ranking summed to 100%. Section 13: a 25% unexplained remainder may have been larger than the term that was optimised.

Check the share the fix addressed against the gain it claimed. Section 6: a fix on 10% of the cost cannot deliver more than 1.11× whatever its speedup.

Check whether the model was used inside its fitted range. Section 10: nothing refuses to answer outside it, and the answer looks the same.

Check the sample count. Section 11: one sample is not a measurement, and a 30% spread across fifty samples is not a result either.

Check the regime. Section 12: work on a bandwidth ceiling when the workload is latency bound is work on a ceiling that is not binding.

23. Design Review

Which of the workload's inputs were measured, and which were assumed?

Do your ranked shares sum to a hundred? If not, what is the remainder and could it be bigger than the second term?

What share of the cost does the proposed fix address, and what is its ceiling?

Over what range was the model validated, and is the question inside it?

How many samples, and what spread?

Is the workload bandwidth bound or latency bound at the operating point in question?

Where is the basis of this decision written down? If the answer is a number in a slide, it is section 14's result-only build.

24. How This Appears In Real Engineering

Analysis failures do not present as wrong numbers. They present as correct numbers that led somewhere wrong, and the number is usually defensible in isolation.

The characteristic case is an optimisation that shipped and did not help. Section 6: the fix was real, the speedup was real, and the share it addressed was 8% — so the ceiling was 1.09× and the measured end-to-end improvement was inside the noise.

The second is a benchmark result extrapolated. Section 10: a model validated between 10 and 50 answering a question at 90, confidently, with no flag.

The third is a CI gate everybody ignores. Section 9: no noise band, a failure rate dominated by noise, and a culture of re-running until green — at which point the gate catches nothing.

The fourth is a decision nobody can revisit. Section 14: the inputs changed, the number is still on the slide, and no record exists of what it assumed.

25. Common Misconceptions

"The model gave us a number." From which inputs? Section 5's assuming build produces a number from any subset and marks none of them.

"We got a 3x speedup on the memory path." On what share? At a 20% share that is a 1.19× overall gain, and the ceiling is 1.25×.

"We swept the parameters and nothing mattered." Then the input that matters was not in the sweep. Section 7 calls that no lever rather than an insensitive system.

"The gate is too noisy so we re-run it." A gate without a noise band fails on noise by construction. Section 9's no-band build failed three of four runs and two were noise.

"The model extrapolates well." Nothing about a model refuses to answer outside its range. It returns a number with the same confidence it returns any other.

"We measured it." How many times? Section 11's single-sample build reports anything it is handed, and a 30% spread is not a measurement either.

"We know where the time goes — it is 40% here and 20% there." That is 60%. The other 40% is a term nobody named and it is larger than the second one.

"The result is in the deck." Then the inputs, the assumptions, the method and the range are not, and the decision cannot be revisited when any of them changes.

26. Interview Reasoning

Q1. Somebody hands you a performance model's output. What do you ask first? Which inputs were measured and which were assumed. A model fills its gaps and the answer carries no mark saying which.

Q2. A fix gives a 2x speedup on half the workload. What is the overall gain? 1.33×. And no fix on that half can ever beat 2.00×, which is worth knowing before the work starts.

Q3. A fix addresses 5 percent of the cost. Is it worth building? Its ceiling is 1.05×. Whether that is worth building is a business question, but it is bounded and the bound is one division.

Q4. You sweep every parameter and the answer does not move. What have you learned? That the input which matters is not in your sweep. That is a stronger conclusion than "the system is insensitive" and it points somewhere.

Q5. Your CI performance gate fails 60 percent of runs. What is wrong? Most likely no noise band. A gate that fails inside the measurement noise fails on noise, and a gate people re-run is a gate that catches nothing.

Q6. How wide should the noise band be? Wide enough that the false-failure rate is acceptable and narrow enough to catch the smallest regression you care about. Both need measuring; neither is a default.

Q7. A model fitted from 10 to 50 is asked about 90. What happens? It returns a number, confidently. Nothing about a fitted model refuses, which is why the range has to be carried alongside it and checked.

Q8. What is a 100 percent overreach? A query as far outside the fitted range as the range is wide. At a fit of 10 to 50, that is 90.

Q9. How many samples do you need? More than one, and enough that the spread is meaningful. Section 11 uses ten and 10% as a floor, not a standard — the real answer needs a distribution and a stated test.

Q10. Fifty samples with a 30 percent spread — is that a result? No. Enough samples and a tight enough spread are both necessary and neither is sufficient.

Q11. How do you decide whether to work on latency or bandwidth? Compare the bandwidth ceiling against what your concurrency sustains at your latency. Whichever is lower is binding, and that selects which chapter applies.

Q12. Your bottleneck shares are 40, 20 and 15. What do you do? Find the missing 25 before optimising anything. It is larger than the second-ranked term and nobody has named it.

Q13. The shares total 130 percent. What does that mean? Double counting — two terms are measuring overlapping work. Nothing is unexplained and the ranking is still wrong.

Q14. What must a performance decision record? The inputs, the assumptions, the method and the valid range. Without all four it cannot be revisited when any input changes, and inputs change.

Q15. Which of the five properties in section 15 is about the measurement? Only confidence. The other four are about the analysis surrounding it, which is why a correct measurement can still fail the chart.

Q16. Your threshold sits at a value the arithmetic never produces. Why does that matter? Because the boundary is then untestable — the comparisons on either side of it are identical for every possible input, and a bug that moves it cannot be detected.

27. Exercises

1. Extend RTL 1 with a confidence level per input — measured, estimated or assumed. How does characterised change, and what should a model do with an estimate?

2. RTL 2 assumes the fix has no cost. Add a build cost in engineer-weeks and derive the share below which no speedup justifies the work.

3. In RTL 3, make two inputs interact — a delta that appears only when both are varied. Does the one-at-a-time ranking still find it?

4. RTL 4 uses a fixed noise band. Derive it from a rolling spread of recent runs and find the window length at which the gate stops responding to real regressions.

5. In RTL 5, model a fit whose confidence decays with distance rather than stopping at the edge. What replaces in_range?

6. RTL 6 uses a fixed sample floor. Make it depend on the spread — more samples needed when the spread is wide — and find the spread at which the required count exceeds a practical budget.

7. Compose RTL 7 with 18.1 section 9's utilisation-dependent latency. At what utilisation does a bandwidth-bound workload become latency bound?

8. Add a sixth property to RTL 10 for reproducibility — can somebody else obtain the same number? Where does it belong in the mask, and is it implied by the other five?

28. Summary

Four chapters of models are useless without a method, and this chapter builds the method.

A model assumes what it is not told. Five attempts, four with a missing input, and the assuming build produced an answer for every one.

A fix is bounded by its share. 2× on half is 1.33×; 100× on a twentieth is 1.05×, and the ceiling is one division away.

Only one input usually moves the answer — and when none of them does, the model is incomplete rather than the system insensitive.

A gate needs a noise band. Three failures in four without one, two of them noise.

A model is valid where it was fitted. Both edges inside, and nothing refuses to answer at 100% overreach.

A number needs a sample count and a spread, and both are necessary while neither is sufficient.

The regime selects the chapter. Bandwidth bound at 64 outstanding; latency bound at one.

A ranking must sum to a hundred. 40/20/15 leaves 25% nobody named, potentially larger than the term being optimised.

And a decision must record its basis, or it cannot be revisited when the inputs change — which they will.

Module 19 — CXL Security takes a fabric that performs and asks the question every chapter so far has assumed away: whether the device on the other end is the device it claims to be.

Continue learning

Standards & specifications

Governing standard
CXL Specification (CXL Consortium)(opens CXL Consortium in a new tab)

Defines CXL.io, CXL.cache and CXL.mem, and the coherence and memory-pooling behaviour built on them. System design and deployment topology are not mandated.

This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.

Where this fits

Part of the CXL curriculum.