LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
cache_miss.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_CACHE_MISS_H
6
#define LINE_API_CACHE_MISS_H
7
8
/**
9
* @file
10
* @ingroup api_cache
11
* Exact cache miss rates from the recursive normalizing constant.
12
*
13
* Templated port of matlab/src/api/cache/cache_miss.m, cross-checked against
14
* jar/src/main/java/jline/api/cache/Cache_miss.java.
15
*
16
* Two quantities are computed, both as ratios of cache_erec constants:
17
* M = E(gamma, m + e_1) / E(gamma, m), the global miss rate; and
18
* pi0(k) = E(gamma without item k, m) / E(gamma, m), the probability that
19
* item k is absent from the cache,
20
* from which the per-user rate MU(v) = sum_k lambda(v,k) pi0(k) and the
21
* per-item rate MI(k) = (sum_v lambda(v,k)) pi0(k) follow.
22
*
23
* Pure field operations throughout, so the exact instantiation returns rates
24
* with no rounding.
25
*
26
* DIVERGENCE, MATLAB vs JAR: MATLAB conditions on the absence of item k by
27
* deleting ROW k of gamma, gamma(setdiff(1:n,k),:) -- gamma is item-by-list,
28
* so a row is an item. The JAR's Cache_miss deletes COLUMN k instead (it
29
* builds gammaWithoutK by iterating over gamma.getNumCols() and skipping
30
* j == k), which removes a cache LIST, not an item, and additionally reads the
31
* item count as lambda.getNumCols() while indexing gamma by it. The JAR's
32
* pi0/MU/MI are therefore wrong whenever h != n, and meaningless in general.
33
* This port follows MATLAB.
34
*/
35
36
#include <cstddef>
37
#include <vector>
38
39
#include "
line/api/cache/cache_erec.h
"
40
#include "
line/num/number.h
"
41
#include "
line/util/error.h
"
42
#include "
line/util/matrix.h
"
43
44
namespace
line
{
45
namespace
cache
{
46
47
/** Return value of cache_miss, mirroring [M,MU,MI,pi0]. */
48
template
<
class
T>
49
struct
CacheMissResult
{
50
T
M
;
///< global miss rate
51
std::vector<T>
MU
;
///< (u) per-user miss rate; empty when no lambda given
52
std::vector<T>
MI
;
///< (n) per-item miss rate; empty when no lambda given
53
std::vector<T>
pi0
;
///< (n) per-item miss probability; empty when no lambda given
54
};
55
56
/**
57
* @brief Exact cache miss rates from the recursive normalizing constant.
58
*
59
* @param gamma (n x h) access factors
60
* @param m (h) list capacities
61
* @param lambda (u x n) per-user per-item request rates, MATLAB's
62
* lambda(:,:,1); pass an empty matrix for the miss rate alone
63
*/
64
template
<
class
T>
65
CacheMissResult<T>
cache_miss
(
const
Matrix<T>
& gamma,
const
std::vector<int>& m,
66
const
Matrix<T>
& lambda) {
67
if
(gamma.
cols
() != m.size())
68
throw
InputError
(
"cache_miss: gamma and m disagree on the number of lists"
);
69
if
(m.empty())
throw
InputError
(
"cache_miss: empty capacity vector"
);
70
71
std::vector<int> ma = m;
72
ma[0] += 1;
73
74
const
T Em =
cache_erec
(gamma, m);
75
if
(Em ==
num_traits<T>::from_int
(0))
76
throw
NumericError
(
ErrorKind
{
"Degenerate"
},
"cache_miss: the normalizing constant is zero"
);
77
78
CacheMissResult<T>
r;
79
r.
M
=
cache_erec
(gamma, ma) / Em;
80
if
(lambda.
empty
())
return
r;
81
82
const
std::size_t u = lambda.
rows
();
83
const
std::size_t n = gamma.
rows
();
84
if
(lambda.
cols
() != n)
85
throw
InputError
(
"cache_miss: lambda and gamma disagree on the number of items"
);
86
87
r.pi0.assign(n,
num_traits<T>::from_int
(0));
88
for
(std::size_t k = 0; k < n; ++k)
89
r.pi0[k] =
cache_erec
(detail::gamma_without_row(gamma, k), m) / Em;
90
91
r.MU.assign(u,
num_traits<T>::from_int
(0));
92
for
(std::size_t v = 0; v < u; ++v)
93
for
(std::size_t k = 0; k < n; ++k) r.MU[v] += lambda(v, k) * r.pi0[k];
94
95
r.MI.assign(n,
num_traits<T>::from_int
(0));
96
for
(std::size_t k = 0; k < n; ++k) {
97
T s =
num_traits<T>::from_int
(0);
98
for
(std::size_t v = 0; v < u; ++v) s += lambda(v, k);
99
r.MI[k] = s * r.pi0[k];
100
}
101
return
r;
102
}
103
104
/** Overload without request rates: only the global miss rate is defined. */
105
template
<
class
T>
106
CacheMissResult<T>
cache_miss
(
const
Matrix<T>
& gamma,
const
std::vector<int>& m) {
107
return
cache_miss
(gamma, m,
Matrix<T>
());
108
}
109
110
/**
111
* @brief Cost-capped overload, MATLAB's cache_miss(gamma, m, lambda, sigma, cap):
112
* every normalizing constant is the cost-constrained cache_erec(gamma, m,
113
* sigma, cap), and the per-item constants drop item k from sigma as well.
114
* Empty sigma or cap falls back to the unconstrained form, as in the reference.
115
*
116
* @param sigma (n) per-item storage costs
117
* @param cap (h) per-list storage cost caps
118
*/
119
template
<
class
T>
120
CacheMissResult<T>
cache_miss
(
const
Matrix<T>
& gamma,
const
std::vector<int>& m,
121
const
Matrix<T>
& lambda,
const
std::vector<int>& sigma,
122
const
std::vector<int>& cap) {
123
if
(sigma.empty() || cap.empty())
return
cache_miss
(gamma, m, lambda);
124
if
(gamma.
cols
() != m.size())
125
throw
InputError
(
"cache_miss: gamma and m disagree on the number of lists"
);
126
if
(m.empty())
throw
InputError
(
"cache_miss: empty capacity vector"
);
127
if
(sigma.size() != gamma.
rows
())
128
throw
InputError
(
"cache_miss: sigma and gamma disagree on the number of items"
);
129
130
std::vector<int> ma = m;
131
ma[0] += 1;
132
133
const
T Em =
cache_erec
(gamma, m, sigma, cap);
134
if
(Em ==
num_traits<T>::from_int
(0))
135
throw
NumericError
(
ErrorKind
{
"Degenerate"
},
"cache_miss: the normalizing constant is zero"
);
136
137
CacheMissResult<T>
r;
138
r.
M
=
cache_erec
(gamma, ma, sigma, cap) / Em;
139
if
(lambda.
empty
())
return
r;
140
141
const
std::size_t u = lambda.
rows
();
142
const
std::size_t n = gamma.
rows
();
143
if
(lambda.
cols
() != n)
144
throw
InputError
(
"cache_miss: lambda and gamma disagree on the number of items"
);
145
146
r.pi0.assign(n,
num_traits<T>::from_int
(0));
147
for
(std::size_t k = 0; k < n; ++k) {
148
std::vector<int> sigma_others;
149
sigma_others.reserve(n - 1);
150
for
(std::size_t i = 0; i < n; ++i)
151
if
(i != k) sigma_others.push_back(sigma[i]);
152
r.pi0[k] =
cache_erec
(detail::gamma_without_row(gamma, k), m, sigma_others, cap) / Em;
153
}
154
155
r.MU.assign(u,
num_traits<T>::from_int
(0));
156
for
(std::size_t v = 0; v < u; ++v)
157
for
(std::size_t k = 0; k < n; ++k) r.MU[v] += lambda(v, k) * r.pi0[k];
158
159
r.MI.assign(n,
num_traits<T>::from_int
(0));
160
for
(std::size_t k = 0; k < n; ++k) {
161
T s =
num_traits<T>::from_int
(0);
162
for
(std::size_t v = 0; v < u; ++v) s += lambda(v, k);
163
r.MI[k] = s * r.pi0[k];
164
}
165
return
r;
166
}
167
168
/** Cost-capped overload without request rates. */
169
template
<
class
T>
170
CacheMissResult<T>
cache_miss
(
const
Matrix<T>
& gamma,
const
std::vector<int>& m,
171
const
std::vector<int>& sigma,
const
std::vector<int>& cap) {
172
return
cache_miss
(gamma, m,
Matrix<T>
(), sigma, cap);
173
}
174
175
}
// namespace cache
176
}
// namespace line
177
178
#endif
// LINE_API_CACHE_MISS_H
cache_erec.h
Exact recursive normalizing constant of a multi-list cache model.
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:105
line::Matrix
Definition
matrix.h:56
line::Matrix::cols
std::size_t cols() const
Definition
matrix.h:90
line::Matrix::rows
std::size_t rows() const
Definition
matrix.h:89
line::Matrix::empty
bool empty() const
Definition
matrix.h:92
line::NumericError::NumericError
NumericError(const std::string &what)
Definition
error.h:112
error.h
The exception types the port throws.
matrix.h
Dense matrix and non-owning view.
line::cache
Definition
cache_cost.h:42
line::cache::cache_miss
CacheMissResult< T > cache_miss(const Matrix< T > &gamma, const std::vector< int > &m, const Matrix< T > &lambda)
Exact cache miss rates from the recursive normalizing constant.
Definition
cache_miss.h:65
line::cache::cache_erec
T cache_erec(const Matrix< T > &gamma, const std::vector< int > &m)
Exact recursive normalizing constant of a multi-list cache model.
Definition
cache_erec.h:201
line
Conservation laws of a layered queueing network, enumerated from its structure.
Definition
aoi_dist2ph.h:52
number.h
Number-type abstraction for the templated API port.
line::ErrorKind
The <kind> part of a LINE:<category>:<kind> identifier (see _kb/17-error-vocabulary....
Definition
error.h:37
line::cache::CacheMissResult
Return value of cache_miss, mirroring [M,MU,MI,pi0].
Definition
cache_miss.h:49
line::cache::CacheMissResult::M
T M
global miss rate
Definition
cache_miss.h:50
line::cache::CacheMissResult::MI
std::vector< T > MI
(n) per-item miss rate; empty when no lambda given
Definition
cache_miss.h:52
line::cache::CacheMissResult::MU
std::vector< T > MU
(u) per-user miss rate; empty when no lambda given
Definition
cache_miss.h:51
line::cache::CacheMissResult::pi0
std::vector< T > pi0
(n) per-item miss probability; empty when no lambda given
Definition
cache_miss.h:53
line::num_traits
Definition
number.h:123
include
line
api
cache
cache_miss.h
Generated by
1.18.0