1function [CacheAvgTable] = getAvgCacheTable(self)
2% [CACHEAVGTABLE] = GETAVGCACHETABLE(SELF)
3% Return a table of detailed per-
class performance metrics for every Cache
4% node in
the model. For each cache node and read (input)
class there
is a
5% total row (List=0) and, where
the solver reports per-list (per-level) hit
6% probabilities and
the cache has more than one list, one extra row per list.
10% JobClass read (input) class name
11% List 0 = total over all lists; l = cache list (level) l
12% ListCap capacity of
the list (total capacity on
the total row)
13% Items number of items managed by
the cache
14% HitProb (true) hit probability; per list on list rows
15% DelayedHitProb delayed-hit probability (retrieval system; total row only)
16% MissProb miss probability (total row only)
17% HitRate hit throughput = ArvR * HitProb
18% DelayedHitRate delayed-hit throughput = ArvR * DelayedHitProb
19% MissRate miss throughput = ArvR * MissProb
20% ArvR read-class arrival rate into
the cache
21% ResidT expected retrieval latency / residence time (NaN if not computed)
23% The hit class throughput reported by getAvgNodeTable aggregates true hits
24% and delayed hits; this table separates them.
26% Copyright (c) 2012-2026, Imperial College London
29if GlobalConstants.DummyMode
30 CacheAvgTable = IndexedTable(Table());
34sn = self.model.getStruct;
37caches = find(sn.nodetype == NodeType.Cache)';
39 CacheAvgTable = IndexedTable(Table());
43% Node throughputs. The cache read-class arrival equals that class's source
44% throughput (every read request enters
the cache); robust across
solvers,
45% including simulators where delayed hits are not folded into hit/miss tput.
46[~,~,~,TNn] = self.getAvgNode();
47srcNode = find(sn.nodetype == NodeType.Source, 1);
51[Listv, ListCapv, Itemsv, HitPv, DHitPv, MissPv, HitRv, DHitRv, MissRv, ArvRv, Latv] = deal([]);
54 np = sn.nodeparam{ind};
55 hitclass = np.hitclass;
57 if isfield(np,
'nitems'), nitems = np.nitems; end
59 if isfield(np,
'itemcap'), itemcap = np.itemcap(:).
'; end
61 totcap = sum(itemcap);
62 node = self.model.nodes{ind};
63 hitp = node.getHitRatio();
64 missp = node.getMissRatio();
65 dhitp = node.getDelayedHitRatio();
66 hitplist = node.getHitRatioByList();
67 lat = node.getResidT();
69 % read (input) classes are those with a defined hit class
70 if r > length(hitclass) || hitclass(r) <= 0
73 ph = nanGetAt(hitp, r);
74 pm = nanGetAt(missp, r);
75 pd = nanGetAt(dhitp, r);
76 if isnan(ph) && isnan(pm) && isnan(pd)
77 continue % no solved cache metrics for this class
79 if isnan(ph), ph = 0; end
80 if isnan(pm), pm = 0; end
81 if isnan(pd), pd = 0; end
83 if ~isempty(TNn) && ~isempty(srcNode) && srcNode <= size(TNn,1) && r <= size(TNn,2)
84 arvr = TNn(srcNode, r);
86 latr = nanGetAt(lat, r);
88 % --- total row (List = 0) ---
89 % ArvR is the retrieval-system throughput arvr*(missprob+delayedprob) =
90 % MissRate + DelayedHitRate, i.e. the rate of requests that enter the
91 % retrieval system (a miss or a delayed hit). This is the arrival rate that
92 % is Little-consistent with ResidT = Z (the delayed-hit expected latency,
93 % eq:latency tot / retrieval_fpi_latency): ArvR*ResidT = sum_i(phi_i+d_i),
94 % the mean number of requests in the retrieval system (fetch job included).
95 arvr_retr = arvr*(pm+pd);
96 [Node, JobClass, Listv, ListCapv, Itemsv, HitPv, DHitPv, MissPv, ...
97 HitRv, DHitRv, MissRv, ArvRv, Latv] = addrow( ...
98 Node, JobClass, Listv, ListCapv, Itemsv, HitPv, DHitPv, MissPv, ...
99 HitRv, DHitRv, MissRv, ArvRv, Latv, ...
100 sn.nodenames{ind}, sn.classnames{r}, 0, totcap, nitems, ...
101 ph, pd, pm, arvr*ph, arvr*pd, arvr*pm, arvr_retr, latr);
103 % --- per-list rows (only if a multi-list breakdown is available) ---
104 if h > 1 && ~isempty(hitplist) && r <= size(hitplist,1) && ~all(isnan(hitplist(r,:)))
106 phl = full(hitplist(r,l));
107 if isnan(phl), phl = 0; end
108 capl = NaN; if l <= numel(itemcap), capl = itemcap(l); end
109 [Node, JobClass, Listv, ListCapv, Itemsv, HitPv, DHitPv, MissPv, ...
110 HitRv, DHitRv, MissRv, ArvRv, Latv] = addrow( ...
111 Node, JobClass, Listv, ListCapv, Itemsv, HitPv, DHitPv, MissPv, ...
112 HitRv, DHitRv, MissRv, ArvRv, Latv, ...
113 sn.nodenames{ind}, sn.classnames{r}, l, capl, nitems, ...
114 phl, NaN, NaN, arvr*phl, NaN, NaN, arvr, NaN);
121JobClass = label(JobClass);
126DelayedHitProb = DHitPv;
129DelayedHitRate = DHitRv;
133CacheAvgTable = Table(Node, JobClass, List, ListCap, Items, HitProb, ...
134 DelayedHitProb, MissProb, HitRate, DelayedHitRate, MissRate, ArvR, ResidT);
135CacheAvgTable = IndexedTable(CacheAvgTable);
138function [Node, JobClass, Listv, ListCapv, Itemsv, HitPv, DHitPv, MissPv, ...
139 HitRv, DHitRv, MissRv, ArvRv, Latv] = addrow( ...
140 Node, JobClass, Listv, ListCapv, Itemsv, HitPv, DHitPv, MissPv, ...
141 HitRv, DHitRv, MissRv, ArvRv, Latv, ...
142 nodename, classname, listidx, listcap, nitems, ...
143 ph, pd, pm, hr, dhr, mr, arvr, lat)
144Node{end+1,1} = nodename;
145JobClass{end+1,1} = classname;
146Listv(end+1,1) = listidx;
147ListCapv(end+1,1) = listcap;
148Itemsv(end+1,1) = nitems;
153DHitRv(end+1,1) = dhr;
155ArvRv(end+1,1) = arvr;
159function v = nanGetAt(vec, r)
160% Safe scalar read; returns NaN if out of range or empty.
161if isempty(vec) || r > numel(vec)