Skip to content

Commit

Permalink
MB-48506: Introduce CheckpointBench.ExtractItemsToExpel
Browse files Browse the repository at this point in the history
Extracting the items to expel is the part of the logic the executes
under CM::queueLock. That's what the new bench measures.
The bench serves a double purpose:
 (1) Measuring the runtime of expel at various expel-count
 (2) Showing the asymptotic behaviour of our code, currently linear

Both metrics will be improved in following patches and we'll use this
bench for tracking results.

Note: ExtractItemsToExpel/1 is quite noisy and not really
representative of any real workload, but it's reported for (2).

$ ./ep_engine_benchmarks --benchmark_filter="ExtractItemsToExpel" --benchmark_repetitions=10
Running ./ep_engine_benchmarks
Run on (24 X 2239.57 MHz CPU s)
CPU Caches:
  L1 Data 32 KiB (x12)
  L1 Instruction 32 KiB (x12)
  L2 Unified 256 KiB (x12)
  L3 Unified 15360 KiB (x2)
--------------------------------------------------------------------------------------------------------
Benchmark                                                              Time             CPU   Iterations
--------------------------------------------------------------------------------------------------------

CheckpointBench/ExtractItemsToExpel/1/iterations:1_mean             9937 ns         9509 ns           10
CheckpointBench/ExtractItemsToExpel/1/iterations:1_median           9298 ns         7990 ns           10
CheckpointBench/ExtractItemsToExpel/1/iterations:1_stddev           2274 ns         4017 ns           10
CheckpointBench/ExtractItemsToExpel/1/iterations:1_cv              22.89 %         42.24 %            10

CheckpointBench/ExtractItemsToExpel/10/iterations:1_mean           11802 ns        10504 ns           10
CheckpointBench/ExtractItemsToExpel/10/iterations:1_median         11627 ns        10359 ns           10
CheckpointBench/ExtractItemsToExpel/10/iterations:1_stddev           523 ns          498 ns           10
CheckpointBench/ExtractItemsToExpel/10/iterations:1_cv              4.43 %          4.74 %            10

CheckpointBench/ExtractItemsToExpel/100/iterations:1_mean          33975 ns        32624 ns           10
CheckpointBench/ExtractItemsToExpel/100/iterations:1_median        33963 ns        32630 ns           10
CheckpointBench/ExtractItemsToExpel/100/iterations:1_stddev          962 ns          908 ns           10
CheckpointBench/ExtractItemsToExpel/100/iterations:1_cv             2.83 %          2.78 %            10

CheckpointBench/ExtractItemsToExpel/1000/iterations:1_mean        305137 ns       303309 ns           10
CheckpointBench/ExtractItemsToExpel/1000/iterations:1_median      299253 ns       297779 ns           10
CheckpointBench/ExtractItemsToExpel/1000/iterations:1_stddev       15277 ns        15124 ns           10
CheckpointBench/ExtractItemsToExpel/1000/iterations:1_cv            5.01 %          4.99 %            10

CheckpointBench/ExtractItemsToExpel/10000/iterations:1_mean      3285609 ns      3282457 ns           10
CheckpointBench/ExtractItemsToExpel/10000/iterations:1_median    3293980 ns      3291032 ns           10
CheckpointBench/ExtractItemsToExpel/10000/iterations:1_stddev      98379 ns        98295 ns           10
CheckpointBench/ExtractItemsToExpel/10000/iterations:1_cv           2.99 %          2.99 %            10

Change-Id: I14513f24699efb5a5885a74310a1f1b2e9fdc105
Reviewed-on: http://review.couchbase.org/c/kv_engine/+/161771
Tested-by: Build Bot <build@couchbase.com>
Reviewed-by: Dave Rigby <daver@couchbase.com>
  • Loading branch information
paolococchi committed Sep 29, 2021
1 parent 313bb92 commit 0d74bf6
Showing 1 changed file with 87 additions and 19 deletions.
106 changes: 87 additions & 19 deletions engines/ep/benchmarks/vbucket_bench.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,17 @@ class CheckpointBench : public EngineFixture {
}

/**
* Creates the given number of checkpoints in CM and moves cursor to the
* open checkpoint.
* Loads the given number of items in CM and moves cursor to the end of the
* open checkpoint queue.
*
* @param numCheckpoints
* @param numItems
* @param valueSize
*/
void createCheckpointsAndMoveCursor(size_t numCheckpoints);
void loadItemsAndMoveCursor(size_t numItems, size_t valueSize);

CheckpointList extractClosedUnrefCheckpoints(CheckpointManager&);

std::pair<CheckpointQueue, size_t> extractItemsToExpel(CheckpointManager&);
};

/**
Expand Down Expand Up @@ -436,34 +439,39 @@ CheckpointList CheckpointBench::extractClosedUnrefCheckpoints(
return manager.extractClosedUnrefCheckpoints(lh);
}

void CheckpointBench::createCheckpointsAndMoveCursor(size_t numCheckpoints) {
std::pair<CheckpointQueue, size_t> CheckpointBench::extractItemsToExpel(
CheckpointManager& manager) {
std::lock_guard<std::mutex> lh(manager.queueLock);
return manager.extractItemsToExpel(lh);
}

void CheckpointBench::loadItemsAndMoveCursor(size_t numItems,
size_t valueSize) {
auto& vb = *engine->getKVBucket()->getVBucket(vbid);
auto& manager = *vb.checkpointManager;

// Clean up everything and start from scat every iteration
manager.clear(0 /*seqno*/);
ASSERT_EQ(0, manager.getHighSeqno());
ASSERT_EQ(1, manager.getNumItems());

