From 3cc3060481bc8b136854d863c662398b41e5f46b Mon Sep 17 00:00:00 2001 From: Ivan Morozko Date: Sat, 5 Oct 2024 21:40:20 +0400 Subject: [PATCH] Optimize clues by moving allocations out of Build* methods --- .../dc/FastADC/util/clue_set_builder.h | 21 ++++++++++++++----- .../dc/FastADC/util/common_clue_set_builder.h | 6 ++---- .../FastADC/util/cross_clue_set_builder.cpp | 10 +++++---- .../dc/FastADC/util/cross_clue_set_builder.h | 3 ++- .../FastADC/util/single_clue_set_builder.cpp | 9 ++++---- .../dc/FastADC/util/single_clue_set_builder.h | 2 +- 6 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/core/algorithms/dc/FastADC/util/clue_set_builder.h b/src/core/algorithms/dc/FastADC/util/clue_set_builder.h index 4670dea360..be13525834 100644 --- a/src/core/algorithms/dc/FastADC/util/clue_set_builder.h +++ b/src/core/algorithms/dc/FastADC/util/clue_set_builder.h @@ -9,18 +9,29 @@ namespace algos::fastadc { inline ClueSet BuildClueSet(std::vector const& pliShards, PredicatePacks const& packs) { ClueSet clue_set; + ClueSet partial_clue_set; size_t task_count = (pliShards.size() * (pliShards.size() + 1)) / 2; LOG(DEBUG) << " [CLUE] task count: " << task_count; + // Range of all pliShards is equal, so it's safe to pass a pre-allocated vector of + // pliShards[0]'s range + size_t range = pliShards[0].Range(); + size_t evidence_count = range * range; + + clue_set.reserve(range * 2); + partial_clue_set.reserve(range * 2); + + std::vector forward_clues(evidence_count, 0); + std::vector reverse_clues(evidence_count, 0); + for (size_t i = 0; i < pliShards.size(); i++) { for (size_t j = i; j < pliShards.size(); j++) { - ClueSet partial_clue_set; - if (i == j) { - partial_clue_set = SingleClueSetBuilder{pliShards[i]}.BuildClueSet(packs); + SingleClueSetBuilder{pliShards[i]}.BuildClueSet(packs, forward_clues, + partial_clue_set); } else { - partial_clue_set = - CrossClueSetBuilder{pliShards[i], pliShards[j]}.BuildClueSet(packs); + CrossClueSetBuilder{pliShards[i], pliShards[j]}.BuildClueSet( + packs, forward_clues, reverse_clues, partial_clue_set); } for (auto const& [clue, count] : partial_clue_set) { diff --git a/src/core/algorithms/dc/FastADC/util/common_clue_set_builder.h b/src/core/algorithms/dc/FastADC/util/common_clue_set_builder.h index 2b5f94a49a..8f05b0430e 100644 --- a/src/core/algorithms/dc/FastADC/util/common_clue_set_builder.h +++ b/src/core/algorithms/dc/FastADC/util/common_clue_set_builder.h @@ -31,12 +31,10 @@ inline ClueSet AccumulateClues(Vectors const&... vectors) { } #else template -ClueSet AccumulateClues(Vectors const&... vectors) { - ClueSet clue_set; +ClueSet AccumulateClues(ClueSet& clue_set, Vectors const&... vectors) { + clue_set.clear(); int64_t clue_zero_count = 0; - clue_set.reserve((vectors.size() + ...)); - auto insert_clues = [&](std::vector const& clues) { for (auto const& clue : clues) { if (clue.none()) { diff --git a/src/core/algorithms/dc/FastADC/util/cross_clue_set_builder.cpp b/src/core/algorithms/dc/FastADC/util/cross_clue_set_builder.cpp index f873eaa324..e2c1f55279 100644 --- a/src/core/algorithms/dc/FastADC/util/cross_clue_set_builder.cpp +++ b/src/core/algorithms/dc/FastADC/util/cross_clue_set_builder.cpp @@ -5,9 +5,11 @@ namespace algos::fastadc { CrossClueSetBuilder::CrossClueSetBuilder(PliShard const& shard1, PliShard const& shard2) : plis1_(shard1.plis), plis2_(shard2.plis), evidence_count_(shard1.Range() * shard2.Range()) {} -ClueSet CrossClueSetBuilder::BuildClueSet(PredicatePacks const& packs) { - std::vector forward_clues(evidence_count_, 0); - std::vector reverse_clues(evidence_count_, 0); +void CrossClueSetBuilder::BuildClueSet(PredicatePacks const& packs, + std::vector& forward_clues, + std::vector& reverse_clues, ClueSet& clue_set) { + forward_clues.assign(evidence_count_, Clue()); + reverse_clues.assign(evidence_count_, Clue()); for (auto const& cat_pack : packs.str_single) { CorrectStrSingle(forward_clues, reverse_clues, plis1_[cat_pack.left_idx], @@ -33,7 +35,7 @@ ClueSet CrossClueSetBuilder::BuildClueSet(PredicatePacks const& packs) { num_pack.eq_mask, num_pack.gt_mask); } - return AccumulateClues(forward_clues, reverse_clues); + AccumulateClues(clue_set, forward_clues, reverse_clues); } void CrossClueSetBuilder::SetSingleEQ(std::vector& clues1, std::vector& clues2, diff --git a/src/core/algorithms/dc/FastADC/util/cross_clue_set_builder.h b/src/core/algorithms/dc/FastADC/util/cross_clue_set_builder.h index 9350186344..81a891ca0b 100644 --- a/src/core/algorithms/dc/FastADC/util/cross_clue_set_builder.h +++ b/src/core/algorithms/dc/FastADC/util/cross_clue_set_builder.h @@ -15,7 +15,8 @@ class CrossClueSetBuilder { CrossClueSetBuilder(CrossClueSetBuilder&& other) noexcept = default; CrossClueSetBuilder& operator=(CrossClueSetBuilder&& other) noexcept = delete; - ClueSet BuildClueSet(PredicatePacks const& packs); + void BuildClueSet(PredicatePacks const& packs, std::vector& forward_clues, + std::vector& reverse_clues, ClueSet& clue_set); private: std::vector const& plis1_; diff --git a/src/core/algorithms/dc/FastADC/util/single_clue_set_builder.cpp b/src/core/algorithms/dc/FastADC/util/single_clue_set_builder.cpp index 417a86b98c..7eb52a1336 100644 --- a/src/core/algorithms/dc/FastADC/util/single_clue_set_builder.cpp +++ b/src/core/algorithms/dc/FastADC/util/single_clue_set_builder.cpp @@ -8,8 +8,9 @@ SingleClueSetBuilder::SingleClueSetBuilder(PliShard const& shard) tid_range_(shard.Range()), evidence_count_(tid_range_ * tid_range_) {} -ClueSet SingleClueSetBuilder::BuildClueSet(PredicatePacks const& packs) { - std::vector clues(evidence_count_, 0); +void SingleClueSetBuilder::BuildClueSet(PredicatePacks const& packs, std::vector& clues, + ClueSet& clue_set) { + clues.assign(evidence_count_, Clue()); for (auto const& cat_pack : packs.str_single) { CorrectStrSingle(clues, plis_[cat_pack.left_idx], cat_pack.eq_mask); @@ -29,14 +30,12 @@ ClueSet SingleClueSetBuilder::BuildClueSet(PredicatePacks const& packs) { num_pack.eq_mask, num_pack.gt_mask); } - ClueSet clue_set = AccumulateClues(clues); + AccumulateClues(clue_set, clues); // Reflex evidence check and removal: Clue reflex_clue{}; // All bits zero clue_set[reflex_clue] -= tid_range_; if (clue_set[reflex_clue] == 0) clue_set.erase(clue_set.find(reflex_clue)); - - return clue_set; } void SingleClueSetBuilder::SetSingleEQ(std::vector& clues, Pli::Cluster const& cluster, diff --git a/src/core/algorithms/dc/FastADC/util/single_clue_set_builder.h b/src/core/algorithms/dc/FastADC/util/single_clue_set_builder.h index b22135f26d..f82410dad7 100644 --- a/src/core/algorithms/dc/FastADC/util/single_clue_set_builder.h +++ b/src/core/algorithms/dc/FastADC/util/single_clue_set_builder.h @@ -18,7 +18,7 @@ class SingleClueSetBuilder { SingleClueSetBuilder(SingleClueSetBuilder&& other) noexcept = default; SingleClueSetBuilder& operator=(SingleClueSetBuilder&& other) noexcept = delete; - ClueSet BuildClueSet(PredicatePacks const& packs); + void BuildClueSet(PredicatePacks const& packs, std::vector& clues, ClueSet& clue_set); private: std::vector const& plis_;