LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
pfqn_ssd.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_PFQN_PFQN_SSD_H
6
#define LINE_API_PFQN_PFQN_SSD_H
7
8
/**
9
* @file
10
* @ingroup api_pfqn
11
* Server-Station Disaggregation bounds for a multiserver closed network
12
* (Dallery and Suri, SIGMETRICS 1986).
13
*
14
* Templated port of matlab/src/api/pfqn/pfqn_ssd.m. Single-class model: L is the
15
* per-station demand vector, N the population, Z the think time.
16
*
17
* Theorem 5 eq. (6) carries no think time of its own. The objection this file
18
* used to raise still stands as far as it went: inserting a bare +Z into the
19
* Theorem 5 form is NOT a bound, because the BJB optimistic step needs
20
* sum_k Q_k(N-1) = N-1, which fails once Z X(N-1) jobs sit at the terminal.
21
* What that argument missed is that the queueing term can be corrected instead
22
* of the delay being disaggregated separately. The reference now scales it by
23
* the terminal-workload factor of Lazowska et al. 1984, Table 5.2:
24
* (N-1) Y_l / (1 + Z/(N R_l)) on the lower bound and (N-1) Y_u / (1 + Z/R_u) on
25
* the upper. Both reduce to the Z=0 forms exactly, so this generalises rather
26
* than replaces eq. (6), and the Z>0 case is computed instead of refused.
27
*
28
* All operations stay in the field, so the bound is exact in rational
29
* arithmetic: a bound computed exactly is worth having, since a bound violated
30
* only by rounding is indistinguishable from a real violation.
31
*/
32
33
#include <algorithm>
34
#include <vector>
35
36
#include "
line/num/number.h
"
37
#include "
line/util/error.h
"
38
#include "
line/util/matrix.h
"
39
40
namespace
line
{
41
namespace
pfqn
{
42
43
template
<
class
T>
44
struct
SsdBounds
{
45
T
Xlo
;
46
T
Xhi
;
47
};
48
49
/**
50
* @brief Server-Station Disaggregation bounds for a multiserver closed
51
* network (Dallery and Suri, SIGMETRICS 1986).
52
*
53
* @param L demands, @param N population, @param Z think time,
54
* @param nservers per-station server counts (empty for all ones)
55
*/
56
template
<
class
T>
57
SsdBounds<T>
pfqn_ssd
(
const
std::vector<T>& L,
const
T& N,
const
T& Z,
58
const
std::vector<T>& nservers) {
59
const
std::size_t K = L.size();
60
if
(K == 0)
throw
InputError
(
"pfqn_ssd: empty demand vector"
);
61
if
(!nservers.empty() && nservers.size() != K)
62
throw
InputError
(
"pfqn_ssd: server-count vector has the wrong length"
);
63
const
T one =
num_traits<T>::from_int
(1);
64
65
T Rl =
num_traits<T>::from_int
(0), Ru =
num_traits<T>::from_int
(0);
66
T Yl =
num_traits<T>::from_int
(0);
67
std::size_t b = 0;
68
for
(std::size_t i = 0; i < K; ++i) {
69
const
T c = nservers.empty() ? one : nservers[i];
70
if
(c ==
num_traits<T>::from_int
(0))
throw
InputError
(
"pfqn_ssd: zero server count"
);
71
Rl += L[i];
72
const
T lc = L[i] / c;
73
Ru += lc;
74
if
(lc > Yl) {
75
Yl = lc;
76
b = i;
77
}
78
}
79
const
T
Kt
=
num_traits<T>::from_int
(
static_cast<
long
>
(K));
80
const
T Yu = Ru /
Kt
;
81
const
T cb = nservers.empty() ? one : nservers[b];
82
83
const
T zero =
num_traits<T>::from_int
(0);
84
// Lazowska Table 5.2 terminal-workload scaling; at Z=0 both factors are 1.
85
// A zero total demand forces Yl = Yu = 0, so the term vanishes and the
86
// division that would be undefined is never reached.
87
const
T ql = (Rl == zero) ? zero : (N - one) * Yl / (one + Z / (N * Rl));
88
const
T qu = (Ru == zero) ? zero : (N - one) * Yu / (one + Z / Ru);
89
90
SsdBounds<T>
r;
91
r.
Xlo
= N / (Rl + Z + ql);
// Theorem 5 lower, think-time corrected
92
T hi = N / (Ru + Z + qu);
// Theorem 5 upper, eq. (6), think-time corrected
93
const
T cap = cb / L[b];
94
if
(cap < hi) hi = cap;
95
const
T pop = N / (Rl + Z);
96
if
(pop < hi) hi = pop;
97
r.
Xhi
= hi;
98
return
r;
99
}
100
101
template
<
class
T>
102
SsdBounds<T>
pfqn_ssd
(
const
std::vector<T>& L,
const
T& N,
const
T& Z) {
103
return
pfqn_ssd
(L, N, Z, std::vector<T>());
104
}
105
106
}
// namespace pfqn
107
}
// namespace line
108
109
#endif
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:39
error.h
The exception types the port throws.
matrix.h
Dense matrix and non-owning view.
line::pfqn
Definition
cd_peak_scaling.h:43
line::pfqn::NcMethod::Kt
@ Kt
Definition
pfqn_nc.h:112
line::pfqn::pfqn_ssd
SsdBounds< T > pfqn_ssd(const std::vector< T > &L, const T &N, const T &Z, const std::vector< T > &nservers)
Server-Station Disaggregation bounds for a multiserver closed network (Dallery and Suri,...
Definition
pfqn_ssd.h:57
line
Definition
aoi_dist2ph.h:52
number.h
Number-type abstraction for the templated API port.
line::num_traits
Definition
number.h:111
line::pfqn::SsdBounds
Definition
pfqn_ssd.h:44
line::pfqn::SsdBounds::Xlo
T Xlo
Definition
pfqn_ssd.h:45
line::pfqn::SsdBounds::Xhi
T Xhi
Definition
pfqn_ssd.h:46
include
line
api
pfqn
pfqn_ssd.h
Generated by
1.18.0