1
0
mirror of https://github.com/facebook/rocksdb.git synced 2026-10-23 08:09:02 +03:00
Files
rocksdb/monitoring/perf_level_imp.h
Andrew Chang ee305ac1c3 Avoid a TLS init call on every perf counter update (#15428)
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/15428

RocksDB counts per-operation statistics (blocks read, bytes read, mutex waits,
timings) in `perf_context`. It is a `thread_local` variable: each thread has its
own copy, so threads never contend on it. This per-thread copy is "thread-local
storage" (TLS).

**Problem**: `PerfContext` has a non-trivial destructor. For such a variable, C++
must make sure the calling thread's copy is constructed before each use from
another source file, so the compiler emits a call to a small "TLS init"
function. That call goes through the PLT (procedure linkage table, the jump
table used to call functions that may live in another shared library). Every
`PERF_COUNTER_ADD` therefore paid a real function call before incrementing a
counter, and these macros run in hot loops such as key comparisons during block
iteration. `perf_level`, the on/off switch, has a smaller cost: it is
`extern thread_local` without `constinit`, so each read also tests whether it
has been initialized.

**Fix**:
- The perf macros read a `constinit thread_local PerfContext*` that each
  thread sets on first use. After that, a counter update is a pointer load,
  a null check and the increment.
- `perf_level` is declared and defined `constinit`, so reading it is a plain
  thread-local load.
- No public API change. `perf_context`, `get_perf_context()` and macro
  behavior are unchanged, and so is thread-exit behavior.

**Results**:
- Microbenchmark (`PERF_COUNTER_ADD` in a loop): 2.10 -> 0.84 ns per update
  with counting enabled; unchanged at 0.42 ns with counting disabled.
- Calls to the TLS init functions drop from 40 and 96 to 0 in block.cc.o
  and memtable.cc.o.
- In CPU profiles of large production RocksDB deployments, these accessors
  cost roughly 0.3-0.6% of total CPU. This change removes most of the
  `perf_context` part.

Reviewed By: xingbowang

Differential Revision: D125982209

fbshipit-source-id: f38b4fffda09611d28322e7534b135fb35631389
2026-10-21 11:47:50 -07:00

15 lines
452 B
C++

// 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 "port/port.h"
#include "rocksdb/perf_level.h"
namespace ROCKSDB_NAMESPACE {
extern thread_local constinit PerfLevel perf_level;
} // namespace ROCKSDB_NAMESPACE