1%{ @file cache_retrieval_inputs.m
2 % @brief Extract delayed-hit retrieval algorithm inputs from a NetworkStruct
4 % @author LINE Development Team
8 % @brief Builds
the inputs of
the retrieval (delayed-hit) analytic algorithms from a model
11 % Given
the NetworkStruct of a cache equipped with a retrieval system
12 % (Cache.setRetrievalSystem), reconstructs
the inputs required by
the
13 % retrieval_* algorithms (retrieval_nc, retrieval_metrics, retrieval_fpi,
14 % retrieval_fpi_latency):
16 % m cache list capacities (1 x h)
17 % lambda per-item arrival rates (1 x n) = sourceRate * pread
18 % gamma access factors gamma_{i,j} (n x h) via cache_gamma_lp
19 % eta fetching demands eta_{s,i} (n x (r+1)) col 1 = IS, cols 2.. = PS
20 % alpha cell(1,S); alpha{s}(1,:,i) PH entry vector of item i at station s
21 % T cell(1,S); T{s}(:,:,i) PH subgenerator of item i at station s
22 % R (S+1) x (S+1) x n routing matrices (index 1 = cache/outside,
23 % 2..S+1 = retrieval stations), R(a,b,i) probability a->b for item i
24 % station_type (1 x S)
string per retrieval station, one of "IS", "PS",
25 % "SIRO", "FCFS", "LCFSPR" (mapped from sn.sched)
27 % The retrieval system
is single-class (IRM): exactly one read class may route
28 % into
the retrieval system. Supported retrieval scheduling policies are IS,
29 % PS, SIRO, FCFS and LCFSPR. IS
is independent; PS, SIRO, FCFS and LCFSPR use
30 %
the mean-field sharing slowdown. PS and LCFSPR (symmetric/insensitive BCMP
31 % disciplines) admit general phase-type service and class-dependent rates;
32 % SIRO and FCFS require exponential service with identical per-class rates.
33 % Any other scheduling policy raises an error, matching retrieval_fpi_latency.
37 % [m,lambda,gamma,eta,alpha,T,R,station_type] = cache_retrieval_inputs(sn)
40function [m,lambda,gamma,eta,alpha,T,R,station_type] = cache_retrieval_inputs(sn, lambdaOverride)
41% [...] = CACHE_RETRIEVAL_INPUTS(SN) builds
the retrieval-algorithm inputs from
42% an OPEN cache model (per-item rate lambda = sourceRate * pread).
44% [...] = CACHE_RETRIEVAL_INPUTS(SN, LAMBDAOVERRIDE) uses
the supplied read-class
45% arrival rate LAMBDAOVERRIDE (a scalar rate for
the single read class) instead of
46%
the Source throughput, so
the same inputs can be built for a CLOSED integrated
47% cache-queueing sublayer where
the read rate comes from
the network solution
48% (da_cacheqn_retrieval). All other inputs (gamma, eta, alpha, T, R) are unchanged.
54ci = find(sn.nodetype == NodeType.Cache);
56 line_error(mfilename, 'Retrieval analysis requires exactly one Cache node.');
59if ~isfield(ch,
'retrievalSystemCapacity') || ch.retrievalSystemCapacity <= 0
60 line_error(mfilename,
'The Cache node has no retrieval system (call setRetrievalSystem).');
68% --- read class (single-class IRM) ---
69rk = keys(ch.retrievalSystemQueueIndices);
71 line_error(mfilename, 'Retrieval analysis supports a single read class.
');
73jobinClass = double(rk{1}) + 1; % stored 0-indexed
74queueNodes = ch.retrievalSystemQueueIndices(rk{1});
75queueNodes = double(queueNodes(:).');
78 line_error(mfilename,
'The retrieval system has no stations.');
81% --- per-item arrival rates lambda(i) = readRate * pread(i) ---
82% readRate
is the Source throughput
for an open model, or
the caller-supplied
83% closed read-
class arrival rate (from
the network solution) when overridden.
84pread = ch.pread{jobinClass};
85if ~isempty(lambdaOverride)
86 readRate = lambdaOverride;
88 source_ist = sn.nodeToStation(sn.nodetype == NodeType.Source);
89 if isempty(source_ist)
90 line_error(mfilename, [
'Retrieval analysis of a closed model requires an explicit read ' ...
91 'rate (call cache_retrieval_inputs(sn, lambdaOverride)); no Source node found.']);
93 readRate = sn.rates(source_ist, jobinClass);
95if isnan(readRate), readRate = 0; end
96lambda = readRate * pread(:).
'; % 1 x n
98% --- gamma via the existing plain-cache utility (n x h) ---
99lambda3d = zeros(1, n, h);
102 lambda3d(1, k, l) = lambda(k);
107 % Default linear cache routing: item flows from list l to list l+1.
110 Rmat = diag(ones(1, h), 1);
115gamma = cache_gamma_lp(lambda3d, Rcost); % n x h
117% --- station types (IS / PS / SIRO / FCFS) ---
118% SIRO and FCFS are treated as PS: for exponential service the tagged-job sojourn
119% is Exp(mu/(1+phitilde)), identical to PS (see retrieval_fpi_latency). The
120% exponential requirement is enforced below once phase sizes are known; FCFS also
121% requires class-independent rates (checked below).
122station_type = strings(1, S);
124 sst = sn.nodeToStation(queueNodes(s));
125 if sn.sched(sst) == SchedStrategy.INF
126 station_type(s) = "IS";
127 elseif sn.sched(sst) == SchedStrategy.PS
128 station_type(s) = "PS";
129 elseif sn.sched(sst) == SchedStrategy.SIRO
130 station_type(s) = "SIRO";
131 elseif sn.sched(sst) == SchedStrategy.FCFS
132 station_type(s) = "FCFS";
133 elseif sn.sched(sst) == SchedStrategy.LCFSPR
134 station_type(s) = "LCFSPR";
136 line_error(mfilename, ['Retrieval analysis supports only IS, PS, SIRO, FCFS and LCFSPR
' ...
137 'retrieval stations; station %d uses an unsupported scheduling policy.
'], queueNodes(s));
141% --- per-item PH service (alpha,T) per station, routing R ---
146 sst = sn.nodeToStation(queueNodes(s));
147 rcls0 = ch.retrievalClasses(1, jobinClass);
148 fsz(s) = size(sn.proc{sst}{rcls0}{1}, 1);
149 if (station_type(s) == "SIRO" || station_type(s) == "FCFS") && fsz(s) > 1
150 line_error(mfilename, ['Retrieval analysis supports SIRO/FCFS retrieval stations only with
' ...
151 'exponential (single-phase) service; station %d has phase-type service.
'], queueNodes(s));
153 alpha{s} = zeros(1, fsz(s), n);
154 T{s} = zeros(fsz(s), fsz(s), n);
156R = zeros(S+1, S+1, n);
157lin = @(node, cls) (node-1)*K + cls; % rtnodes flat index
159 rcls = ch.retrievalClasses(i, jobinClass);
161 sst = sn.nodeToStation(queueNodes(s));
162 alpha{s}(1, :, i) = sn.pie{sst}{rcls}(:).';
163 T{s}(:, :, i) = sn.proc{sst}{rcls}{1};
165 % routing: index 1 = cache (outside), 2..S+1 = retrieval stations
167 R(1, s+1, i) = sn.rtnodes(lin(ci, rcls), lin(queueNodes(s), rcls)); % cache -> queue s
168 R(s+1, 1, i) = sn.rtnodes(lin(queueNodes(s), rcls), lin(ci, rcls)); % queue s -> cache
170 R(s+1, sp+1, i) = sn.rtnodes(lin(queueNodes(s), rcls), lin(queueNodes(sp), rcls));
175% --- eta(i,1) = sum of IS
visits*mean; eta(i,1+p) = PS station p ---
176% SIRO and FCFS reduce to PS only with
class-independent service rates; LCFSPR
177%
is insensitive and exempt.
178for s = find(station_type ==
"FCFS" | station_type ==
"SIRO")
181 taus(i) = -alpha{s}(:, :, i) / T{s}(:, :, i) * ones(fsz(s), 1);
183 if max(taus) - min(taus) > 1e-9 * max(taus)
184 line_error(mfilename, [
'Retrieval analysis requires class-independent (identical) mean ' ...
185 'service rates at SIRO/FCFS station %d.'], queueNodes(s));
189isIdx = find(station_type ==
"IS");
190psIdx = find(station_type ==
"PS" | station_type ==
"SIRO" | station_type ==
"FCFS" | station_type ==
"LCFSPR"); % SIRO/FCFS/LCFSPR as PS
195 a = Ri(1, 2:S+1); % outside -> station entry probs
196 Pmat = Ri(2:S+1, 2:S+1); % station -> station
197 visits = a / (eye(S) - Pmat); % expected
visits per fetch
200 tau(s) = -alpha{s}(:, :, i) / T{s}(:, :, i) * ones(fsz(s), 1);
203 eta(i, 1) = sum(eta_s(isIdx));
205 eta(i, 1+p) = eta_s(psIdx(p));