![]() |
LINE Solver (C++)
Templated C++ port of the LINE queueing solver
|
Refined mean field (RMF) miss rates of a multi-list RANDOM(m) cache. More...
#include <cstddef>#include <limits>#include <type_traits>#include <vector>#include "line/num/number.h"#include "line/util/error.h"#include "line/util/eig.h"#include "line/util/linalg.h"#include "line/util/lu.h"#include "line/util/matrix.h"#include "line/util/lsoda.h"#include "line/util/ode.h"Go to the source code of this file.
Classes | |
| struct | line::cache::CacheMissRmfResult< T > |
| Return value of cache_miss_rmf, mirroring [M,MU,MI,pi0,tout,pi0_t,MU_t,xtraj]. More... | |
| struct | line::cache::CacheRmfExpansionTransient< T > |
| Result of cache_miss_rmf_expansion_transient. More... | |
Namespaces | |
| namespace | line |
| namespace | line::cache |
Functions | |
| std::size_t | line::cache::cache_miss_rmf_index (std::size_t i, std::size_t k, std::size_t n_items) |
| Flat index of (item i, list k), k = 0 meaning "not cached" (rmf_index.m). | |
| template<class T> | |
| CacheMissRmfResult< T > | line::cache::cache_miss_rmf (const std::vector< T > &gamma, const std::vector< int > &m_in, const Matrix< T > &lambda, const T &tmax, const std::vector< std::vector< Matrix< T > > > &accost) |
| Refined mean-field miss rates of a RANDOM(m) multi-list cache. | |
| template<class T> | |
| CacheMissRmfResult< T > | line::cache::cache_miss_rmf (const std::vector< T > &gamma, const std::vector< int > &m_in, const Matrix< T > &lambda, const T &tmax) |
| cache_miss_rmf on the linear chain, i.e. | |
| template<class T> | |
| CacheMissRmfResult< T > | line::cache::cache_miss_rmf (const std::vector< T > &gamma, const std::vector< int > &m, const Matrix< T > &lambda) |
| cache_miss_rmf with the reference horizon tmax = 1e4. | |
| template<class T> | |
| CacheMissRmfResult< T > | line::cache::cache_miss_rmf_transient (const std::vector< int > &m_in, const Matrix< T > &lambda, const T &t0, const T &t1, const std::vector< T > &x0init) |
| Transient mean-field trajectory over [t0,t1] from a given initial occupancy, the optional TSPAN/X0INIT path of cache_miss_rmf.m. | |
| template<class T> | |
| CacheRmfExpansionTransient< T > | line::cache::cache_miss_rmf_expansion_transient (const std::vector< int > &m_in, const Matrix< T > &lambda, const T &time, std::size_t n_points, int order) |
| Refined mean-field TRANSIENT, CacheRMF.meanFieldExpansionTransient. | |
Refined mean field (RMF) miss rates of a multi-list RANDOM(m) cache.
Templated port of matlab/src/api/cache/cache_miss_rmf.m, including its nested rmf_drift, rmf_jacobian, rmf_hessian, rmf_noise_matrix, rmf_fixed_point, rmf_dimension_reduction and rmf_expansion_steady_state.
The model is a density dependent population process (DDPP) whose state x(i,k) is the probability that item i sits in list k, k = 0 meaning "not cached". A request for item i in list k promotes it to list k+1 and demotes a uniformly chosen occupant of list k+1, so the drift is
flow(i,k) = p(i) x(i,k) - hit(k) x(i,k+1) / m(k+1), dx(i,k)/dt -= flow(i,k), dx(i,k+1)/dt += flow(i,k), hit(k) = sum_j p(j) x(j,k),
for k = 0..h-1. The mean-field fixed point pi is the t -> infinity limit of that drift, and Gast's refinement adds the 1/N correction
E[X] = pi + V/N + O(1/N^2), V = -(F')^-1 (1/2) sum_{b,c} F''_{bc} W_bc,
with W the solution of the Lyapunov equation F' W + W F'^T + Q = 0 and Q the noise intensity of the DDPP. Reference: N. Gast, "Expected Values Estimated via Mean-Field Approximation are 1/N-Accurate", POMACS 2017.
WHAT UNBLOCKED THIS. The fixed point is reached by integrating the drift to t = 1e4, which MATLAB does with ode15s. The drift is stiff: the per-item request rates p(i) of a Zipf-like popularity profile span several orders of magnitude, so the fast items equilibrate in O(1/p_max) while the slow ones need O(1/p_min), and an explicit integrator would be pinned to the fast scale for the whole horizon. The port now has line/util/ode.h, an adaptive Rosenbrock-4 with an embedded lower-order estimate, and this file uses it. The Jacobian is supplied analytically (rmf_jacobian is needed for the refinement anyway), so the integrator never forms a numeric one here.
DIFFERENCES FROM THE REFERENCE. Three, all in the dimension reduction, and all forced by the same fact: the Jacobian of this drift is singular by construction (each item's occupancies are conserved, so the item-indicator vectors are exact left null vectors) and the refinement divides by its reduced version.
MEASURED AGREEMENT (MATLAB R2025a, T = double), global miss rate M:
lambda = [0.5 0.3 0.15 0.05; 0.1 0.2 0.3 0.4] (2 users, 4 items) m = [2] MATLAB 0.992377021789716 port 0.992377021789764 5e-14 m = [1 2] MATLAB 0.490863272756674 port 0.490863283075726 2.1e-8 lambda = [49 49 49 49 7 1 1]/205 (1 user, 7 items) m = [1 1 3] MATLAB 0.024017720168154 port 0.024017720912976 3.1e-8 m = [3] MATLAB 0.348362022568998 port 0.345660745093153 7.8e-3
The last row is not a discrepancy in the arithmetic but in which answer is returned: on that case the reference's refinement produces non-finite entries and cache_miss_rmf.m silently keeps the plain mean-field fixed point (its value agrees with the port's unrefined value to 1e-9), whereas the port's rank decision leaves the reduced Jacobian non-singular and the 1/N correction is applied, moving the miss rate by 0.8 percent. The result's refined flag says which of the two happened, so the caller can tell.
When the reduced Jacobian is singular – a small or non-hyperbolic fixed point – MATLAB's linear solves emit a warning and return non-finite entries, which cache_miss_rmf.m detects and discards, keeping the plain mean-field fixed point. The port raises NumericError from the same solves and catches it in the same place, with the same outcome; the result carries a refined flag saying which of the two was used, which the reference does not expose.
ARITHMETIC. Gated: the fixed point is reached by a tolerance-driven integration, so it is an approximation in any arithmetic.
COST. The Hessian is a dense model_dim^3 tensor and the Lyapunov solve is a dense rk^2 by rk^2 system, exactly as in the reference. With n items and h lists model_dim = n(h+1), so the refinement is practical for tens of items and quickly stops being so; the plain mean-field path has no such limit.
Definition in file cache_miss_rmf.h.