LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_ssa_analyzer_serial.m
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)
3
4M = sn.nstations; %number of stations
5K = sn.nclasses; %number of classes
6
7% istSpaceShift = zeros(1,M);
8% for i=1:M
9% if i==1
10% istSpaceShift(i) = 0;
11% else
12% istSpaceShift(i) = istSpaceShift(i-1) + size(sn.space{i-1},2);
13% end
14% end
15
16S = sn.nservers;
17NK = sn.njobs'; % initial population per class
18sched = sn.sched;
19Tstart = tic;
20
21PH = sn.proc;
22tranSysState = [];
23tranSync = [];
24
25XN = NaN*zeros(1,K);
26UN = NaN*zeros(M,K);
27QN = NaN*zeros(M,K);
28RN = NaN*zeros(M,K);
29TN = NaN*zeros(M,K);
30CN = NaN*zeros(1,K);
31
32
33if isfield(options,'config') && isfield(options.config,'eventcache')
34 eventCache = EventCache.create(options.config.eventcache, sn);
35else
36 eventCache = EventCache.create(false, sn);
37end
38
39% see _kb/06-solver-catalog.md for rationale (SSA utilization estimator)
40userCap = sn.cap;
41userClasscap = sn.classcap;
42[probSysState,StateSpaceAggr,arvRates,depRates,tranSysState,tranSync] = solver_ssa(sn, init_state, options, eventCache);
43%%
44wset = 1:size(StateSpaceAggr,1);
45for k=1:K
46 refsf = sn.stationToStateful(sn.refstat(k));
47 XN(k) = probSysState*depRates(wset,refsf,k);
48end
49
50for ist=1:M
51 isf = sn.stationToStateful(ist);
52 for k=1:K
53 TN(ist,k) = probSysState*depRates(wset,isf,k);
54 QN(ist,k) = probSysState*StateSpaceAggr(wset,(ist-1)*K+k);
55 end
56 % see _kb/06-solver-catalog.md for rationale (SSA utilization estimator)
57 canDropClass = isinf(sn.njobs(:)') & (isfinite(userCap(ist)) | isfinite(userClasscap(ist,:)));
58 switch sched(ist)
59 case SchedStrategy.INF
60 for k=1:K
61 UN(ist,k) = QN(ist,k);
62 end
63 case {SchedStrategy.PS, SchedStrategy.DPS, SchedStrategy.GPS, ...
64 SchedStrategy.PSPRIO, SchedStrategy.DPSPRIO, SchedStrategy.GPSPRIO, SchedStrategy.LPS}
65 if isempty(sn.lldscaling) && isempty(sn.cdscaling) && isempty(sn.jdscaling)
66 for k=1:K
67 if ~isempty(PH{ist}{k})
68 if canDropClass(k)
69 UN(ist,k) = TN(ist,k)/sn.rates(ist,k)/S(ist);
70 else
71 UN(ist,k) = probSysState*arvRates(wset,isf,k)/sn.rates(ist,k)/S(ist);
72 end
73 end
74 end
75 else % lld/cd/ljd cases
76 ind = sn.stationToNode(ist);
77 % see _kb/06-solver-catalog.md for rationale (SSA utilization estimator)
78 isCd = ~isempty(sn.cdscaling) && ist <= numel(sn.cdscaling) && ~isempty(sn.cdscaling{ist});
79 isJd = ~isempty(sn.jdscaling) && ist <= numel(sn.jdscaling) && ~isempty(sn.jdscaling{ist});
80 ceff = S(ist);
81 if ~isempty(sn.lldscaling) && ist <= size(sn.lldscaling,1)
82 ceff = max(ceff, max(sn.lldscaling(ist,:)));
83 end
84 for k=1:K
85 if ~isempty(PH{ist}{k})
86 if isCd || isJd
87 % effective peak = product of declared cd and jd peaks
88 cdiv = 1;
89 if isCd, cdiv = cdiv * sn.cdscalingpeak(ist,k); end
90 if isJd, cdiv = cdiv * sn.jdscalingpeak(ist,k); end
91 else
92 cdiv = ceff;
93 end
94 if cdiv > 0
95 UN(ist,k) = TN(ist,k)*map_mean(PH{ist}{k})/cdiv;
96 else
97 UN(ist,k) = 0;
98 end
99 end
100 end
101 % UN(i,1:K) = 0;
102 % for st = wset
103 % [ni,nir] = State.toMarginal(sn, ind, StateSpace(st,(istSpaceShift(i)+1):(istSpaceShift(i)+size(sn.space{i},2))));
104 % if ni>0
105 % for k=1:K
106 % UN(i,k) = UN(i,k) + probSysState(st)*nir(k)*sn.schedparam(i,k)/(nir*sn.schedparam(i,:)');
107 % end
108 % end
109 % end
110 end
111 otherwise
112 if isempty(sn.lldscaling) && isempty(sn.cdscaling) && isempty(sn.jdscaling)
113 for k=1:K
114 if ~isempty(PH{ist}{k})
115 if canDropClass(k)
116 UN(ist,k) = TN(ist,k)*map_mean(PH{ist}{k})/S(ist);
117 else
118 UN(ist,k) = probSysState*arvRates(wset,isf,k)*map_mean(PH{ist}{k})/S(ist);
119 end
120 end
121 end
122 else % lld/cd/ljd cases
123 ind = sn.stationToNode(ist);
124 % see _kb/06-solver-catalog.md for rationale (SSA utilization estimator)
125 isCd = ~isempty(sn.cdscaling) && ist <= numel(sn.cdscaling) && ~isempty(sn.cdscaling{ist});
126 isJd = ~isempty(sn.jdscaling) && ist <= numel(sn.jdscaling) && ~isempty(sn.jdscaling{ist});
127 ceff = S(ist);
128 if ~isempty(sn.lldscaling) && ist <= size(sn.lldscaling,1)
129 ceff = max(ceff, max(sn.lldscaling(ist,:)));
130 end
131 for k=1:K
132 if ~isempty(PH{ist}{k})
133 if isCd || isJd
134 % effective peak = product of declared cd and jd peaks
135 cdiv = 1;
136 if isCd, cdiv = cdiv * sn.cdscalingpeak(ist,k); end
137 if isJd, cdiv = cdiv * sn.jdscalingpeak(ist,k); end
138 else
139 cdiv = ceff;
140 end
141 if cdiv > 0
142 UN(ist,k) = TN(ist,k)*map_mean(PH{ist}{k})/cdiv;
143 else
144 UN(ist,k) = 0;
145 end
146 end
147 end
148 % UN(i,1:K) = 0;
149 % for st = wset
150 % [ni,~,sir] = State.toMarginal(sn, ind, StateSpace(st,(istSpaceShift(i)+1):(istSpaceShift(i)+size(sn.space{i},2))));
151 % if ni>0
152 % for k=1:K
153 % UN(i,k) = UN(i,k) + probSysState(st)*sir(k)/S(i);
154 % end
155 % end
156 % end
157 end
158 end
159end
160
161for k=1:K
162 for ist=1:M
163 if TN(ist,k)>0
164 RN(ist,k) = QN(ist,k)./TN(ist,k);
165 else
166 RN(ist,k)=0;
167 end
168 end
169 CN(k) = NK(k)./XN(k);
170end
171%%
172
173% now update the routing probabilities in nodes with state-dependent routing
174TNcache = zeros(sn.nstateful, K);
175XNcache = zeros(sn.nstateful, K);
176for k=1:K
177 for isf=1:sn.nstateful
178 if sn.nodetype(isf) == NodeType.Cache
179 TNcache(isf,k) = probSysState*depRates(:,isf,k);
180 XNcache(isf,k) = probSysState*arvRates(:,isf,k);
181 end
182 end
183end
184
185% see _kb/09-ldes-and-cache.md for rationale (SSA cache hit/miss accounting)
186retrievalLatencyWarned = false;
187for k=1:K
188 for isf=1:sn.nstateful
189 if sn.nodetype(isf) == NodeType.Cache
190 ind = sn.statefulToNode(isf);
191 np = sn.nodeparam{ind};
192 if length(np.hitclass)>=k
193 h = np.hitclass(k);
194 m = np.missclass(k);
195 if h>0 && m>0
196 sn.nodeparam{ind}.actualhitprob(k) = TNcache(isf,h)/sum(TNcache(isf,[h,m]));
197 sn.nodeparam{ind}.actualmissprob(k) = TNcache(isf,m)/sum(TNcache(isf,[h,m]));
198 else
199 sn.nodeparam{ind}.actualhitprob(k) = NaN;
200 sn.nodeparam{ind}.actualmissprob(k) = NaN;
201 end
202
203 % see _kb/09-ldes-and-cache.md for rationale (SSA retrieval latency NaN)
204 expectedLatency = NaN;
205 if isfield(np, 'retrievalSystemQueueIndices') ...
206 && isKey(np.retrievalSystemQueueIndices, int32(k-1)) ...
207 && ~isempty(np.retrievalSystemQueueIndices(int32(k-1)))
208 if ~retrievalLatencyWarned
209 line_warning(mfilename, 'Retrieval-system expected latency is not currently implemented; reporting NaN.');
210 retrievalLatencyWarned = true;
211 end
212 end
213 sn.nodeparam{ind}.actualresidt(k) = expectedLatency;
214 end
215 end
216 end
217end
218
219QN(isnan(QN))=0;
220CN(isnan(CN))=0;
221RN(isnan(RN))=0;
222UN(isnan(UN))=0;
223XN(isnan(XN))=0;
224TN(isnan(TN))=0;
225end