LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
cache_mva_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_MVA_MISS_H
6#define LINE_API_CACHE_MVA_MISS_H
7
8/**
9 * @file
10 * @ingroup api_cache
11 * Per-item and global cache miss probabilities by mean value analysis.
12 *
13 * Templated port of matlab/src/api/cache/cache_mva_miss.m, cross-checked
14 * against jar/src/main/java/jline/api/cache/Cache_mva_miss.java.
15 *
16 * Recursion on the capacity vector: at capacity m the weight of item k in list
17 * j is w(k,j) = prod_{i<=j} R(i,k) p(k)^j |Mk(k; m - e_j)|, i.e. the item's
18 * miss probability one slot down, scaled by the probability of reaching list j
19 * through the routing chain R and by j independent requests. The per-list
20 * normalization x(j) = 1/sum_k |w(k,j)| turns the weights into occupancy
21 * shares and the miss probability of item k is what is left after removing the
22 * m(j) slots of every list:
23 *
24 * Mk(k) = |1 - sum_j x(j) m(j) w(k,j)|, M = sum_k p(k) Mk(k).
25 *
26 * The base case sum(m) == 0 (or any negative capacity, which the recursion
27 * reaches from a list of capacity zero) is Mk == 1: nothing is cached.
28 *
29 * Only products, sums, integer powers and divisions, so the algorithm stays in
30 * the field and instantiates at exact arithmetic. The abs() calls of the
31 * reference are kept: they are no-ops on a correct instance (every weight is
32 * non-negative) but they change the answer on an over-committed one, so
33 * dropping them would silently diverge from MATLAB and the JAR.
34 */
35
36#include <cstddef>
37#include <vector>
38
39#include "line/num/number.h"
40#include "line/util/error.h"
41#include "line/util/matrix.h"
42
43namespace line {
44namespace cache {
45
46/** Return value of cache_mva_miss, mirroring [M,Mk]. */
47template <class T>
49 T M; ///< global miss rate, sum_k p(k) Mk(k)
50 std::vector<T> Mk; ///< (n) per-item miss probability
51};
52
53/**
54 * @brief Per-item and global cache miss probabilities by mean value analysis.
55 *
56 * @param p (n) item popularities
57 * @param m (h) list capacities
58 * @param R (h x n) per-list routing probabilities
59 */
60template <class T>
61CacheMvaMissResult<T> cache_mva_miss(const std::vector<T>& p, const std::vector<int>& m,
62 const Matrix<T>& R) {
63 const std::size_t n = p.size();
64 const std::size_t h = m.size();
65 if (R.rows() < h || R.cols() != n)
66 throw InputError("cache_mva_miss: R must be at least (h x n)");
67
68 const T zero = num_traits<T>::from_int(0);
69 const T one = num_traits<T>::from_int(1);
70
71 long mt = 0;
72 int mmin = 0;
73 bool first = true;
74 for (int v : m) {
75 mt += v;
76 if (first || v < mmin) mmin = v;
77 first = false;
78 }
79
81 if (mt == 0 || mmin < 0) {
82 r.Mk.assign(n, one);
83 r.M = zero;
84 for (std::size_t k = 0; k < n; ++k) r.M += p[k];
85 return r;
86 }
87
88 Matrix<T> w(n, h, zero);
89 for (std::size_t j = 0; j < h; ++j) {
90 std::vector<int> mj = m;
91 mj[j] -= 1;
92 const CacheMvaMissResult<T> rec = cache_mva_miss(p, mj, R);
93 for (std::size_t k = 0; k < n; ++k) {
94 T prod = one;
95 for (std::size_t i = 0; i <= j; ++i) prod *= R(i, k);
96 w(k, j) = prod * num_pow_int(p[k], static_cast<unsigned>(j + 1)) * num_abs(rec.Mk[k]);
97 }
98 }
99
100 std::vector<T> x(h, zero);
101 for (std::size_t j = 0; j < h; ++j) {
102 T s = zero;
103 for (std::size_t k = 0; k < n; ++k) s += num_abs(w(k, j));
104 if (s == zero)
105 throw NumericError("cache_mva_miss: list has zero total weight, x is undefined");
106 x[j] = one / s;
107 }
108
109 r.Mk.assign(n, zero);
110 r.M = zero;
111 for (std::size_t k = 0; k < n; ++k) {
112 T v = one;
113 for (std::size_t j = 0; j < h; ++j)
114 v -= x[j] * num_traits<T>::from_int(static_cast<long>(m[j])) * w(k, j);
115 r.Mk[k] = num_abs(v);
116 r.M += p[k] * r.Mk[k];
117 }
118 return r;
119}
120
121} // namespace cache
122} // namespace line
123
124#endif // LINE_API_CACHE_MVA_MISS_H
InputError(const std::string &what)
Definition error.h:39
std::size_t cols() const
Definition matrix.h:90
std::size_t rows() const
Definition matrix.h:89
NumericError(const std::string &what)
Definition error.h:45
The exception types the port throws.
Dense matrix and non-owning view.
CacheMvaMissResult< T > cache_mva_miss(const std::vector< T > &p, const std::vector< int > &m, const Matrix< T > &R)
Per-item and global cache miss probabilities by mean value analysis.
T num_abs(const T &v)
Definition number.h:172
T num_pow_int(const T &base, unsigned e)
Integer power, valid in any field (no transcendental requirement).
Definition number.h:192
Number-type abstraction for the templated API port.
Return value of cache_mva_miss, mirroring [M,Mk].
std::vector< T > Mk
(n) per-item miss probability
T M
global miss rate, sum_k p(k) Mk(k)