Add a perf context level that doesn't measure time for mutex operations
Summary: Timing mutex operations can impact scalability of the system. Add a new perf context level that can measure time counters except for mutex. Test Plan: Add a new unit test case to make sure it is not set. Reviewers: IslamAbdelRahman, rven, kradhakrishnan, yhchiang, anthony Reviewed By: anthony Subscribers: MarkCallaghan, leveldb, dhruba Differential Revision: https://reviews.facebook.net/D53199
This commit is contained in:
parent
f7ef1a6132
commit
fb9811ee9b
@ -1,5 +1,9 @@
|
|||||||
# Rocksdb Change Log
|
# Rocksdb Change Log
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
### Public API Changes
|
||||||
|
* Add a new perf context level between kEnableCount and kEnableTime. Level 2 now doesn't include timers for mutexes.
|
||||||
|
|
||||||
## 4.4.0 (1/14/2016)
|
## 4.4.0 (1/14/2016)
|
||||||
### Public API Changes
|
### Public API Changes
|
||||||
* Change names in CompactionPri and add a new one.
|
* Change names in CompactionPri and add a new one.
|
||||||
|
@ -543,28 +543,31 @@ TEST_F(PerfContextTest, SeekKeyComparison) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PerfContextTest, DBMutexLockCounter) {
|
TEST_F(PerfContextTest, DBMutexLockCounter) {
|
||||||
SetPerfLevel(kEnableTime);
|
|
||||||
int stats_code[] = {0, static_cast<int>(DB_MUTEX_WAIT_MICROS)};
|
int stats_code[] = {0, static_cast<int>(DB_MUTEX_WAIT_MICROS)};
|
||||||
for (int c = 0; c < 2; ++c) {
|
for (PerfLevel perf_level :
|
||||||
|
{PerfLevel::kEnableTimeExceptForMutex, PerfLevel::kEnableTime}) {
|
||||||
|
for (int c = 0; c < 2; ++c) {
|
||||||
InstrumentedMutex mutex(nullptr, Env::Default(), stats_code[c]);
|
InstrumentedMutex mutex(nullptr, Env::Default(), stats_code[c]);
|
||||||
mutex.Lock();
|
mutex.Lock();
|
||||||
std::thread child_thread([&] {
|
std::thread child_thread([&] {
|
||||||
SetPerfLevel(kEnableTime);
|
SetPerfLevel(perf_level);
|
||||||
perf_context.Reset();
|
perf_context.Reset();
|
||||||
ASSERT_EQ(perf_context.db_mutex_lock_nanos, 0);
|
ASSERT_EQ(perf_context.db_mutex_lock_nanos, 0);
|
||||||
mutex.Lock();
|
mutex.Lock();
|
||||||
mutex.Unlock();
|
mutex.Unlock();
|
||||||
if (stats_code[c] == DB_MUTEX_WAIT_MICROS) {
|
if (perf_level == PerfLevel::kEnableTimeExceptForMutex ||
|
||||||
|
stats_code[c] != DB_MUTEX_WAIT_MICROS) {
|
||||||
|
ASSERT_EQ(perf_context.db_mutex_lock_nanos, 0);
|
||||||
|
} else {
|
||||||
// increment the counter only when it's a DB Mutex
|
// increment the counter only when it's a DB Mutex
|
||||||
ASSERT_GT(perf_context.db_mutex_lock_nanos, 0);
|
ASSERT_GT(perf_context.db_mutex_lock_nanos, 0);
|
||||||
} else {
|
|
||||||
ASSERT_EQ(perf_context.db_mutex_lock_nanos, 0);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Env::Default()->SleepForMicroseconds(100);
|
Env::Default()->SleepForMicroseconds(100);
|
||||||
mutex.Unlock();
|
mutex.Unlock();
|
||||||
child_thread.join();
|
child_thread.join();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PerfContextTest, FalseDBMutexWait) {
|
TEST_F(PerfContextTest, FalseDBMutexWait) {
|
||||||
|
@ -14,9 +14,11 @@ namespace rocksdb {
|
|||||||
// How much perf stats to collect. Affects perf_context and iostats_context.
|
// How much perf stats to collect. Affects perf_context and iostats_context.
|
||||||
|
|
||||||
enum PerfLevel {
|
enum PerfLevel {
|
||||||
kDisable = 0, // disable perf stats
|
kDisable = 0, // disable perf stats
|
||||||
kEnableCount = 1, // enable only count stats
|
kEnableCount = 1, // enable only count stats
|
||||||
kEnableTime = 2 // enable time stats too
|
kEnableTimeExceptForMutex = 2, // Other than count stats, also enable time
|
||||||
|
// stats except for mutexes
|
||||||
|
kEnableTime = 3 // enable count and time stats
|
||||||
};
|
};
|
||||||
|
|
||||||
// set the perf stats level for current thread
|
// set the perf stats level for current thread
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
namespace rocksdb {
|
namespace rocksdb {
|
||||||
void InstrumentedMutex::Lock() {
|
void InstrumentedMutex::Lock() {
|
||||||
PERF_CONDITIONAL_TIMER_GUARD(db_mutex_lock_nanos,
|
PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(db_mutex_lock_nanos,
|
||||||
stats_code_ == DB_MUTEX_WAIT_MICROS);
|
stats_code_ == DB_MUTEX_WAIT_MICROS);
|
||||||
uint64_t wait_time_micros = 0;
|
uint64_t wait_time_micros = 0;
|
||||||
if (env_ != nullptr && stats_ != nullptr) {
|
if (env_ != nullptr && stats_ != nullptr) {
|
||||||
{
|
{
|
||||||
@ -31,8 +31,8 @@ void InstrumentedMutex::LockInternal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InstrumentedCondVar::Wait() {
|
void InstrumentedCondVar::Wait() {
|
||||||
PERF_CONDITIONAL_TIMER_GUARD(db_condition_wait_nanos,
|
PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(db_condition_wait_nanos,
|
||||||
stats_code_ == DB_MUTEX_WAIT_MICROS);
|
stats_code_ == DB_MUTEX_WAIT_MICROS);
|
||||||
uint64_t wait_time_micros = 0;
|
uint64_t wait_time_micros = 0;
|
||||||
if (env_ != nullptr && stats_ != nullptr) {
|
if (env_ != nullptr && stats_ != nullptr) {
|
||||||
{
|
{
|
||||||
@ -53,8 +53,8 @@ void InstrumentedCondVar::WaitInternal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool InstrumentedCondVar::TimedWait(uint64_t abs_time_us) {
|
bool InstrumentedCondVar::TimedWait(uint64_t abs_time_us) {
|
||||||
PERF_CONDITIONAL_TIMER_GUARD(db_condition_wait_nanos,
|
PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(db_condition_wait_nanos,
|
||||||
stats_code_ == DB_MUTEX_WAIT_MICROS);
|
stats_code_ == DB_MUTEX_WAIT_MICROS);
|
||||||
uint64_t wait_time_micros = 0;
|
uint64_t wait_time_micros = 0;
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (env_ != nullptr && stats_ != nullptr) {
|
if (env_ != nullptr && stats_ != nullptr) {
|
||||||
|
@ -33,10 +33,10 @@ namespace rocksdb {
|
|||||||
PerfStepTimer perf_step_timer_ ## metric(&(perf_context.metric)); \
|
PerfStepTimer perf_step_timer_ ## metric(&(perf_context.metric)); \
|
||||||
perf_step_timer_ ## metric.Start();
|
perf_step_timer_ ## metric.Start();
|
||||||
|
|
||||||
#define PERF_CONDITIONAL_TIMER_GUARD(metric, condition) \
|
#define PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(metric, condition) \
|
||||||
PerfStepTimer perf_step_timer_##metric(&(perf_context.metric)); \
|
PerfStepTimer perf_step_timer_##metric(&(perf_context.metric), true); \
|
||||||
if ((condition)) { \
|
if ((condition)) { \
|
||||||
perf_step_timer_##metric.Start(); \
|
perf_step_timer_##metric.Start(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update metric with time elapsed since last START. start time is reset
|
// Update metric with time elapsed since last START. start time is reset
|
||||||
|
@ -12,12 +12,12 @@ namespace rocksdb {
|
|||||||
|
|
||||||
class PerfStepTimer {
|
class PerfStepTimer {
|
||||||
public:
|
public:
|
||||||
PerfStepTimer(uint64_t* metric)
|
explicit PerfStepTimer(uint64_t* metric, bool for_mutex = false)
|
||||||
: enabled_(perf_level >= PerfLevel::kEnableTime),
|
: enabled_(perf_level >= PerfLevel::kEnableTime ||
|
||||||
env_(enabled_ ? Env::Default() : nullptr),
|
(!for_mutex && perf_level >= kEnableTimeExceptForMutex)),
|
||||||
start_(0),
|
env_(enabled_ ? Env::Default() : nullptr),
|
||||||
metric_(metric) {
|
start_(0),
|
||||||
}
|
metric_(metric) {}
|
||||||
|
|
||||||
~PerfStepTimer() {
|
~PerfStepTimer() {
|
||||||
Stop();
|
Stop();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user