LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
fj_respt_bulk.h
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2012-2026, QORE Lab, Imperial College London
3
* All rights reserved.
4
*/
5
#ifndef LINE_API_FJ_RESPT_BULK_H
6
#define LINE_API_FJ_RESPT_BULK_H
7
8
/**
9
* @file
10
* @ingroup api_fj
11
* Centralized splitting analysed as an M[K]/M/c bulk arrival system.
12
*
13
* Templated port of matlab/src/api/fj/fj_respt_bulk.m.
14
*
15
* A request forks into K tasks held in a single central queue and served by c
16
* identical servers, so the same server may serve several tasks of the same
17
* request: an M[K]/M/c queue with fixed batch size K. Its level chain is solved
18
* by truncation, which is exact up to the tail mass discarded.
19
*
20
* The request response time is the completion of the LAST of the K tasks. By
21
* PASTA the batch finds n tasks in system, its last task is the (n+K)-th in
22
* line, and under first come first served with c exponential servers it starts
23
* service after max(0, n+K-c) departures, each an exponential of rate c mu:
24
*
25
* E[R_request] = sum_n p_n [ max(0, n+K-c)/(c mu) + 1/mu ].
26
*
27
* This lower bounds the distributed splitting fork-join system, because no task
28
* is bound to a particular server.
29
*/
30
31
#include <cstddef>
32
#include <vector>
33
34
#include "
line/api/fj/fj_types.h
"
35
#include "
line/api/mc/ctmc_solve.h
"
36
#include "
line/num/number.h
"
37
#include "
line/util/error.h
"
38
#include "
line/util/matrix.h
"
39
40
namespace
line
{
41
namespace
fj
{
42
43
/** [Rreq, Rtask, Q, p] of fj_respt_bulk. */
44
template
<
class
T>
45
struct
FJResptBulkResult
{
46
T
Rreq
;
47
T
Rtask
;
48
T
Q
;
49
std::vector<T>
p
;
50
};
51
52
/**
53
* @brief Centralized splitting analysed as an M[K]/M/c bulk arrival system.
54
*
55
* @param K batch size, that is the number of tasks per request
56
* @param lambda arrival rate of requests
57
* @param mu per-server task service rate
58
* @param c number of servers
59
* @param nmax truncation level of the task-count chain, 0 for the default
60
* @return the request and task response times, the mean queue and the distribution
61
*/
62
template
<
class
T>
63
FJResptBulkResult<T>
fj_respt_bulk
(
unsigned
K,
const
T& lambda,
const
T& mu,
unsigned
c,
64
std::size_t nmax = 0) {
65
detail::require_positive_K(K,
"fj_respt_bulk"
);
66
if
(c < 1)
throw
InputError
(
"fj_respt_bulk: c must be a positive integer"
);
67
const
T zero =
num_traits<T>::from_int
(0), one =
num_traits<T>::from_int
(1);
68
if
(!(lambda > zero) || !(mu > zero))
69
throw
InputError
(
"fj_respt_bulk: lambda and mu must be positive"
);
70
71
const
T Kt =
num_traits<T>::from_int
(
static_cast<
long
>
(K));
72
const
T ct =
num_traits<T>::from_int
(
static_cast<
long
>
(c));
73
const
T rho = lambda * Kt / (ct * mu);
74
if
(rho >= one)
75
throw
NumericError
(
"fj_respt_bulk: unstable system, rho = lambda*K/(c*mu) >= 1"
);
76
77
if
(nmax == 0) {
78
const
double
rd =
num_traits<T>::to_double
(rho);
79
const
double
want =
static_cast<
double
>
(K) + 40.0 *
static_cast<
double
>
(c) / (1.0 - rd);
80
nmax =
static_cast<
std::size_t
>
(want > 200.0 ? want : 200.0);
81
}
82
const
std::size_t ns = nmax + 1;
83
84
// Generator of the task-count chain: batch arrivals of K, service min(n,c) mu
85
Matrix<T>
Q(ns, ns, zero);
86
for
(std::size_t i = 0; i < ns; ++i) {
87
if
(i > 0) {
88
const
std::size_t busy = (i < c) ? i : c;
89
const
T srv =
num_traits<T>::from_int
(
static_cast<
long
>
(busy)) * mu;
90
Q(i, i - 1) = Q(i, i - 1) + srv;
91
Q(i, i) = Q(i, i) - srv;
92
}
93
const
std::size_t j = i + K;
94
if
(j < ns) {
95
Q(i, j) = Q(i, j) + lambda;
96
Q(i, i) = Q(i, i) - lambda;
97
}
98
}
99
100
FJResptBulkResult<T>
out;
101
out.
p
=
mc::ctmc_solve
(Q);
102
103
out.
Q
= zero;
104
for
(std::size_t n = 0; n < ns; ++n)
105
out.
Q
+=
num_traits<T>::from_int
(
static_cast<
long
>
(n)) * out.
p
[n];
106
out.
Rtask
= out.
Q
/ (lambda * Kt);
107
108
// Last of the K tasks of a tagged batch: the (n+K)-th in line on arrival
109
out.
Rreq
= zero;
110
for
(std::size_t n = 0; n < ns; ++n) {
111
const
std::size_t ahead = n + K;
112
const
T wait = (ahead > c) ?
num_traits<T>::from_int
(
static_cast<
long
>
(ahead - c)) /
113
(ct * mu)
114
: zero;
115
out.
Rreq
+= out.
p
[n] * (wait + one / mu);
116
}
117
return
out;
118
}
119
120
}
// namespace fj
121
}
// namespace line
122
123
#endif
// LINE_API_FJ_RESPT_BULK_H
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:39
line::Matrix
Definition
matrix.h:56
line::NumericError::NumericError
NumericError(const std::string &what)
Definition
error.h:45
ctmc_solve.h
Steady-state distribution of a continuous-time Markov chain.
error.h
The exception types the port throws.
fj_types.h
Shared return types and arithmetic helpers for the templated fork-join port.
matrix.h
Dense matrix and non-owning view.
line::fj
Definition
fj_amva.h:34
line::fj::fj_respt_bulk
FJResptBulkResult< T > fj_respt_bulk(unsigned K, const T &lambda, const T &mu, unsigned c, std::size_t nmax=0)
Centralized splitting analysed as an M[K]/M/c bulk arrival system.
Definition
fj_respt_bulk.h:63
line::mc::ctmc_solve
std::vector< T > ctmc_solve(const Matrix< T > &Qin)
Steady-state distribution of a continuous-time Markov chain.
Definition
ctmc_solve.h:122
line
Definition
aoi_dist2ph.h:52
number.h
Number-type abstraction for the templated API port.
line::fj::FJResptBulkResult
[Rreq, Rtask, Q, p] of fj_respt_bulk.
Definition
fj_respt_bulk.h:45
line::fj::FJResptBulkResult::Rreq
T Rreq
Definition
fj_respt_bulk.h:46
line::fj::FJResptBulkResult::p
std::vector< T > p
Definition
fj_respt_bulk.h:49
line::fj::FJResptBulkResult::Q
T Q
Definition
fj_respt_bulk.h:48
line::fj::FJResptBulkResult::Rtask
T Rtask
Definition
fj_respt_bulk.h:47
line::num_traits
Definition
number.h:111
include
line
api
fj
fj_respt_bulk.h
Generated by
1.18.0