1function [W, rho_total] = qsys_mg1_srpt(lambda, mu, cs)
2% QSYS_MG1_SRPT Compute mean response time
for M/G/1/SRPT queue
4% [W, RHO] = QSYS_MG1_SRPT(LAMBDA, MU, CS) computes the mean response time
5%
for each job
class in an M/G/1 queue with Shortest Remaining Processing
6% Time (SRPT) scheduling.
8% For SRPT, the mean response time
for a job of size x
is given by the
9% Schrage-Miller formula (Section 4.2 of Wierman-Harchol-Balter 2003):
11% E[T(x)] = lambda*integral_0^x t*F_bar(t)dt / (1-rho(x))^2
12% + integral_0^x dt/(1-rho(t))
15% - rho(x) = lambda * integral_0^x t*f(t)dt (truncated load)
16% - F_bar(t) = 1 - F(t) (complementary CDF)
18% For exponential service (M/M/1/SRPT), with multiple
classes having
19% different service rates, the analysis reduces to preemptive priority
20% queueing since the memoryless property makes remaining time distribution
21% equal to the original distribution.
24% lambda : Vector of arrival rates per class
25% mu : Vector of service rates per class
26% cs : Vector of coefficients of variation per class (cs=1 for exponential)
29% W : Vector of mean response times per class (sorted by service time)
30% rho : Overall system utilization
33% For multiple
classes with different service times, SRPT effectively
34% gives preemptive priority to smaller jobs. Classes are internally
35% sorted by mean service time (ascending), and priority queue analysis
39% - L. E. Schrage and L. W. Miller,
"The queue M/G/1 with the shortest
40% remaining processing time discipline", Operations Research, 14:670-684, 1966.
41% - A. Wierman and M. Harchol-Balter,
"Classifying scheduling policies with
42% respect to unfairness in an M/GI/1", SIGMETRICS 2003.
44% Copyright (c) 2012-2026, Imperial College London
47% Ensure inputs are column vectors
48lambda = reshape(lambda, [], 1);
49mu = reshape(mu, [], 1);
50cs = reshape(cs, [], 1);
52% Validate input lengths
53if ~isequal(length(lambda), length(mu), length(cs))
54 error(
'qsys_mg1_srpt:InvalidInput', ...
55 'lambda, mu, and cs must have the same length');
58% Validate positive values
59if any(lambda <= 0) || any(mu <= 0) || any(cs < 0)
60 error('qsys_mg1_srpt:InvalidInput', ...
61 'lambda and mu must be positive, cs must be non-negative');
66% Compute mean service times per class
67mean_service = 1 ./ mu;
69% Sort
classes by mean service time (ascending) for SRPT priority
70[sorted_service, sort_idx] = sort(mean_service, 'ascend');
72% Reorder parameters according to sorted service times
73lambda_sorted = lambda(sort_idx);
74mu_sorted = mu(sort_idx);
75cs_sorted = cs(sort_idx);
77% Compute per-class utilizations (sorted order)
78rho_i = lambda_sorted ./ mu_sorted;
81rho_total = sum(rho_i);
85 error('qsys_mg1_srpt:UnstableSystem', ...
86 sprintf('System
is unstable: utilization rho = %g >= 1', rho_total));
89% For SRPT with general service distributions, we use numerical integration.
90% For the exponential case (cs = 1), SRPT reduces to preemptive priority.
91% We check if all cs values are approximately 1 (exponential case).
92is_exponential = all(abs(cs - 1) < 1e-10);
94if is_exponential || K == 1
95 % Exponential case or single class: use preemptive priority formula
96 W_sorted = qsys_mg1_srpt_exp(lambda_sorted, mu_sorted);
98 % General case: use numerical integration for each class
99 W_sorted = qsys_mg1_srpt_general(lambda_sorted, mu_sorted, cs_sorted);
102% Restore original class ordering
103[~, unsort_idx] = sort(sort_idx);
104W = W_sorted(unsort_idx);
106% Compute rhohat = Q/(1+Q) to match qsys convention
108rho_total = Q / (1 + Q);
113function W = qsys_mg1_srpt_exp(lambda, mu)
114% SRPT for exponential service - uses preemptive priority formula
115% Because of memoryless property, SRPT behaves like preemptive priority
116% where priority
is based on expected service time.
118% For preemptive resume priority, class k only sees residual service time
119% from
classes 1 to k (higher priority
classes plus itself), since it can
120% preempt all lower priority
classes.
125% Compute response times using preemptive priority formula
129 % Cumulative utilization up to class k-1 (higher priority
classes)
133 rho_prev = sum(rho_i(1:k-1));
136 % Cumulative utilization up to class k
137 rho_curr = sum(rho_i(1:k));
139 % Cumulative mean residual service time from
classes 1 to k
140 % E[R_k] = sum_{i=1}^k lambda_i / mu_i^2
141 % Class k only sees residual from
classes that can
't be preempted (1 to k)
142 E_R_k = sum(lambda(1:k) ./ (mu(1:k).^2));
144 % Mean waiting time for class k (preemptive priority)
145 % W_q_k = E[R_k] / ((1 - rho_prev) * (1 - rho_curr))
146 W_q = E_R_k / ((1 - rho_prev) * (1 - rho_curr));
148 % Response time = waiting time + service time
149 W(k) = W_q + 1 / mu(k);
155function W = qsys_mg1_srpt_general(lambda, mu, cs)
156% SRPT for general service distributions
157% Uses numerical integration of the Schrage-Miller formula
162% Build mixture distribution parameters
163% Aggregate arrival rate and mixture probabilities
164lambda_total = sum(lambda);
165p = lambda / lambda_total; % mixture probabilities
167% Compute overall moments
168% E[S] = sum_i p_i * E[S_i]
169% E[S^2] = sum_i p_i * E[S_i^2]
170mean_S = sum(p ./ mu);
171var_S = sum(p .* ((1 + cs.^2) ./ mu.^2)) - mean_S^2;
172E_S2 = sum(p .* ((1 + cs.^2) ./ mu.^2));
175rho = lambda_total * mean_S;
177% For each class, compute response time at the class's mean service time
178% This
is an approximation - exact SRPT analysis
requires the full
179% job size distribution, but we can use the
class-conditional formula.
182 x = 1 / mu(k); % Mean service time
for class k
184 % Compute truncated load rho(x) and integrals numerically
185 % For the mixture distribution
187 % Truncated load: rho(x) = lambda_total * integral_0^x t*f(t)dt
188 % where f(t) = sum_i p_i * f_i(t)
190 % For simplicity, approximate
using the cumulative contribution
191 % from
classes with smaller mean service times
192 smaller_idx = (1 ./ mu) <= x;
193 rho_x = sum(lambda(smaller_idx) ./ mu(smaller_idx));
195 % Approximate the integral terms
196 % For the waiting time component
200 % Use approximation based on truncated workload
201 % Numerator integral: lambda * integral_0^x t*F_bar(t)dt
202 % For exponential mixture, approximate
206 % Contribution from
class i
207 numerator = numerator + lambda(i) / (mu(i)^2);
211 % Second integral: integral_0^x dt/(1-rho(t))
212 % Approximate
using quadrature
217 t = (step - 0.5) * dt;
218 % Compute rho(t) at
this point
221 % For exponential: integral_0^t s*mu*exp(-mu*s)ds
222 % = 1/mu * (1 - exp(-mu*t)*(1 + mu*t))
223 rho_t = rho_t + lambda(i) / mu(i) * (1 - exp(-mu(i)*t) * (1 + mu(i)*t));
226 second_term = second_term + dt / (1 - rho_t);
230 % Schrage-Miller formula
231 W(k) = numerator / (1 - rho_x)^2 + second_term;