Skip to content

Commit c80aecc

Browse files
committed
txgraph: Avoid per-group vectors for clusters & dependencies (optimization)
Instead construct a single vector with the list of all clusters in all groups, and then store per-group offset/range in that list. For dependencies, reuse m_deps_to_add, and store offset/range into that.
1 parent ee57e93 commit c80aecc

File tree

1 file changed

+45
-18
lines changed

1 file changed

+45
-18
lines changed

src/txgraph.cpp

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,23 @@ class TxGraphImpl final : public TxGraph
164164
/** Information about one group of Clusters to be merged. */
165165
struct GroupEntry
166166
{
167-
/** Which clusters are to be merged. */
168-
std::vector<Cluster*> m_clusters;
169-
/** Which dependencies are to be applied to those merged clusters, as (parent, child)
170-
* pairs. */
171-
std::vector<std::pair<GraphIndex, GraphIndex>> m_deps;
167+
/** Where the clusters to be merged start in m_group_clusters. */
168+
uint32_t m_cluster_offset;
169+
/** How many clusters to merge. */
170+
uint32_t m_cluster_count;
171+
/** Where the dependencies for this cluster group in m_deps_to_add start. */
172+
uint32_t m_deps_offset;
173+
/** How many dependencies to add. */
174+
uint32_t m_deps_count;
175+
};
176+
177+
/** Information about all groups of Clusters to be merged. */
178+
struct GroupData
179+
{
180+
/** The groups of Clusters to be merged. */
181+
std::vector<GroupEntry> m_groups;
182+
/** Which clusters are to be merged. GroupEntry::m_cluster_offset indexes into this. */
183+
std::vector<Cluster*> m_group_clusters;
172184
};
173185

174186
/** The vectors of clusters, one vector per quality level. ClusterSetIndex indexes into each. */
@@ -179,7 +191,7 @@ class TxGraphImpl final : public TxGraph
179191
* into this. */
180192
std::vector<std::pair<GraphIndex, GraphIndex>> m_deps_to_add;
181193
/** Information about the merges to be performed, if known. */
182-
std::optional<std::vector<GroupEntry>> m_group_data = std::vector<GroupEntry>{};
194+
std::optional<GroupData> m_group_data = GroupData{};
183195
/** Total number of transactions in this graph (sum of all transaction counts in all Clusters).
184196
* */
185197
GraphIndex m_txcount{0};
@@ -796,24 +808,34 @@ void TxGraphImpl::GroupClusters() noexcept
796808
std::sort(an_deps.begin(), an_deps.end(), [](auto& a, auto& b) noexcept { return a.second < b.second; });
797809
std::sort(an_clusters.begin(), an_clusters.end(), [](auto& a, auto& b) noexcept { return a.second < b.second; });
798810

799-
// Translate the resulting cluster groups to the m_group_data structure.
800-
m_group_data = std::vector<GroupEntry>{};
811+
// Translate the resulting cluster groups to the m_group_data structure, and the dependencies
812+
// back to m_deps_to_add.
813+
m_group_data = GroupData{};
814+
m_group_data->m_group_clusters.reserve(an_clusters.size());
815+
m_deps_to_add.clear();
816+
m_deps_to_add.reserve(an_deps.size());
801817
auto an_deps_it = an_deps.begin();
802818
auto an_clusters_it = an_clusters.begin();
803819
while (an_clusters_it != an_clusters.end()) {
804820
// Process all clusters/dependencies belonging to the partition with representative rep.
805821
auto rep = an_clusters_it->second;
806822
// Create and initialize a new GroupData entry for the partition.
807-
auto& new_entry = m_group_data->emplace_back();
808-
// Add all its clusters to it (copying those from an_clusters to m_clusters).
823+
auto& new_entry = m_group_data->m_groups.emplace_back();
824+
new_entry.m_cluster_offset = m_group_data->m_group_clusters.size();
825+
new_entry.m_cluster_count = 0;
826+
new_entry.m_deps_offset = m_deps_to_add.size();
827+
new_entry.m_deps_count = 0;
828+
// Add all its clusters to it (copying those from an_clusters to m_group_clusters).
809829
while (an_clusters_it != an_clusters.end() && an_clusters_it->second == rep) {
810-
new_entry.m_clusters.push_back(an_clusters_it->first);
830+
m_group_data->m_group_clusters.push_back(an_clusters_it->first);
811831
++an_clusters_it;
832+
++new_entry.m_cluster_count;
812833
}
813-
// Add all its dependencies to it (copying those back from an_deps to m_deps).
834+
// Add all its dependencies to it (copying those back from an_deps to m_deps_to_add).
814835
while (an_deps_it != an_deps.end() && an_deps_it->second == rep) {
815-
new_entry.m_deps.push_back(an_deps_it->first);
836+
m_deps_to_add.push_back(an_deps_it->first);
816837
++an_deps_it;
838+
++new_entry.m_deps_count;
817839
}
818840
}
819841
Assume(an_deps_it == an_deps.end());
@@ -857,22 +879,27 @@ void TxGraphImpl::ApplyDependencies() noexcept
857879
if (m_deps_to_add.empty()) return;
858880

859881
// For each group of to-be-merged Clusters.
860-
for (auto& group_data : *m_group_data) {
882+
for (const auto& group_data : m_group_data->m_groups) {
861883
// Invoke Merge() to merge them into a single Cluster.
862-
Merge(group_data.m_clusters);
884+
auto cluster_span = std::span{m_group_data->m_group_clusters}
885+
.subspan(group_data.m_cluster_offset, group_data.m_cluster_count);
886+
Merge(cluster_span);
863887
// Actually apply all to-be-added dependencies (all parents and children from this grouping
864888
// belong to the same Cluster at this point because of the merging above).
865-
const auto& loc = m_entries[group_data.m_deps[0].second].m_locator;
889+
auto deps_span = std::span{m_deps_to_add}
890+
.subspan(group_data.m_deps_offset, group_data.m_deps_count);
891+
Assume(!deps_span.empty());
892+
const auto& loc = m_entries[deps_span[0].second].m_locator;
866893
Assume(loc.IsPresent());
867-
loc.cluster->ApplyDependencies(*this, group_data.m_deps);
894+
loc.cluster->ApplyDependencies(*this, deps_span);
868895
}
869896

870897
// Wipe the list of to-be-added dependencies now that they are applied.
871898
m_deps_to_add.clear();
872899
Compact();
873900
// Also no further Cluster mergings are needed (note that we clear, but don't set to
874901
// std::nullopt, as that would imply the groupings are unknown).
875-
m_group_data = std::vector<GroupEntry>{};
902+
m_group_data = GroupData{};
876903
}
877904

878905
void Cluster::Relinearize(TxGraphImpl& graph, uint64_t max_iters) noexcept

0 commit comments

Comments
 (0)