// Note: Testclass sets chk_max_items=1, load N items will end up with
// N checkpoints
for (size_t i = 0; i < numCheckpoints; ++i) {
const std::string value(valueSize, 'x');
for (size_t i = 0; i < numItems; ++i) {
queued_item item{
new Item(StoredDocKey(std::string("key") + std::to_string(i),
CollectionID::Default),
vbid,
queue_op::mutation,
0 /*revSeqno*/,
0 /*bySeqno*/)};
0,
0,
value.c_str(),
value.size(),
PROTOCOL_BINARY_RAW_BYTES)};
item->setVBucketId(vbid);
item->setQueuedTime();
EXPECT_TRUE(manager.queueDirty(
item, GenerateBySeqno::Yes, GenerateCas::Yes, nullptr));
}
ASSERT_EQ(numCheckpoints, manager.getNumCheckpoints());
ASSERT_EQ(numCheckpoints, manager.getHighSeqno());
ASSERT_GT(manager.getNumItems(), numCheckpoints);
ASSERT_EQ(numItems, manager.getHighSeqno());

// Make all closed checkpoints eligible for removal
// Make all possible items eligible for removal
flushAllItems(vbid);
}

Expand All @@ -487,9 +495,13 @@ BENCHMARK_DEFINE_F(CheckpointBench, ExtractClosedUnrefCheckpoints)
const size_t numCheckpoints = state.range(0);
auto& manager = *engine->getKVBucket()->getVBucket(vbid)->checkpointManager;

ASSERT_EQ(1, manager.getCheckpointConfig().getCheckpointMaxItems());

while (state.KeepRunning()) {
state.PauseTiming();
createCheckpointsAndMoveCursor(numCheckpoints);

loadItemsAndMoveCursor(numCheckpoints, 0);
ASSERT_EQ(numCheckpoints, manager.getNumCheckpoints());

// Benchmark
{
Expand Down Expand Up @@ -518,9 +530,13 @@ BENCHMARK_DEFINE_F(CheckpointBench, GetCursorsToDrop)
const size_t numCheckpoints = state.range(0);
auto& manager = *engine->getKVBucket()->getVBucket(vbid)->checkpointManager;

ASSERT_EQ(1, manager.getCheckpointConfig().getCheckpointMaxItems());

while (state.KeepRunning()) {
state.PauseTiming();
createCheckpointsAndMoveCursor(numCheckpoints);

loadItemsAndMoveCursor(numCheckpoints, 0);
ASSERT_EQ(numCheckpoints, manager.getNumCheckpoints());

// Benchmark
{
Expand All @@ -537,6 +553,49 @@ BENCHMARK_DEFINE_F(CheckpointBench, GetCursorsToDrop)
}
}

BENCHMARK_DEFINE_F(CheckpointBench, ExtractItemsToExpel)
(benchmark::State& state) {
const size_t numItems = state.range(0);

// Ensure all items in the open checkpoint - avoid checkpoint creation
ASSERT_LE(numItems, MAX_CHECKPOINT_ITEMS);
auto& config = engine->getConfiguration();
const size_t _1B = 1000 * 1000 * 1000;
config.setCheckpointMaxSize(_1B);
config.setChkMaxItems(MAX_CHECKPOINT_ITEMS);
config.setChkPeriod(MAX_CHECKPOINT_PERIOD);

auto& bucket = *engine->getKVBucket();
auto& manager = *bucket.getVBucket(vbid)->checkpointManager;
const auto& ckptConfig = manager.getCheckpointConfig();
ASSERT_EQ(_1B, bucket.getCheckpointMaxSize());
ASSERT_EQ(MAX_CHECKPOINT_ITEMS, ckptConfig.getCheckpointMaxItems());
ASSERT_EQ(MAX_CHECKPOINT_PERIOD, ckptConfig.getCheckpointPeriod());

while (state.KeepRunning()) {
state.PauseTiming();

// High-seqno never expelled, so load numItems+1 for expelling numItems
loadItemsAndMoveCursor(numItems + 1, 1024);
ASSERT_EQ(1, manager.getNumCheckpoints());

// Benchmark
{
state.ResumeTiming();
const auto res = extractItemsToExpel(manager);
// Don't account deallocation, so pause before res goes out of scope
state.PauseTiming();

EXPECT_EQ(numItems, res.first.size());
EXPECT_GT(res.second, 0);
}

// Need to resume here, gbench will fail when it's time to exit the
// loop otherwise.
state.ResumeTiming();
}
}

// Run with couchstore backend(0); item counts from 1..10,000,000
BENCHMARK_REGISTER_F(MemTrackingVBucketBench, QueueDirty)
->Args({0, 1})
Expand Down Expand Up @@ -614,6 +673,15 @@ BENCHMARK_REGISTER_F(CheckpointBench, ExtractClosedUnrefCheckpoints)

// Arguments: numCheckpoints
BENCHMARK_REGISTER_F(CheckpointBench, GetCursorsToDrop)
->Args({1})
->Args({10})
->Args({100})
->Args({1000})
->Args({10000})
->Iterations(1);

// Arguments: numItems
BENCHMARK_REGISTER_F(CheckpointBench, ExtractItemsToExpel)
->Args({1})
->Args({10})
->Args({100})
Expand Down

0 comments on commit 0d74bf6

Please sign in to comment.