Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

osd/PGPool::update: optimize with subset_of #17820

Merged
merged 2 commits into from
Sep 28, 2017

Commits on Sep 27, 2017

  1. inverval_set: optimize subset_of with sequential search

    Optimize subset_of to use sequential search when it
    performs better than the lower_bound method, for set
    size ratios smaller than 10. This is analogous to
    intersection_of behavior since commit 825470f.
    
    The subset_of method can be used in some cases as a
    less-expensive alternative to the intersection_of
    method, since subset_of can return early if any element
    of the smaller set is not contained in the larger set,
    and intersection_of has the added burden of storing
    the intersecting elements.
    
    Signed-off-by: Zac Medico <zmedico@gmail.com>
    zmedico committed Sep 27, 2017
    Configuration menu
    Copy the full SHA
    5c37758 View commit details
    Browse the repository at this point in the history
  2. 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>
    zmedico committed Sep 27, 2017
    Configuration menu
    Copy the full SHA
    18cbba4 View commit details
    Browse the repository at this point in the history