LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
overtake_prob_markov.m
1function prOt = overtake_prob_markov(self, eidx)
2% OVERTAKE_PROB_MARKOV Overtaking probability via the LQNS phased-server Markov chain.
3%
4% PROT = OVERTAKE_PROB_MARKOV(SELF, EIDX) computes the probability that a new
5% arrival to server entry EIDX finds the server busy in phase 2 (post-reply
6% processing), using the LQNS V6 slice/overtake Markov chain (Layer 1) rather
7% than the reduced 3-state CTMC in OVERTAKE_PROB.
8%
9% This is the input-mapping layer (Layer 1c): it derives the per-client-phase
10% slice parameters (nSlices, host residence, calls to the server task, calls to
11% other tasks, delay at other tasks) from the LayeredNetworkStruct and the
12% current per-layer MVA residence times, then delegates the chain solution to
13% LQN_OVERTAKE_MARKOV. Contributions of all synchronous caller entries are
14% summed and truncated to 1 (cf. LQNS Markov_Phased_Server::PrOT_e).
15%
16% Reference: Franks & Woodside, "Effectiveness of early replies in client-server
17% systems", Perf. Eval. 36 (1999). See [[overtaking-markov-port]].
18
19 lqn = self.lqn;
20 prOt = 0.0;
21
22 % Server phase-2 residence (x_j for the tested server phase j=2).
23 xj = self.servt_ph2(eidx);
24 if ~(xj > GlobalConstants.FineTol)
25 return;
26 end
27 server_tidx = lqn.parent(eidx);
28
29 % Synchronous caller activities into this server entry.
30 caller_acts = full(lqn.callpair(lqn.callpair(:,2) == eidx, 1));
31 if isempty(caller_acts)
32 return;
33 end
34
35 % Group caller activities by their owning client entry.
36 caller_entries = [];
37 for ci = 1:numel(caller_acts)
38 aidx = caller_acts(ci);
39 ceidx = local_entry_of_activity(lqn, aidx);
40 if ceidx > 0 && ~any(caller_entries == ceidx)
41 caller_entries(end+1) = ceidx; %#ok<AGROW>
42 end
43 end
44
45 for ceidx = caller_entries
46 ctidx = lqn.parent(ceidx);
47 acts = lqn.actsof{ceidx};
48 if isempty(acts)
49 continue;
50 end
51
52 % Maximum client phase (LINE activities carry phase 1 or 2).
53 maxPhaseA = 1;
54 for aidx = acts
55 a = aidx - lqn.ashift;
56 if a >= 1 && a <= lqn.nacts
57 maxPhaseA = max(maxPhaseA, lqn.actphase(a));
58 end
59 end
60
61 % clientPhases rows p=0..maxPhaseA: [nSlices service y_ij y_ik t_k].
62 nStates = maxPhaseA + 1;
63 clientPhases = zeros(nStates, 5);
64 clientPhases(1,1) = 1.0; % think slice: nSlices=1
65 clientPhases(1,2) = local_think_time(lqn, ctidx); % service = client think time
66
67 y_aj = zeros(1, maxPhaseA + 1);
68 for p = 1:maxPhaseA
69 nSlices = 1.0; service = 0.0;
70 y_ij = 0.0; y_ik = 0.0; tk_num = 0.0;
71 for aidx = acts
72 a = aidx - lqn.ashift;
73 if a < 1 || a > lqn.nacts || lqn.actphase(a) ~= p
74 continue;
75 end
76 service = service + self.servt(aidx); % host residence of the phase
77 for c = lqn.callsof{aidx}
78 if lqn.calltype(c) ~= CallType.SYNC
79 continue;
80 end
81 y = lqn.callproc_mean(c);
82 if y == 0, continue; end
83 nSlices = nSlices + y;
84 dst_tidx = lqn.parent(lqn.callpair(c,2));
85 if dst_tidx == server_tidx
86 y_ij = y_ij + y;
87 else
88 y_ik = y_ik + y;
89 tk_num = tk_num + y * self.callresidt(c); % rendezvous delay
90 end
91 end
92 end
93 if y_ik > 0.0, t_k = tk_num / y_ik; else, t_k = 0.0; end
94 clientPhases(p+1,:) = [nSlices, service, y_ij, y_ik, t_k];
95 y_aj(p+1) = y_ij;
96 y_aj(1) = y_aj(1) + y_ij;
97 end
98
99 if y_aj(1) == 0.0
100 continue; % this client does not call the server task
101 end
102
103 % Client entry visit probability (1 for reference/sole entry).
104 prVisit = 1.0;
105 if self.tput(ctidx) > GlobalConstants.FineTol && self.tput(ceidx) > GlobalConstants.FineTol
106 prVisit = self.tput(ceidx) / self.tput(ctidx);
107 end
108
109 prOt = prOt + lqn_overtake_markov(clientPhases, prVisit, xj, y_aj);
110 end
111
112 prOt = max(0.0, min(1.0, prOt));
113end
114
115% ---------------------------------------------------------------------------
116function ceidx = local_entry_of_activity(lqn, aidx)
117% Absolute entry index owning activity aidx (via actsof), else -1.
118 ceidx = -1;
119 for e = 1:lqn.nentries
120 eabs = lqn.eshift + e;
121 if any(lqn.actsof{eabs} == aidx)
122 ceidx = eabs;
123 return;
124 end
125 end
126end
127
128function z = local_think_time(lqn, tidx)
129% Client task think time (0 when unspecified).
130 z = 0.0;
131 if isfield(lqn, 'think_mean') && numel(lqn.think_mean) >= tidx
132 v = lqn.think_mean(tidx);
133 if isfinite(v) && v > 0, z = v; end
134 end
135end
Definition Station.m:245