1%% Example: Fork-Join Percentile Analysis
using SolverMAM
3% This example demonstrates automatic Fork-Join percentile analysis
4%
using SolverMAM with FJ_codes integration. When a valid Fork-Join
5% topology
is detected, SolverMAM automatically uses FJ_codes to
6% compute response time percentiles.
9% Z. Qiu, J.F. Pérez, and
P. Harrison,
"Beyond the Mean in Fork-Join Queues:
10% Efficient Approximation for Response-Time Tails", IFIP Performance 2015.
11% Copyright 2015 Imperial College London
16%% Create a simple Fork-Join model
17% This creates the structure: Source → Fork → K Queues → Join → Sink
19model = Network(
'FJ_Percentile_Example');
21% Source with exponential arrivals
22source = Source(model,
'Source');
25fork = Fork(model,
'Fork');
27% K parallel queues with exponential service
28K = 10; % Number of parallel queues
29mu = 1.0; % Service rate (per queue)
33 queues{i} = Queue(model, sprintf(
'Queue%d', i), SchedStrategy.FCFS);
36% Join node (paired with Fork)
37join = Join(model,
'Join', fork);
40sink = Sink(model,
'Sink');
42% Create an open
class (after Sink)
43jobClass = OpenClass(model,
'Class1');
44lambda = 0.5; % Arrival rate
45source.setArrival(jobClass, Exp(lambda));
48 queues{i}.setService(jobClass, Exp(mu));
51% Link the network: Source → Fork → Queues → Join → Sink
52% Create routing matrix
53P = model.initRoutingMatrix();
54P{1}(source, fork) = 1.0;
56 P{1}(fork, queues{i}) = 1.0;
57 P{1}(queues{i}, join) = 1.0;
59P{1}(join, sink) = 1.0;
63%% Solve with SolverMAM (automatically detects FJ and uses FJ_codes)
65fprintf(
'Creating SolverMAM...\n');
66solver = SolverMAM(model);
68fprintf(
'Running analysis (FJ topology will be auto-detected)...\n');
71%% Display average metrics
73fprintf(
'\n=== Average Performance Metrics ===\n');
74avgTable = solver.getAvgTable();
77%% Display percentile metrics
79fprintf(
'\n=== Response Time Percentiles ===\n');
80% Request specific percentiles: 50th, 90th, 95th, 99th
81percentiles = [50, 90, 95, 99];
82[percRT, percTable] = solver.getPerctRespT(percentiles);
86% Display detailed percentile information
87fprintf(
'\nDetailed Percentile Results:\n');
88for i = 1:length(percRT)
89 fprintf(
' Class: %s\n', percRT(i).
class);
90 fprintf(
' K (parallel queues): %d\n', percRT(i).K);
91 fprintf(
' Method: %s\n', percRT(i).method);
92 for p = 1:length(percRT(i).percentiles)
93 fprintf(
' %.2f percentile: %.4f\n', ...
94 percRT(i).percentiles(p), percRT(i).values(p));
98%% Compare with theoretical values
for exponential
case
99% For exponential service in Fork-Join, we can compute theoretical bounds
101fprintf(
'\n=== Theoretical Comparison ===\n');
102fprintf(
'System parameters:\n');
103fprintf(
' Arrival rate (lambda): %.2f\n', lambda);
104fprintf(
' Service rate per queue (mu): %.2f\n', mu);
105fprintf(
' Number of parallel queues (K): %d\n', K);
106fprintf(
' Utilization per queue: %.2f\n', lambda/mu);
108 fprintf(
' Stability: Stable\n');
110 fprintf(
' Stability: Unstable\n');
113% Mean response time approximation
for exponential FJ
114mean_rt_approx = sum(1./(mu * (1:K)));
115fprintf(
' Approximate mean response time: %.4f\n', mean_rt_approx);
117fprintf(
'\nNote: FJ_codes provides accurate percentile approximations\n');
118fprintf(
' for the synchronization delay in Fork-Join systems.\n');