Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
osd/PGPool::update: optimize with subset_of
Replace expensive inverval_set intersection_of and operator== calls with a single subset_of call. I borrowed this idea from Piotr Dałek's "osd/PGPool: don't use intermediate interval set" patch. The following benchmark program demonstrates a 38% performance increase: #include <iostream> #include <chrono> #include "include/interval_set.h" #define NANOSECONDS(d) \ std::chrono::duration_cast<std::chrono::nanoseconds>(d).count() typedef uint64_t snapid_t; typedef std::chrono::steady_clock::duration duration; duration PGPool_update_old(const interval_set<snapid_t> &rs) { std::chrono::steady_clock::time_point start, end; interval_set<snapid_t> newly_removed_snaps, cached_removed_snaps; // initialize state cached_removed_snaps = rs; // start timed simulation start = std::chrono::steady_clock::now(); { newly_removed_snaps = cached_removed_snaps; interval_set<snapid_t> intersection; intersection.intersection_of(newly_removed_snaps, cached_removed_snaps); assert(intersection == cached_removed_snaps); cached_removed_snaps.swap(newly_removed_snaps); newly_removed_snaps = cached_removed_snaps; newly_removed_snaps.subtract(intersection); } // end timed simulation end = std::chrono::steady_clock::now(); return end - start; } duration PGPool_update_new(const interval_set<snapid_t> &rs) { std::chrono::steady_clock::time_point start, end; interval_set<snapid_t> newly_removed_snaps, cached_removed_snaps; // initialize state cached_removed_snaps = rs; // start timed simulation start = std::chrono::steady_clock::now(); { newly_removed_snaps = cached_removed_snaps; assert(cached_removed_snaps.subset_of(newly_removed_snaps)); interval_set<snapid_t> removed_snaps = newly_removed_snaps; newly_removed_snaps.subtract(cached_removed_snaps); cached_removed_snaps.swap(removed_snaps); } // end timed simulation end = std::chrono::steady_clock::now(); return end - start; } int main(int argc, char *argv[]) { assert(argc == 3); const int sample_count = std::stoi(argv[1]); const int interval_count = std::stoi(argv[2]); const int interval_distance = 4; const int interval_size = 2; const int max_offset = interval_count * interval_distance; interval_set<snapid_t> removed_snaps; for (int i = 0; i < max_offset; i += interval_distance) removed_snaps.insert(i, interval_size); duration old_delta(0), new_delta(0); for (int i = 0; i < sample_count; ++i) { old_delta += PGPool_update_old(removed_snaps); new_delta += PGPool_update_new(removed_snaps); } float ratio = float(NANOSECONDS(old_delta)) / NANOSECONDS(new_delta); std::cout << ratio << std::endl; } Suggested-by: Piotr Dałek <piotr.dalek@corp.ovh.com> Signed-off-by: Zac Medico <zmedico@gmail.com>
- Loading branch information