1function [W, rho_total] = qsys_mg1_lrpt(lambda, mu, cs)
2% QSYS_MG1_LRPT Compute mean response time
for M/G/1/LRPT queue
4% [W, RHO] = QSYS_MG1_LRPT(LAMBDA, MU, CS) computes the mean response time
5%
for each job
class in an M/G/1 queue with Longest Remaining Processing
6% Time (LRPT) scheduling.
8% Under LRPT, the job with the longest remaining processing time receives
9% exclusive service. This
is a remaining-size based policy that favors
12% For LRPT, the slowdown
for a job of size x
is given by
13% (Section 3.2 of Wierman-Harchol-Balter 2003):
15% E[S(x)]^LRPT = 1/(1-rho) + lambda*E[X^2]/(2*x*(1-rho)^2)
16% E[T(x)]^LRPT = x * E[S(x)]^LRPT
18% For exponential service, the expected response time for class k
is computed
19% by integrating E[T(x)] over the exponential distribution of class k sizes.
21% CLASSIFICATION (Wierman-Harchol-Balter 2003):
22% LRPT
is "Always Unfair" - it favors large jobs at the expense of
26% lambda : Vector of arrival rates per class
27% mu : Vector of service rates per class
28% cs : Vector of coefficients of variation per class (cs=1 for exponential)
31% W : Vector of mean response times per class
32% rho : Overall system utilization (modified for Little
's law)
35% - A. Wierman and M. Harchol-Balter, "Classifying scheduling policies with
36% respect to unfairness in an M/GI/1", SIGMETRICS 2003, Section 3.2.
38% Copyright (c) 2012-2026, Imperial College London
41% Ensure inputs are column vectors
42lambda = reshape(lambda, [], 1);
43mu = reshape(mu, [], 1);
44cs = reshape(cs, [], 1);
46% Validate input lengths
47if ~isequal(length(lambda), length(mu), length(cs))
48 error('qsys_mg1_lrpt:InvalidInput
', ...
49 'lambda, mu, and cs must have the same length
');
52% Validate positive values
53if any(lambda <= 0) || any(mu <= 0) || any(cs < 0)
54 error('qsys_mg1_lrpt:InvalidInput
', ...
55 'lambda and mu must be positive, cs must be non-negative
');
61rho_total = sum(lambda ./ mu);
65 error('qsys_mg1_lrpt:UnstableSystem
', ...
66 sprintf('System
is unstable: utilization rho = %g >= 1', rho_total));
69% Check
if all
classes are exponential (cs = 1)
70if all(abs(cs - 1) < 1e-6)
71 % Use specialized formula for exponential service
72 W = qsys_mg1_lrpt_exp(lambda, mu);
74 % General case: use class-based approximation
75 W = qsys_mg1_lrpt_general(lambda, mu, cs);
78% Compute rhohat = Q/(1+Q) to match qsys convention
80rho_total = Q / (1 + Q);
84function W = qsys_mg1_lrpt_exp(lambda, mu)
85% Specialized LRPT formula for exponential service times
87% Uses the Wierman-Harchol-Balter formula:
88% E[S(x)]^LRPT = 1/(1-rho) + lambda*E[X^2]/(2*x*(1-rho)^2)
89% E[T(x)]^LRPT = x/(1-rho) + lambda*E[X^2]/(2*(1-rho)^2)
91% For exponential service, integrate over the job size distribution:
92% E[T_k] = integral_0^inf E[T(x)] * f_k(x) dx
95lambda_total = sum(lambda);
96rho_total = sum(lambda ./ mu);
97p = lambda / lambda_total; % mixing probabilities
99% Compute E[X^2] for the mixture distribution
100% E[X^2] = sum_i p_i * E[S_i^2] = sum_i p_i * 2/mu_i^2
101E_X2 = sum(p .* 2 ./ (mu.^2));
108 % Upper limit for integration: 20 mean service times
111 % LRPT response time for a job of size x
112 T_of_x = @(x) x / (1 - rho_total) + lambda_total * E_X2 / (2 * (1 - rho_total)^2);
114 % Exponential density for class k
115 f_k = @(x) mu_k * exp(-mu_k * x);
117 % Integrand: E[T(x)] * f_k(x)
118 integrand = @(x) T_of_x(x) .* f_k(x);
120 % Numerical integration
121 W(k) = integral(integrand, 0, x_max, 'RelTol', 1e-8, 'AbsTol', 1e-10);
126function W = qsys_mg1_lrpt_general(lambda, mu, cs)
127% General LRPT formula using class-based preemptive priority approximation
130mean_service = 1 ./ mu;
132% Sort
classes by mean service time DESCENDING for LRPT priority
133[~, sort_idx] = sort(mean_service, 'descend');
135lambda_sorted = lambda(sort_idx);
136mu_sorted = mu(sort_idx);
138rho_i = lambda_sorted ./ mu_sorted;
140W_sorted = zeros(K, 1);
146 rho_prev = sum(rho_i(1:k-1));
149 rho_curr = sum(rho_i(1:k));
150 E_R_k = sum(lambda_sorted(1:k) ./ (mu_sorted(1:k).^2));
151 W_q = E_R_k / ((1 - rho_prev) * (1 - rho_curr));
152 W_sorted(k) = W_q + 1 / mu_sorted(k);
155[~, unsort_idx] = sort(sort_idx);
156W = W_sorted(unsort_idx);