LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
da_cacheqn.m
1function [res, hitprob, missprob, it, sn, cacheinfo] = da_cacheqn(sn, missfun, netfun, options)
2% [RES,HITPROB,MISSPROB,IT,SN,CACHEINFO] = DA_CACHEQN(SN, MISSFUN, NETFUN, OPTIONS)
3%
4% Shared decomposition-aggregation driver for integrated cache-queueing
5% models. Alternates between (i) the solution of each cache in isolation,
6% given the current per-class arrival rates, and (ii) the solution of the
7% surrounding queueing network with the caches replaced by class switches
8% routing according to the hit/miss probabilities, until the cache arrival
9% rates reach a fixed point (driven by da_fpi with the 1-norm).
10%
11% SN: NetworkStruct; mutated in place (cache nodes relabeled as
12% ClassSwitch, routing and visits refreshed) and returned.
13% MISSFUN: MISSRATE = MISSFUN(GAMMA, M, LAMBDA_CACHE, CH) solves the
14% isolated cache and returns the per-class miss rates
15% (1 x nclasses); CH is the cache node parameter struct
16% (sn.nodeparam), e.g. to select the algorithm by replacement
17% strategy.
18% NETFUN: RES = NETFUN(SN) solves the surrounding queueing network; the
19% returned struct must include the field XN (1 x nclasses system
20% throughputs); all other fields are passed through to the caller.
21% OPTIONS: solver options struct (iter_max, iter_tol).
22%
23% Returns the last NETFUN result RES, the per-cache hit/miss probabilities
24% (length(caches) x nclasses, rows ordered as find(sn.nodetype==Cache)),
25% the iteration count IT, the mutated SN, and CACHEINFO with the converged
26% isolated-cache inputs per cache (fields node, gamma, m, lambda_cache,
27% Rcost, strat) for per-item occupancy reporting.
28%
29% Copyright (c) 2012-2026, Imperial College London
30% All rights reserved.
31
32I = sn.nnodes;
33K = sn.nclasses;
34
35statefulNodes = find(sn.isstateful)';
36statefulNodesClasses = [];
37for ind = statefulNodes
38 statefulNodesClasses(end+1:end+K) = ((ind-1)*K+1):(ind*K);
39end
40caches = find(sn.nodetype == NodeType.Cache);
41ncaches = length(caches);
42
43hitprob = zeros(ncaches, K);
44missprob = zeros(ncaches, K);
45res = struct();
46
47cacheinfo = struct();
48cacheinfo.node = caches;
49cacheinfo.gamma = cell(1, ncaches);
50cacheinfo.m = cell(1, ncaches);
51cacheinfo.lambda_cache = cell(1, ncaches);
52cacheinfo.Rcost = cell(1, ncaches);
53cacheinfo.strat = cell(1, ncaches);
54
55% initialization sweep: seed the cache arrival rates with random values and
56% relabel the caches as class switches
57lambda0 = zeros(1, K);
58for cIdx = 1:ncaches
59 ch = sn.nodeparam{caches(cIdx)};
60 inputClass = find(ch.hitclass);
61 lambda0(inputClass) = rand(1, length(inputClass));
62 sn.nodetype(caches(cIdx)) = NodeType.ClassSwitch;
63end
64
65fpopts = options;
66fpopts.config.da_norm = @(d) norm(d, 1);
67[~, it] = da_fpi(@da_sweep, lambda0, fpopts);
68
69 function [xnew, xref] = da_sweep(x, itnum) %#ok<INUSD>
70 lambda = x;
71 for cIdx = 1:ncaches
72 ind = caches(cIdx);
73 ch = sn.nodeparam{ind};
74 hitClass = ch.hitclass;
75 missClass = ch.missclass;
76 inputClass = find(hitClass);
77
78 % solution of isolated cache
79 [gamma, lambda_cache, Rcost] = da_cache_isolate(ch, lambda);
80 cacheinfo.gamma{cIdx} = gamma;
81 cacheinfo.m{cIdx} = ch.itemcap;
82 cacheinfo.lambda_cache{cIdx} = lambda_cache;
83 cacheinfo.Rcost{cIdx} = Rcost;
84 cacheinfo.strat{cIdx} = ch.replacestrat;
85
86 missrate = missfun(gamma, ch.itemcap, lambda_cache, ch);
87 missrate = reshape(missrate, 1, []); % row, as legacy indexed assignment did
88 missprob(cIdx,:) = missrate ./ lambda; % NaN if no arrivals
89 hitprob(cIdx,:) = 1 - missprob(cIdx,:);
90 hitprob(isnan(hitprob)) = 0;
91 missprob(isnan(missprob)) = 0;
92
93 % bring back the isolated model results into the queueing model
94 for r = inputClass
95 sn.rtnodes((ind-1)*K+r,:) = 0;
96 for jnd = 1:I
97 if sn.connmatrix(ind, jnd)
98 sn.rtnodes((ind-1)*K+r, (jnd-1)*K+hitClass(r)) = hitprob(cIdx, r);
99 sn.rtnodes((ind-1)*K+r, (jnd-1)*K+missClass(r)) = missprob(cIdx, r);
100 end
101 end
102 end
103 sn.rt = dtmc_stochcomp(sn.rtnodes, statefulNodesClasses);
104 end
105 [visits, nodevisits, sn] = sn_refresh_visits(sn, sn.chains, sn.rt, sn.rtnodes);
106 sn.visits = visits;
107 sn.nodevisits = nodevisits;
108
109 % aggregation step: solve the surrounding queueing network
110 res = netfun(sn);
111
112 % update the cache arrival rates from the network solution
113 nv = cellsum(nodevisits);
114 for cIdx = 1:ncaches
115 ind = caches(cIdx);
116 inputClass = find(sn.nodeparam{ind}.hitclass);
117 for r = inputClass
118 c = find(sn.chains(:,r));
119 inchain = find(sn.chains(c,:));
120 if sn.refclass(c) > 0
121 lambda(r) = sum(res.XN(inchain)) * nv(ind,r) / nv(sn.stationToNode(sn.refstat(r)), sn.refclass(c));
122 else
123 lambda(r) = sum(res.XN(inchain)) * nv(ind,r) / nv(sn.stationToNode(sn.refstat(r)), r);
124 end
125 end
126 end
127 xnew = lambda;
128 xref = x;
129 end
130end
Definition fjtag.m:157
Definition Station.m:245