1function [QN,UN,RN,TN,CN,XN,lG,hitprob,missprob,delayedprob,hitproblist,itemprob,latency,runtime,method] = solver_mva_retrieval_analyzer(sn, options)
2% [Q,U,R,T,C,X,LG,HITPROB,MISSPROB,DELAYEDPROB,HITPROBLIST,LATENCY,RUNTIME,METHOD] = SOLVER_MVA_RETRIEVAL_ANALYZER(SN, OPTIONS)
4% Fixed-point approximation of a delayed-hit (retrieval-system) cache via the FPI
5% kernels: retrieval_fpi (hit / miss / delayed-hit ratios) and
6% retrieval_fpi_latency (expected latency Z, eq:latency tot).
8% Copyright (c) 2012-2026, Imperial College London
13XN = zeros(1, sn.nclasses);
14QN = zeros(sn.nstations, sn.nclasses);
15UN = zeros(sn.nstations, sn.nclasses);
16RN = zeros(sn.nstations, sn.nclasses);
17TN = zeros(sn.nstations, sn.nclasses);
21line_debug(
'MVA retrieval analyzer starting: nclasses=%d', sn.nclasses);
23[m, lambda, gamma, eta, alpha, T, R, station_type] = cache_retrieval_inputs(sn);
26% --- FPI hit / miss / delayed-hit ratios ---
27[pmiss, phit, pdh] = retrieval_fpi(m, lambda, eta, gamma);
28pi0 = pmiss(:).
'; % per-item miss
29pih = sum(phit, 1); % per-item hit
30phid = sum(pdh, 1); % per-item delayed
32% --- FPI expected latency Z (eq:latency tot) ---
33Z = retrieval_fpi_latency(m, lambda, gamma, alpha, T, R, station_type);
35% --- read class and per-class aggregates (single read class) ---
36ci = find(sn.nodetype == NodeType.Cache);
38rk = keys(ch.retrievalSystemQueueIndices);
39jobinClass = double(rk{1}) + 1;
40w = lambda(:) / sum(lambda);
41hitAgg = sum(w .* pih(:));
42missAgg = sum(w .* pi0(:));
43delayedAgg = sum(w .* phid(:));
45% --- source throughput ---
46source_ist = sn.nodeToStation(sn.nodetype == NodeType.Source);
47sourceRate = sn.rates(source_ist, :);
48sourceRate(isnan(sourceRate)) = 0;
49TN(source_ist, :) = sourceRate;
51% --- cache results (hitprob is the TRUE hit fraction; delayedprob the
52% delayed-hit fraction; true hit + delayed + miss = 1) ---
53hitprob = NaN(1, sn.nclasses);
54missprob = NaN(1, sn.nclasses);
55delayedprob = NaN(1, sn.nclasses);
56latency = NaN(1, sn.nclasses);
57hitprob(jobinClass) = hitAgg;
58missprob(jobinClass) = missAgg;
59delayedprob(jobinClass) = delayedAgg;
60latency(jobinClass) = Z;
62% per-list (per-level) hit fractions for the read class: phit is (h x n);
63% access-weighted over items gives the per-list hit probability (rows sum to
65hitproblist = NaN(sn.nclasses, numel(m));
66hitproblist(jobinClass, :) = (phit * w(:)).';
68% per-item occupancy [nitems x (lists+1)]: column 1 = miss (item not cached),
69% columns 2..end = probability the item resides in each list.
70itemprob = [pi0(:), phit.
'];
72hc = ch.hitclass(jobinClass);
73mc = ch.missclass(jobinClass);
74if hc > 0, XN(hc) = sourceRate(jobinClass) * (hitAgg + delayedAgg); end
75if mc > 0, XN(mc) = sourceRate(jobinClass) * missAgg; end
77% --- retrieval-station mean occupancy (QLen) and throughput ---
78queueNodes = double(ch.retrievalSystemQueueIndices(rk{1}));
80psIdx = find(station_type == "PS" | station_type == "SIRO" | station_type == "FCFS" | station_type == "LCFSPR"); % SIRO/FCFS/LCFSPR as PS
82 sst = sn.nodeToStation(queueNodes(s));
83 if station_type(s) == "PS" || station_type(s) == "SIRO" || station_type(s) == "FCFS" || station_type(s) == "LCFSPR"
84 prow = 1 + find(psIdx == s);
89 if prow <= size(pdh, 1)
90 phi_s = sum(pdh(prow, :));
96 Pmat = Ri(2:S+1, 2:S+1);
97 vis = a / (eye(S) - Pmat);
98 tput_s = tput_s + sourceRate(jobinClass) * (lambda(i)/sum(lambda)) * pi0(i) * vis(s);
100 QN(sst, jobinClass) = phi_s;
101 UN(sst, jobinClass) = phi_s;
102 TN(sst, jobinClass) = tput_s;
104 RN(sst, jobinClass) = phi_s / tput_s;