LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
cache_cost.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_COST_H
6#define LINE_API_CACHE_COST_H
7
8/**
9 * @file
10 * @ingroup api_cache
11 * Mean per-list storage cost of a cache with item sizes, and the screen for
12 * promotion paths that storage cost caps make unreachable.
13 *
14 * Templated port of matlab/src/api/cache/cache_cost.m and
15 * cache_cost_pathcheck.m, cross-checked against
16 * jar/src/main/java/jline/api/cache/Cache_cost.java and
17 * Cache_cost_pathcheck.java.
18 *
19 * K_j = sum_i sigma_i pi_ij is the expected storage cost of the items resident
20 * in list j at steady state (Casale-Gast, IEEE/ACM Trans. Networking 29(2),
21 * 2021, Sec. IX). Every operation is a field operation, so the exact
22 * instantiation returns K as a rational.
23 *
24 * The path check exists because E(m,k) sums over every size-feasible state
25 * while under RR-C(m) an item only reaches list j by being promoted one list
26 * at a time from the miss list: a cap on an intermediate list can leave
27 * size-feasible states unreachable, and E(m,k) then normalizes over states the
28 * cache never visits. An EMPTY report is a necessary, not sufficient,
29 * condition for the two sets to agree -- a list of capacity above one may
30 * still be unreachable when its cap admits no combination containing the item.
31 */
32
33#include <cstddef>
34#include <vector>
35
37#include "line/num/number.h"
38#include "line/util/error.h"
39#include "line/util/matrix.h"
40
41namespace line {
42namespace cache {
43
44/** One (item, list, blocking list) triple, all 0-based. */
46 std::size_t item;
47 std::size_t list;
48 std::size_t blocking_list;
49};
50
51/**
52 * @brief Mean per-list storage cost of a cache with item sizes, and the
53 * screen for promotion paths that storage cost caps make unreachable.
54 *
55 * @param gamma (n x h) access factors
56 * @param m (h) list capacities
57 * @param sigma (n) per-item storage costs
58 * @param k (h) per-list storage cost caps; empty for none
59 * @param pij (n x (h+1)) occupancy, column 0 the miss probability; empty to recompute
60 * @return (h) mean storage cost held by each list
61 */
62template <class T>
63std::vector<T> cache_cost(const Matrix<T>& gamma, const std::vector<int>& m,
64 const std::vector<int>& sigma, const std::vector<int>& k,
65 const Matrix<T>& pij) {
66 const std::size_t n = gamma.rows();
67 const std::size_t h = gamma.cols();
68 if (sigma.size() != n)
69 throw InputError("cache_cost: the item size vector must have one entry per item");
70 const Matrix<T> occ = pij.empty() ? cache_prob_erec(gamma, m, sigma, k) : pij;
71 std::vector<T> K(h, num_traits<T>::from_int(0));
72 for (std::size_t j = 0; j < h; ++j) {
74 for (std::size_t i = 0; i < n; ++i)
75 c += num_traits<T>::from_int(static_cast<long>(sigma[i])) * occ(i, j + 1);
76 K[j] = c;
77 }
78 return K;
79}
80
81template <class T>
82std::vector<T> cache_cost(const Matrix<T>& gamma, const std::vector<int>& m,
83 const std::vector<int>& sigma, const std::vector<int>& k) {
84 return cache_cost(gamma, m, sigma, k, Matrix<T>());
85}
86
87/**
88 * @param gamma (n x h) access factors
89 * @param sigma (n) per-item storage costs
90 * @param k (h) per-list storage cost caps
91 * @param parent (h) parent list of each list, 0-based, -1 for lists rooted in the miss list
92 * @return the blocked (item, list, blocking list) triples, empty when none
93 */
94template <class T>
95std::vector<CacheBlockedPair> cache_cost_pathcheck(const Matrix<T>& gamma,
96 const std::vector<int>& sigma,
97 const std::vector<int>& k,
98 const std::vector<int>& parent) {
99 const std::size_t n = gamma.rows();
100 const std::size_t h = gamma.cols();
101 std::vector<CacheBlockedPair> viol;
102 if (sigma.size() != n || k.size() != h || parent.size() != h) return viol;
103 for (std::size_t i = 0; i < n; ++i) {
104 for (std::size_t j = 0; j < h; ++j) {
105 if (gamma(i, j) == num_traits<T>::from_int(0) || sigma[i] > k[j])
106 continue; // item i never resides in list j anyway
107 int l = parent[j];
108 while (l >= 0) {
109 if (sigma[i] > k[static_cast<std::size_t>(l)]) {
111 p.item = i;
112 p.list = j;
113 p.blocking_list = static_cast<std::size_t>(l);
114 viol.push_back(p);
115 break;
116 }
117 l = parent[static_cast<std::size_t>(l)];
118 }
119 }
120 }
121 return viol;
122}
123
124} // namespace cache
125} // namespace line
126
127#endif // LINE_API_CACHE_COST_H
Exact per-item hit and miss probabilities of a multi-list cache.
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
bool empty() const
Definition matrix.h:92
The exception types the port throws.
Dense matrix and non-owning view.
std::vector< CacheBlockedPair > cache_cost_pathcheck(const Matrix< T > &gamma, const std::vector< int > &sigma, const std::vector< int > &k, const std::vector< int > &parent)
Definition cache_cost.h:95
std::vector< T > cache_cost(const Matrix< T > &gamma, const std::vector< int > &m, const std::vector< int > &sigma, const std::vector< int > &k, const Matrix< T > &pij)
Mean per-list storage cost of a cache with item sizes, and the screen for promotion paths that storag...
Definition cache_cost.h:63
Matrix< T > cache_prob_erec(const Matrix< T > &gamma, const std::vector< int > &m, const std::vector< int > &sigma, const std::vector< int > &k)
Per-item hit and miss probabilities under per-list storage cost caps, pi_ij = m_j gamma(i,...
Number-type abstraction for the templated API port.
One (item, list, blocking list) triple, all 0-based.
Definition cache_cost.h:45