1function [XN,UN,QN,RN,TN,CN,tranSysState,tranSync,sn]=solver_ssa_analyzer_serial(sn, init_state, options, isHashed)
2% [XN,UN,QN,RN,TN,CN]=SOLVER_SSA_ANALYZER_SERIAL(SN, OPTIONS)
4M = sn.nstations; %number of stations
5K = sn.nclasses; %number of
classes
7% istSpaceShift = zeros(1,M);
10% istSpaceShift(i) = 0;
12% istSpaceShift(i) = istSpaceShift(i-1) + size(sn.space{i-1},2);
17NK = sn.njobs
'; % initial population per class
33options.samples = options.samples + 1;
34if isfield(options,'config
') && isfield(options.config,'eventcache
')
35 eventCache = EventCache.create(options.config.eventcache, sn);
37 eventCache = EventCache.create(false, sn);
40[probSysState,StateSpaceAggr,arvRates,depRates,tranSysState,tranSync] = solver_ssa(sn, init_state, options, eventCache);
42wset = 1:size(StateSpaceAggr,1);
44 refsf = sn.stationToStateful(sn.refstat(k));
45 XN(k) = probSysState*depRates(wset,refsf,k);
49 isf = sn.stationToStateful(ist);
51 TN(ist,k) = probSysState*depRates(wset,isf,k);
52 QN(ist,k) = probSysState*StateSpaceAggr(wset,(ist-1)*K+k);
55 case SchedStrategy.INF
57 UN(ist,k) = QN(ist,k);
59 case {SchedStrategy.PS, SchedStrategy.DPS, SchedStrategy.GPS, ...
60 SchedStrategy.PSPRIO, SchedStrategy.DPSPRIO, SchedStrategy.GPSPRIO, SchedStrategy.LPS}
61 if isempty(sn.lldscaling) && isempty(sn.cdscaling) && ~sn_has_joint_dependence(sn)
63 if ~isempty(PH{ist}{k})
64 UN(ist,k) = probSysState*arvRates(wset,isf,k)/sn.rates(ist,k)/S(ist);
67 else % lld/cd/ljd cases
68 ind = sn.stationToNode(ist);
72 % [ni,nir] = State.toMarginal(sn, ind, StateSpace(st,(istSpaceShift(i)+1):(istSpaceShift(i)+size(sn.space{i},2))));
75 % UN(i,k) = UN(i,k) + probSysState(st)*nir(k)*sn.schedparam(i,k)/(nir*sn.schedparam(i,:)');
81 if isempty(sn.lldscaling) && isempty(sn.cdscaling) && ~sn_has_joint_dependence(sn)
83 if ~isempty(PH{ist}{k})
84 UN(ist,k) = probSysState*arvRates(wset,isf,k)*map_mean(PH{ist}{k})/S(ist);
87 else % lld/cd/ljd cases
88 ind = sn.stationToNode(ist);
92 % [ni,~,sir] = State.toMarginal(sn, ind, StateSpace(st,(istSpaceShift(i)+1):(istSpaceShift(i)+size(sn.space{i},2))));
95 % UN(i,k) = UN(i,k) + probSysState(st)*sir(k)/S(i);
106 RN(ist,k) = QN(ist,k)./TN(ist,k);
111 CN(k) = NK(k)./XN(k);
115% now update the routing probabilities in
nodes with state-dependent routing
116TNcache = zeros(sn.nstateful, K);
117XNcache = zeros(sn.nstateful, K);
119 for isf=1:sn.nstateful
120 if sn.nodetype(isf) == NodeType.Cache
121 TNcache(isf,k) = probSysState*depRates(:,isf,k);
122 XNcache(isf,k) = probSysState*arvRates(:,isf,k);
127% updates cache actual hit and miss data + retrieval-system expected latency.
128% For retrieval-aware caches, the per-
class hit/miss accounting reads
129% TNcache
for the configured hitClass / missClass (departures of those
130%
classes downstream of the cache). The retrieval-complete arrival fires
131% the actual miss
event in afterEventCache, so the miss-
class departure
132% rate captured by TNcache
is the
true miss rate.
133retrievalLatencyWarned =
false;
135 for isf=1:sn.nstateful
136 if sn.nodetype(isf) == NodeType.Cache
137 ind = sn.statefulToNode(isf);
138 np = sn.nodeparam{ind};
139 if length(np.hitclass)>=k
143 sn.nodeparam{ind}.actualhitprob(k) = TNcache(isf,h)/sum(TNcache(isf,[h,m]));
144 sn.nodeparam{ind}.actualmissprob(k) = TNcache(isf,m)/sum(TNcache(isf,[h,m]));
146 sn.nodeparam{ind}.actualhitprob(k) = NaN;
147 sn.nodeparam{ind}.actualmissprob(k) = NaN;
150 % The Eq. 8 retrieval-system expected latency
is not currently
151 % implemented; report NaN whenever a retrieval system
is
152 % configured
for this class.
153 expectedLatency = NaN;
154 if isfield(np,
'retrievalSystemQueueIndices') ...
155 && isKey(np.retrievalSystemQueueIndices, int32(k-1)) ...
156 && ~isempty(np.retrievalSystemQueueIndices(int32(k-1)))
157 if ~retrievalLatencyWarned
158 line_warning(mfilename, 'Retrieval-system expected latency
is not currently implemented; reporting NaN.');
159 retrievalLatencyWarned = true;
162 sn.nodeparam{ind}.actualresidt(k) = expectedLatency;