Skip to content

Commit

Permalink
Add bitmap control for perf context (#237)
Browse files Browse the repository at this point in the history
* `PerfFlag` implementation aside the `PerfLevel`
design spec in on: https://docs.google.com/document/d/1JYmWMIZwYV0AZW6rNv_oFVZLBCAkxLLYslt39eEZstM/edit?usp=sharing

Signed-off-by: lemonhx <lemonhx@lemonhx.tech>
Co-authored-by: Xinye Tao <xy.tao@outlook.com>
Signed-off-by: tabokie <xy.tao@outlook.com>
  • Loading branch information
LemonHX and tabokie committed May 11, 2022
1 parent 5d01038 commit 2f1efc5
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 27 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,7 @@ set(SOURCES
monitoring/iostats_context.cc
monitoring/perf_context.cc
monitoring/perf_level.cc
monitoring/perf_flag.cc
monitoring/persistent_stats_history.cc
monitoring/statistics.cc
monitoring/thread_status_impl.cc
Expand Down
2 changes: 2 additions & 0 deletions TARGETS
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ cpp_library(
"monitoring/instrumented_mutex.cc",
"monitoring/iostats_context.cc",
"monitoring/perf_context.cc",
"monitoring/perf_flag.cc",
"monitoring/perf_level.cc",
"monitoring/persistent_stats_history.cc",
"monitoring/statistics.cc",
Expand Down Expand Up @@ -600,6 +601,7 @@ cpp_library(
"monitoring/instrumented_mutex.cc",
"monitoring/iostats_context.cc",
"monitoring/perf_context.cc",
"monitoring/perf_flag.cc",
"monitoring/perf_level.cc",
"monitoring/persistent_stats_history.cc",
"monitoring/statistics.cc",
Expand Down
12 changes: 12 additions & 0 deletions db/c.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "rocksdb/merge_operator.h"
#include "rocksdb/options.h"
#include "rocksdb/perf_context.h"
#include "rocksdb/perf_flag.h"
#include "rocksdb/rate_limiter.h"
#include "rocksdb/slice_transform.h"
#include "rocksdb/statistics.h"
Expand Down Expand Up @@ -57,6 +58,7 @@ using ROCKSDB_NAMESPACE::BlockBasedTableOptions;
using ROCKSDB_NAMESPACE::BottommostLevelCompaction;
using ROCKSDB_NAMESPACE::BytewiseComparator;
using ROCKSDB_NAMESPACE::Cache;
using ROCKSDB_NAMESPACE::CheckPerfFlag;
using ROCKSDB_NAMESPACE::Checkpoint;
using ROCKSDB_NAMESPACE::ColumnFamilyDescriptor;
using ROCKSDB_NAMESPACE::ColumnFamilyHandle;
Expand All @@ -71,6 +73,8 @@ using ROCKSDB_NAMESPACE::CuckooTableOptions;
using ROCKSDB_NAMESPACE::DB;
using ROCKSDB_NAMESPACE::DBOptions;
using ROCKSDB_NAMESPACE::DbPath;
using ROCKSDB_NAMESPACE::DisablePerfFlag;
using ROCKSDB_NAMESPACE::EnablePerfFlag;
using ROCKSDB_NAMESPACE::Env;
using ROCKSDB_NAMESPACE::EnvOptions;
using ROCKSDB_NAMESPACE::FileLock;
Expand Down Expand Up @@ -3586,6 +3590,14 @@ void rocksdb_set_perf_level(int v) {
SetPerfLevel(level);
}

void rocksdb_enable_perf_flag(uint64_t flag) { EnablePerfFlag(flag); }

void rocksdb_disable_perf_flag(uint64_t flag) { DisablePerfFlag(flag); }

int rocksdb_check_perf_flag(uint64_t flag) {
return static_cast<int>(CheckPerfFlag(flag));
}

rocksdb_perfcontext_t* rocksdb_perfcontext_create() {
rocksdb_perfcontext_t* context = new rocksdb_perfcontext_t;
context->rep = ROCKSDB_NAMESPACE::get_perf_context();
Expand Down
20 changes: 20 additions & 0 deletions db/perf_context_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,26 @@ TEST_F(PerfContextTest, CPUTimer) {
ASSERT_EQ(count, get_perf_context()->iter_seek_cpu_nanos);
}
}

TEST_F(PerfContextTest, BitMapControl) {
DestroyDB(kDbName, Options());
auto db = OpenDb();
WriteOptions write_options;
SetPerfLevel(PerfLevel::kDisable);
EnablePerfFlag(flag_user_key_comparison_count);
EnablePerfFlag(flag_write_wal_time);

for (int i = 0; i < FLAGS_total_keys; ++i) {
std::string i_str = ToString(i);
std::string key = "k" + i_str;
std::string value = "v" + i_str;

db->Put(write_options, key, value);
}
ASSERT_GT(get_perf_context()->user_key_comparison_count, 0);
ASSERT_GT(get_perf_context()->write_wal_time, 0);
}

} // namespace ROCKSDB_NAMESPACE

int main(int argc, char** argv) {
Expand Down
3 changes: 3 additions & 0 deletions include/rocksdb/c.h
Original file line number Diff line number Diff line change
Expand Up @@ -1543,6 +1543,9 @@ enum {
};

extern ROCKSDB_LIBRARY_API void rocksdb_set_perf_level(int);
extern ROCKSDB_LIBRARY_API void rocksdb_enable_perf_flag(uint64_t);
extern ROCKSDB_LIBRARY_API void rocksdb_disable_perf_flag(uint64_t);
extern ROCKSDB_LIBRARY_API int rocksdb_check_perf_flag(uint64_t);
extern ROCKSDB_LIBRARY_API rocksdb_perfcontext_t* rocksdb_perfcontext_create(
void);
extern ROCKSDB_LIBRARY_API void rocksdb_perfcontext_reset(
Expand Down
127 changes: 127 additions & 0 deletions include/rocksdb/perf_flag.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// complements to perf_level
#pragma once

#include <cstdint>

#include "rocksdb/rocksdb_namespace.h"

namespace ROCKSDB_NAMESPACE {

enum {
flag_user_key_comparison_count = 0,
flag_block_cache_hit_count,
flag_block_read_count,
flag_block_read_byte,
flag_block_read_time,
flag_block_cache_index_hit_count,
flag_index_block_read_count,
flag_block_cache_filter_hit_count,
flag_filter_block_read_count,
flag_compression_dict_block_read_count,
flag_secondary_cache_hit_count,
flag_block_checksum_time,
flag_block_decompress_time,
flag_get_read_bytes,
flag_multiget_read_bytes,
flag_iter_read_bytes,
flag_internal_key_skipped_count,
flag_internal_delete_skipped_count,
flag_internal_recent_skipped_count,
flag_internal_merge_count,
flag_get_snapshot_time,
flag_get_from_memtable_time,
flag_get_from_memtable_count,
flag_get_post_process_time,
flag_get_from_output_files_time,
flag_seek_on_memtable_time,
flag_seek_on_memtable_count,
flag_next_on_memtable_count,
flag_prev_on_memtable_count,
flag_seek_child_seek_time,
flag_seek_child_seek_count,
flag_seek_min_heap_time,
flag_seek_max_heap_time,
flag_seek_internal_seek_time,
flag_find_next_user_entry_time,
flag_write_wal_time,
flag_write_memtable_time,
flag_write_delay_time,
flag_write_scheduling_flushes_compactions_time,
flag_write_pre_and_post_process_time,
flag_write_thread_wait_nanos,
flag_db_mutex_lock_nanos,
flag_db_condition_wait_nanos,
flag_merge_operator_time_nanos,
flag_read_index_block_nanos,
flag_read_filter_block_nanos,
flag_new_table_block_iter_nanos,
flag_new_table_iterator_nanos,
flag_block_seek_nanos,
flag_find_table_nanos,
flag_bloom_memtable_hit_count,
flag_bloom_memtable_miss_count,
flag_bloom_sst_hit_count,
flag_bloom_sst_miss_count,
flag_key_lock_wait_time,
flag_key_lock_wait_count,
flag_env_new_sequential_file_nanos,
flag_env_new_random_access_file_nanos,
flag_env_new_writable_file_nanos,
flag_env_reuse_writable_file_nanos,
flag_env_new_random_rw_file_nanos,
flag_env_new_directory_nanos,
flag_env_file_exists_nanos,
flag_env_get_children_nanos,
flag_env_get_children_file_attributes_nanos,
flag_env_delete_file_nanos,
flag_env_create_dir_nanos,
flag_env_create_dir_if_missing_nanos,
flag_env_delete_dir_nanos,
flag_env_get_file_size_nanos,
flag_env_get_file_modification_time_nanos,
flag_env_rename_file_nanos,
flag_env_link_file_nanos,
flag_env_lock_file_nanos,
flag_env_unlock_file_nanos,
flag_env_new_logger_nanos,
flag_get_cpu_nanos,
flag_iter_next_cpu_nanos,
flag_iter_prev_cpu_nanos,
flag_iter_seek_cpu_nanos,
flag_encrypt_data_nanos,
flag_decrypt_data_nanos,

flag_get_from_table_nanos,
flag_user_key_return_count,
flag_block_cache_miss_count,
flag_bloom_filter_full_positive,
flag_bloom_filter_useful,
flag_bloom_filter_full_true_positive,

flag_bytes_read,
flag_bytes_written,
flag_open_nanos,
flag_allocate_nanos,
flag_write_nanos,
flag_read_nanos,
flag_range_sync_nanos,
flag_prepare_write_nanos,
flag_fsync_nanos,
flag_logger_nanos,
flag_cpu_read_nanos,
flag_cpu_write_nanos,
// Should always be the last
FLAG_END
};

// FLAGS_LEN = ceiling(FLAG_END / bits(uint8_t))
#define FLAGS_LEN \
(((uint64_t)FLAG_END & (uint64_t)0b111) == 0 \
? ((uint64_t)FLAG_END >> 3) \
: ((uint64_t)FLAG_END >> 3) + 1)

void EnablePerfFlag(uint64_t flag);
void DisablePerfFlag(uint64_t flag);
bool CheckPerfFlag(uint64_t flag);

} // namespace ROCKSDB_NAMESPACE
13 changes: 7 additions & 6 deletions monitoring/iostats_context_imp.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,16 @@ extern __thread IOStatsContext iostats_context;
#define IOSTATS(metric) (iostats_context.metric)

// Declare and set start time of the timer
#define IOSTATS_TIMER_GUARD(metric) \
PerfStepTimer iostats_step_timer_##metric(&(iostats_context.metric)); \
#define IOSTATS_TIMER_GUARD(metric) \
PerfStepTimer iostats_step_timer_##metric(&(iostats_context.metric), \
CheckPerfFlag(flag_##metric)); \
iostats_step_timer_##metric.Start();

// Declare and set start time of the timer
#define IOSTATS_CPU_TIMER_GUARD(metric, clock) \
PerfStepTimer iostats_step_timer_##metric( \
&(iostats_context.metric), clock, true, \
PerfLevel::kEnableTimeAndCPUTimeExceptForMutex); \
#define IOSTATS_CPU_TIMER_GUARD(metric, clock) \
PerfStepTimer iostats_step_timer_##metric( \
&(iostats_context.metric), CheckPerfFlag(flag_##metric), clock, true, \
PerfLevel::kEnableTimeAndCPUTimeExceptForMutex); \
iostats_step_timer_##metric.Start();

#else // ROCKSDB_SUPPORT_THREAD_LOCAL && !NIOSTATS_CONTEXT
Expand Down
41 changes: 22 additions & 19 deletions monitoring/perf_context_imp.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,44 +41,47 @@ extern thread_local PerfContext perf_context;
#define PERF_TIMER_START(metric) perf_step_timer_##metric.Start();

// Declare and set start time of the timer
#define PERF_TIMER_GUARD(metric) \
PerfStepTimer perf_step_timer_##metric(&(perf_context.metric)); \
#define PERF_TIMER_GUARD(metric) \
PerfStepTimer perf_step_timer_##metric(&(perf_context.metric), \
CheckPerfFlag(flag_##metric)); \
perf_step_timer_##metric.Start();

// Declare and set start time of the timer
#define PERF_TIMER_GUARD_WITH_CLOCK(metric, clock) \
PerfStepTimer perf_step_timer_##metric(&(perf_context.metric), clock); \
#define PERF_TIMER_GUARD_WITH_CLOCK(metric, clock) \
PerfStepTimer perf_step_timer_##metric(&(perf_context.metric), \
CheckPerfFlag(flag_##metric), clock); \
perf_step_timer_##metric.Start();

// Declare and set start time of the timer
#define PERF_CPU_TIMER_GUARD(metric, clock) \
PerfStepTimer perf_step_timer_##metric( \
&(perf_context.metric), clock, true, \
PerfLevel::kEnableTimeAndCPUTimeExceptForMutex); \
#define PERF_CPU_TIMER_GUARD(metric, clock) \
PerfStepTimer perf_step_timer_##metric( \
&(perf_context.metric), CheckPerfFlag(flag_##metric), clock, true, \
PerfLevel::kEnableTimeAndCPUTimeExceptForMutex); \
perf_step_timer_##metric.Start();

#define PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(metric, condition, stats, \
ticker_type) \
PerfStepTimer perf_step_timer_##metric(&(perf_context.metric), nullptr, \
false, PerfLevel::kEnableTime, stats, \
ticker_type); \
if (condition) { \
perf_step_timer_##metric.Start(); \
#define PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(metric, condition, stats, \
ticker_type) \
PerfStepTimer perf_step_timer_##metric( \
&(perf_context.metric), CheckPerfFlag(flag_##metric), nullptr, false, \
PerfLevel::kEnableTime, stats, ticker_type); \
if (condition) { \
perf_step_timer_##metric.Start(); \
}

// Update metric with time elapsed since last START. start time is reset
// to current timestamp.
#define PERF_TIMER_MEASURE(metric) perf_step_timer_##metric.Measure();

// Increase metric value
#define PERF_COUNTER_ADD(metric, value) \
if (perf_level >= PerfLevel::kEnableCount) { \
perf_context.metric += value; \
#define PERF_COUNTER_ADD(metric, value) \
if (perf_level >= PerfLevel::kEnableCount || CheckPerfFlag(flag_##metric)) { \
perf_context.metric += value; \
}

// Increase metric value
#define PERF_COUNTER_BY_LEVEL_ADD(metric, value, level) \
if (perf_level >= PerfLevel::kEnableCount && \
if ((perf_level >= PerfLevel::kEnableCount || \
CheckPerfFlag(flag_##metric)) && \
perf_context.per_level_perf_context_enabled && \
perf_context.level_to_perf_context) { \
if ((*(perf_context.level_to_perf_context)).find(level) != \
Expand Down
32 changes: 32 additions & 0 deletions monitoring/perf_flag.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "rocksdb/perf_flag.h"

namespace ROCKSDB_NAMESPACE {

#ifdef ROCKSDB_SUPPORT_THREAD_LOCAL
__thread uint8_t perf_flags[FLAGS_LEN] = {0};
#else
uint8_t perf_flags[FLAGS_LEN] = {0};
#endif

#define GET_FLAG(flag) perf_flags[(uint64_t)(flag) >> 3]

void EnablePerfFlag(uint64_t flag) {
if (!CheckPerfFlag(flag)) {
// & 0b111 means find the flag location is a alternative way to do mod
// operation
GET_FLAG(flag) ^= (uint64_t)0b1 << ((uint64_t)flag & (uint64_t)0b111);
}
}

void DisablePerfFlag(uint64_t flag) {
if (CheckPerfFlag(flag)) {
GET_FLAG(flag) ^= (uint64_t)0b1 << ((uint64_t)flag & (uint64_t)0b111);
}
}

bool CheckPerfFlag(uint64_t flag) {
return ((uint64_t)GET_FLAG(flag) & (uint64_t)0b1
<< (flag & (uint64_t)0b111)) != 0;
}

} // namespace ROCKSDB_NAMESPACE
18 changes: 18 additions & 0 deletions monitoring/perf_flag_imp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).
//
#pragma once

#include <cstdint>

#include "rocksdb/perf_flag.h"

namespace ROCKSDB_NAMESPACE {
#ifdef ROCKSDB_SUPPORT_THREAD_LOCAL
extern __thread uint8_t perf_flags[FLAGS_LEN];
#else
extern uint8_t perf_flags[FLAGS_LEN];
#endif
} // namespace ROCKSDB_NAMESPACE
6 changes: 4 additions & 2 deletions monitoring/perf_step_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// (found in the LICENSE.Apache file in the root directory).
//
#pragma once
#include "monitoring/perf_flag_imp.h"
#include "monitoring/perf_level_imp.h"
#include "monitoring/statistics.h"
#include "rocksdb/system_clock.h"
Expand All @@ -13,10 +14,11 @@ namespace ROCKSDB_NAMESPACE {
class PerfStepTimer {
public:
explicit PerfStepTimer(
uint64_t* metric, SystemClock* clock = nullptr, bool use_cpu_time = false,
uint64_t* metric, bool enable_flag = false, SystemClock* clock = nullptr,
bool use_cpu_time = false,
PerfLevel enable_level = PerfLevel::kEnableTimeExceptForMutex,
Statistics* statistics = nullptr, uint32_t ticker_type = 0)
: perf_counter_enabled_(perf_level >= enable_level),
: perf_counter_enabled_(perf_level >= enable_level || enable_flag),
use_cpu_time_(use_cpu_time),
ticker_type_(ticker_type),
clock_((perf_counter_enabled_ || statistics != nullptr)
Expand Down
Loading

0 comments on commit 2f1efc5

Please sign in to comment.