Skip to content

Commit

Permalink
osd/PGPool::update: optimize with subset_of
Browse files Browse the repository at this point in the history
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
zmedico committed Sep 22, 2017
1 parent f17f522 commit 710e253
Showing 1 changed file with 4 additions and 6 deletions.
10 changes: 4 additions & 6 deletions src/osd/PG.cc
Original file line number Diff line number Diff line change
Expand Up @@ -236,12 +236,10 @@ void PGPool::update(OSDMapRef map)
(pi->get_snap_epoch() == map->get_epoch())) {
updated = true;
pi->build_removed_snaps(newly_removed_snaps);
interval_set<snapid_t> intersection;
intersection.intersection_of(newly_removed_snaps, cached_removed_snaps);
if (intersection == cached_removed_snaps) {
cached_removed_snaps.swap(newly_removed_snaps);
newly_removed_snaps = cached_removed_snaps;
newly_removed_snaps.subtract(intersection);
if (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);
} else {
lgeneric_subdout(cct, osd, 0) << __func__
<< " cached_removed_snaps shrank from " << cached_removed_snaps
Expand Down

0 comments on commit 710e253

Please sign in to comment.