LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_mva_cache_analyzer.m
1function [QN,UN,RN,TN,CN,XN,lGN,runtime,iter,method,hitproblist,itemprob] = solver_mva_cache_analyzer(sn, options)
2% [Q,U,R,T,C,X,LG,RUNTIME,ITER,METHOD,HITPROBLIST] = SOLVER_MVA_CACHE_ANALYZER(QN, OPTIONS)
3
4% Copyright (c) 2012-2026, Imperial College London
5% All rights reserved.
6
7T0=tic;
8QN = []; UN = [];
9RN = []; TN = [];
10CN = [];
11XN = zeros(1,sn.nclasses);
12lGN = NaN;
13iter = NaN;
14
15line_debug('MVA cache analyzer starting: method=%s, nclasses=%d', options.method, sn.nclasses);
16
17source_ist = sn.nodeToStation(sn.nodetype == NodeType.Source);
18sourceRate = sn.rates(source_ist,:);
19sourceRate(isnan(sourceRate)) = 0;
20TN(source_ist,:) = sourceRate;
21
22ch = sn.nodeparam{sn.nodetype == NodeType.Cache};
23
24m = ch.itemcap;
25n = ch.nitems;
26h = length(m);
27u = sn.nclasses;
28lambda = zeros(u,n,h);
29
30for v=1:u
31 for k=1:n
32 for l=1:(h+1)
33 if ~isnan(ch.pread{v})
34 lambda(v,k,l) = sourceRate(v) * ch.pread{v}(k);
35 end
36 end
37 end
38end
39
40Rcost = ch.accost;
41if isempty(Rcost)
42 % Default linear cache routing: items flow from list l to list l+1
43 Rcost = cell(u, n);
44 for v = 1:u
45 for k = 1:n
46 Rmat = diag(ones(1, h), 1);
47 Rmat(h+1, h+1) = 1;
48 Rcost{v, k} = Rmat;
49 end
50 end
51end
52
53gamma = cache_gamma_lp(lambda,Rcost);
54
55% per-list (per-level) hit probabilities are reported only from the exact
56% algorithm, where the miss column and the per-list columns of pij share one
57% consistent solution (so the per-list rows sum to the aggregate hit). For
58% the approximate algorithms the per-list breakdown is left undefined (NaN).
59pijlist = []; % genuine per-list occupancy (n x h), set in the exact branch
60switch options.method
61 case 'exact'
62 line_debug('Using exact cache method');
63 switch sn.nodeparam{sn.nodetype == NodeType.Cache}.replacestrat
64 case {ReplacementStrategy.RR, ReplacementStrategy.FIFO}
65 line_debug('Replacement strategy: RR/FIFO, calling cache_mva');
66 [~,~,pij] = cache_mva(gamma, m);
67 pij = [abs(1-sum(pij,2)),pij];
68 pijlist = pij(:, 2:end);
69 otherwise
70 line_error(mfilename,'MVA does not support exact solution of the specified cache replacement policy.')
71 end
72 otherwise
73 line_debug('Default method: using approximate cache method\n');
74 line_debug('Using approximate cache method');
75 switch sn.nodeparam{sn.nodetype == NodeType.Cache}.replacestrat
76 case {ReplacementStrategy.RR, ReplacementStrategy.FIFO}
77 line_debug('Replacement strategy: RR/FIFO, calling cache_prob_fpi');
78 pij = cache_prob_fpi(gamma,m); % FPI method
79 case ReplacementStrategy.LRU
80 % Marked (MMAP) source: items are driven by per-mark MAPs, so
81 % the request sequence is not IRM; use the LRU(m)-MAP TTL
82 % approximation (Gast-Van Houdt, PEVA 2017). For a plain MAP
83 % source with i.i.d. popularity marks the sequence is IRM and
84 % cache_ttl_lrua is already sequence-exact.
85 markedreaders = isfield(sn,'markidx') && ~isempty(sn.markidx) ...
86 && any(sn.markidx(source_ist,:) > 0);
87 if markedreaders
88 Dcell = sn.proc{source_ist}{find(sn.markidx(source_ist,:)>0,1)};
89 D0 = Dcell{1}; D1agg = Dcell{2};
90 D0c = cell(1,n); D1c = cell(1,n);
91 allmarked = true;
92 for k=1:n
93 D1c{k} = zeros(size(D0));
94 for v=1:u
95 if ~isnan(ch.pread{v})
96 if sn.markidx(source_ist,v) > 0
97 D1c{k} = D1c{k} + Dcell{2+sn.markidx(source_ist,v)} * ch.pread{v}(k);
98 elseif sourceRate(v) > 0 && any(ch.pread{v} > 0)
99 allmarked = false; % unmarked reader mixed in
100 end
101 end
102 end
103 D0c{k} = D0 + D1agg - D1c{k};
104 end
105 if allmarked
106 line_debug('Replacement strategy: LRU with marked MAP source, calling cache_ttl_lrum_map');
107 pij = cache_ttl_lrum_map(D0c, D1c, m);
108 else
109 line_debug('Replacement strategy: LRU, calling cache_ttl_lrua');
110 pij = cache_ttl_lrua(lambda, Rcost, m); % allows trees and access costs
111 end
112 else
113 line_debug('Replacement strategy: LRU, calling cache_ttl_lrua');
114 pij = cache_ttl_lrua(lambda, Rcost, m); % allows trees and access costs
115 end
116 case ReplacementStrategy.HLRU
117 % h-LRU / LRU(m) characteristic-time approximation (linear
118 % list topology; access-cost graphs are not supported)
119 line_debug('Replacement strategy: HLRU, calling cache_ttl_hlru');
120 pij = cache_ttl_hlru(lambda, m);
121 otherwise
122 line_error(mfilename,'MVA does not support approximate solution of the specified cache replacement policy.')
123 end
124end
125missRate = zeros(1,u);
126for v=1:u
127 missRate(v) = lambda(v,:,1)*pij(:,1);
128end
129
130% per-list (per-level) hit probabilities (access-weighted), only where the
131% exact algorithm produced a genuine per-list occupancy matrix.
132hitproblist = NaN(u, h);
133if ~isempty(pijlist)
134 for v=1:u
135 if any(~isnan(ch.pread{v}))
136 pread = ch.pread{v}(:).';
137 for l=1:h
138 hitproblist(v,l) = pread * pijlist(:,l);
139 end
140 end
141 end
142end
143
144% per-item occupancy [nitems x (lists+1)] (col 1 = miss, cols 2..end per-list).
145% This requires a genuine per-list distribution (rows summing to 1):
146% - exact algorithm: pij is already genuine;
147% - approximate LRU (cache_ttl_lrua): pij is a genuine per-list distribution;
148% - approximate RR/FIFO: the FPI algorithm (cache_prob_fpi) replicates the
149% aggregate hit across list columns, so it is NOT a genuine per-list
150% breakdown; derive it from the exact product-form algorithm cache_mva instead
151% (the FPI pij is still used above for the aggregate miss rate).
152% The exact RR/FIFO recursion (cache_mva) is only tractable for small item
153% sets, so it is skipped (NaN, with a warning) for caches with more than 10
154% items.
155itemprob = [];
156if ~isempty(pijlist)
157 itemprob = pij; % exact branch: already [n x (h+1)] with col 1 = miss
158elseif size(pij,2) == h+1
159 switch sn.nodeparam{sn.nodetype == NodeType.Cache}.replacestrat
160 case {ReplacementStrategy.RR, ReplacementStrategy.FIFO}
161 if n > 10
162 line_warning(mfilename, 'Per-item cache occupancy (getAvgItemTable) requires the exact algorithm for RR/FIFO and is skipped for caches with more than 10 items (%d items); reporting NaN.', n);
163 itemprob = NaN(n, h+1);
164 else
165 [~,~,pij_ex] = cache_mva(gamma, m);
166 itemprob = [abs(1-sum(pij_ex,2)), pij_ex];
167 end
168 otherwise
169 itemprob = pij; % LRU-TTL: genuine per-list distribution
170 end
171end
172
173for r = 1:sn.nclasses
174 if length(ch.hitclass)>=r && ch.missclass(r)>0 && ch.hitclass(r)>0
175 XN(ch.missclass(r)) = XN(ch.missclass(r)) + missRate(r);
176 XN(ch.hitclass(r)) = XN(ch.hitclass(r)) + (sourceRate(r) - missRate(r));
177 end
178end
179
180% Set the actual method used
181if strcmp(options.method, 'exact')
182 method = 'exact';
183else
184 switch sn.nodeparam{sn.nodetype == NodeType.Cache}.replacestrat
185 case {ReplacementStrategy.RR, ReplacementStrategy.FIFO}
186 method = 'fpi';
187 case ReplacementStrategy.LRU
188 method = 'ttl';
189 otherwise
190 method = options.method;
191 end
192end
193
194runtime=toc(T0);
195end
Definition Station.m:245