123 const std::vector<T>& lambda,
129 "retrieval_fpi_latency requires transcendental arithmetic: it is driven by "
130 "retrieval_fpi, a successive substitution stopped on a relative tolerance");
131 const std::size_t n = lambda.size();
132 const std::size_t S = station.size();
133 if (S == 0)
throw InputError(
"retrieval_fpi_latency: no retrieval station");
134 if (gamma.
rows() != n)
135 throw InputError(
"retrieval_fpi_latency: gamma and lambda disagree on the item count");
137 throw InputError(
"retrieval_fpi_latency: one routing matrix per item is required");
138 for (std::size_t i = 0; i < n; ++i)
139 if (R[i].rows() != S + 1 || R[i].cols() != S + 1)
140 throw InputError(
"retrieval_fpi_latency: routing matrices must be (S+1) x (S+1)");
142 std::vector<std::size_t> fsz(S);
143 for (std::size_t s = 0; s < S; ++s) {
144 fsz[s] = station[s].phases();
145 if (station[s].sub.
size() != n)
146 throw InputError(
"retrieval_fpi_latency: one subgenerator per item is required");
147 if (station[s].alpha.rows() != n)
148 throw InputError(
"retrieval_fpi_latency: alpha must have one row per item");
149 for (std::size_t i = 0; i < n; ++i)
150 if (station[s].sub[i].rows() != fsz[s] || station[s].sub[i].cols() != fsz[s])
151 throw InputError(
"retrieval_fpi_latency: subgenerator size disagrees with alpha");
157 "retrieval_fpi_latency: SIRO/FCFS retrieval stations require exponential "
158 "(single-phase) service");
163 for (std::size_t s = 0; s < S; ++s)
164 for (std::size_t i = 0; i < n; ++i) {
166 for (std::size_t k = 0; k < fsz[s]; ++k) arow(0, k) = station[s].alpha(i, k);
167 tau(i, s) = detail::ph_mean(arow, station[s].sub[i]);
171 for (std::size_t s = 0; s < S; ++s) {
175 double lo = 0.0, hi = 0.0;
176 for (std::size_t i = 0; i < n; ++i) {
178 if (i == 0 || x < lo) lo = x;
179 if (i == 0 || x > hi) hi = x;
181 if (hi - lo > 1e-9 * hi)
183 "retrieval_fpi_latency: SIRO/FCFS retrieval stations require class-independent "
184 "mean service rates");
188 std::vector<std::size_t> is_idx, ps_idx;
189 for (std::size_t s = 0; s < S; ++s) {
195 const std::size_t r = ps_idx.size();
199 for (std::size_t i = 0; i < n; ++i) {
201 for (std::size_t a = 0; a < S; ++a)
202 for (std::size_t b = 0; b < S; ++b)
207 for (std::size_t b = 0; b < S; ++b)
208 for (std::size_t a = 0; a < S; ++a) visits[b] += R[i](0, a + 1) * Vinv(a, b);
211 for (std::size_t s : is_idx) is_sum += visits[s] * tau(i, s);
213 for (std::size_t p = 0; p < r; ++p) eta(i, 1 + p) = visits[ps_idx[p]] * tau(i, ps_idx[p]);
221 for (std::size_t i = 0; i < n; ++i)
222 for (std::size_t s = 0; s <= r; ++s) out.
phi[i] += full.
pdh(s, i);
225 const std::size_t Phi = [&]() {
227 for (std::size_t s = 0; s < S; ++s) t += fsz[s];
230 std::vector<std::size_t> off(S, 0);
231 for (std::size_t s = 1; s < S; ++s) off[s] = off[s - 1] + fsz[s - 1];
233 for (std::size_t i = 0; i < n; ++i) {
244 for (std::size_t p = 0; p < r; ++p) {
246 for (std::size_t k = 0; k < n; ++k)
247 if (k != i) acc += full.
pdh(1 + p, k);
248 phitilde[ps_idx[p]] = acc;
254 for (std::size_t s = 0; s < S; ++s) {
260 for (std::size_t a = 0; a < fsz[s]; ++a)
261 for (std::size_t b = 0; b < fsz[s]; ++b) blk(a, b) = scale * station[s].sub[i](a, b);
262 for (std::size_t a = 0; a < fsz[s]; ++a)
263 for (std::size_t b = 0; b < fsz[s]; ++b) D0(off[s] + a, off[s] + b) += blk(a, b);
266 for (std::size_t a = 0; a < fsz[s]; ++a) {
268 for (std::size_t b = 0; b < fsz[s]; ++b) acc += blk(a, b);
271 for (std::size_t sp = 0; sp < S; ++sp)
272 for (std::size_t a = 0; a < fsz[s]; ++a)
273 for (std::size_t b = 0; b < fsz[sp]; ++b)
274 D0(off[s] + a, off[sp] + b) +=
275 compl_[a] * R[i](s + 1, sp + 1) * station[sp].alpha(i, b);
276 for (std::size_t a = 0; a < fsz[s]; ++a)
277 pe[off[s] + a] = R[i](0, s + 1) * station[s].alpha(i, a);
282 for (std::size_t a = 0; a < Phi; ++a)
283 for (std::size_t b = 0; b < Phi; ++b) A(a, b) = -D0(a, b);
285 const std::vector<std::size_t> piv =
lu_factor(LU);
288 std::vector<T> y2 = y;
291 for (std::size_t a = 0; a < Phi; ++a) {
303 for (std::size_t i = 0; i < n; ++i) {
304 num += out.
phi[i] + out.
d[i];
308 throw NumericError(
ErrorKind{
"Degenerate"},
"retrieval_fpi_latency: no read traffic, the latency is undefined");
RetrievalFpiLatencyResult< T > retrieval_fpi_latency(const std::vector< int > &m, const std::vector< T > &lambda, const Matrix< T > &gamma, const std::vector< RetrievalStationPH< T > > &station, const std::vector< Matrix< T > > &R, const FpiOptions &options=FpiOptions())
FPI-based approximation of the delayed-hit count and the expected latency of a list-based cache with ...