From 39e7a9252ce140883ffc9798341ef85493a5320e Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 23 Jan 2024 01:30:39 +0000 Subject: [PATCH] Link graph: Use non-sparse matrix for accumulating demand totals --- src/linkgraph/demands.cpp | 40 +++++++++++++++++++++--------------- src/linkgraph/linkgraphjob.h | 3 ++- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/linkgraph/demands.cpp b/src/linkgraph/demands.cpp index 6c6c77408b..1ea8a547ad 100644 --- a/src/linkgraph/demands.cpp +++ b/src/linkgraph/demands.cpp @@ -244,8 +244,13 @@ void AsymmetricScalerEq::SetDemands(LinkGraphJob &job, NodeID from_id, NodeID to */ inline void Scaler::SetDemands(LinkGraphJob &job, NodeID from_id, NodeID to_id, uint demand_forw) { + if (demand_forw == 0) return; + job[from_id].DeliverSupply(demand_forw); - job.demand_map[std::make_pair(from_id, to_id)] += demand_forw; + + uint &demand = job.demand_matrix[(from_id * job.Size()) + to_id]; + if (demand == 0) job.demand_matrix_count++; + demand += demand_forw; } /** @@ -437,6 +442,8 @@ DemandCalculator::DemandCalculator(LinkGraphJob &job) : } uint first_unseen = 0; std::vector reachable_nodes(size); + job.demand_matrix.reset(new uint[size * size]{}); + job.demand_matrix_count = 0; do { reachable_nodes.assign(size, false); std::vector queue; @@ -480,24 +487,23 @@ DemandCalculator::DemandCalculator(LinkGraphJob &job) : } } while (first_unseen < size); - if (job.demand_map.size() > 0) { - job.demand_annotation_store.resize(job.demand_map.size()); - size_t start_idx = 0; + if (job.demand_matrix_count > 0) { + job.demand_annotation_store.resize(job.demand_matrix_count); size_t idx = 0; - NodeID last_from = job.demand_map.begin()->first.first; - auto flush = [&]() { - job[last_from].SetDemandAnnotations({ job.demand_annotation_store.data() + start_idx, idx - start_idx }); - }; - for (auto &iter : job.demand_map) { - if (iter.first.first != last_from) { - flush(); - last_from = iter.first.first; - start_idx = idx; + const uint *demand = job.demand_matrix.get(); + for (NodeID from = 0; from != size; from++) { + const size_t start_idx = idx; + for (NodeID to = 0; to != size; to++) { + if (*demand != 0) { + job.demand_annotation_store[idx] = { to, *demand, *demand }; + idx++; + } + demand++; + } + if (idx != start_idx) { + job[from].SetDemandAnnotations({ job.demand_annotation_store.data() + start_idx, idx - start_idx }); } - job.demand_annotation_store[idx] = { iter.first.second, iter.second, iter.second }; - idx++; } - flush(); - job.demand_map.clear(); } + job.demand_matrix.reset(); } diff --git a/src/linkgraph/linkgraphjob.h b/src/linkgraph/linkgraphjob.h index 9db6eb6c33..b77209bfd0 100644 --- a/src/linkgraph/linkgraphjob.h +++ b/src/linkgraph/linkgraphjob.h @@ -152,7 +152,8 @@ protected: public: - btree::btree_map, uint> demand_map; ///< Demand map. + std::unique_ptr demand_matrix; ///< Demand matrix. + uint demand_matrix_count; ///< Count of non-zero entries in demand_matrix. std::vector demand_annotation_store; ///< Demand annotation store. DynUniformArenaAllocator path_allocator; ///< Arena allocator used for paths