Skip to content

Commit

Permalink
Add jemalloc support
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelsproul committed Nov 7, 2022
1 parent 8600645 commit 69ecba7
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 5 deletions.
4 changes: 4 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[env]
# Set the number of arenas to 16 when using jemalloc.
JEMALLOC_SYS_WITH_MALLOC_CONF = "abort_conf:true,narenas:16"

40 changes: 40 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ BUILD_PATH_AARCH64 = "target/$(AARCH64_TAG)/release"
PINNED_NIGHTLY ?= nightly
CLIPPY_PINNED_NIGHTLY=nightly-2022-05-19

# List of features to use when building natively. Can be overriden via the environment.
FEATURES ?= jemalloc

# List of features to use when cross-compiling. Can be overridden via the environment.
CROSS_FEATURES ?= gnosis,slasher-lmdb,slasher-mdbx
CROSS_FEATURES ?= gnosis,slasher-lmdb,slasher-mdbx,jemalloc

# Cargo profile for Cross builds. Default is for local builds, CI uses an override.
CROSS_PROFILE ?= release
Expand Down
7 changes: 5 additions & 2 deletions common/malloc_utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ version = "0.1.0"
authors = ["Paul Hauner <paul@paulhauner.com>"]
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
lighthouse_metrics = { path = "../lighthouse_metrics" }
lazy_static = "1.4.0"
libc = "0.2.79"
parking_lot = "0.12.0"
jemallocator = { version = "0.5.0", optional = true, features = ["background_threads"] }
jemalloc-ctl = { version = "0.5.0", optional = true }

[features]
mallinfo2 = []
jemalloc = ["jemallocator", "jemallocator/stats", "jemalloc-ctl"]
jemalloc-stats = ["jemallocator/stats"]
jemalloc-profiling = ["jemallocator/profiling"]
52 changes: 52 additions & 0 deletions common/malloc_utils/src/jemalloc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//! Set the allocator to `jemalloc`.
//!
//! Due to `jemalloc` requiring configuration at compile time or immediately upon runtime
//! initialisation it is configured via a Cargo config file in `.cargo/config.toml`.
//!
//! The `jemalloc` tuning can be overriden by:
//!
//! A) `JEMALLOC_SYS_WITH_MALLOC_CONF` at compile-time.
//! B) `_RJEM_MALLOC_CONF` at runtime.
use jemalloc_ctl::{arenas, epoch, stats, Error};
use lazy_static::lazy_static;
use lighthouse_metrics::{set_gauge, try_create_int_gauge, IntGauge};

#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;

// Metrics for jemalloc.
lazy_static! {
pub static ref NUM_ARENAS: lighthouse_metrics::Result<IntGauge> =
try_create_int_gauge("jemalloc_num_arenas", "The number of arenas in use");
pub static ref BYTES_ALLOCATED: lighthouse_metrics::Result<IntGauge> =
try_create_int_gauge("jemalloc_bytes_allocated", "Equivalent to stats.allocated");
pub static ref BYTES_ACTIVE: lighthouse_metrics::Result<IntGauge> =
try_create_int_gauge("jemalloc_bytes_active", "Equivalent to stats.active");
pub static ref BYTES_MAPPED: lighthouse_metrics::Result<IntGauge> =
try_create_int_gauge("jemalloc_bytes_mapped", "Equivalent to stats.mapped");
pub static ref BYTES_METADATA: lighthouse_metrics::Result<IntGauge> =
try_create_int_gauge("jemalloc_bytes_metadata", "Equivalent to stats.metadata");
pub static ref BYTES_RESIDENT: lighthouse_metrics::Result<IntGauge> =
try_create_int_gauge("jemalloc_bytes_resident", "Equivalent to stats.resident");
pub static ref BYTES_RETAINED: lighthouse_metrics::Result<IntGauge> =
try_create_int_gauge("jemalloc_bytes_retained", "Equivalent to stats.retained");
}

pub fn scrape_jemalloc_metrics() {
scrape_jemalloc_metrics_fallible().unwrap()
}

pub fn scrape_jemalloc_metrics_fallible() -> Result<(), Error> {
// Advance the epoch so that the underlying statistics are updated.
epoch::advance()?;

set_gauge(&NUM_ARENAS, arenas::narenas::read()? as i64);
set_gauge(&BYTES_ALLOCATED, stats::allocated::read()? as i64);
set_gauge(&BYTES_ACTIVE, stats::active::read()? as i64);
set_gauge(&BYTES_MAPPED, stats::mapped::read()? as i64);
set_gauge(&BYTES_METADATA, stats::metadata::read()? as i64);
set_gauge(&BYTES_RESIDENT, stats::resident::read()? as i64);
set_gauge(&BYTES_RETAINED, stats::retained::read()? as i64);

Ok(())
}
23 changes: 21 additions & 2 deletions common/malloc_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,36 @@
//! detecting `glibc` are best-effort. If this crate throws errors about undefined external
//! functions, then try to compile with the `not_glibc_interface` module.

#[cfg(all(target_os = "linux", not(target_env = "musl")))]
#[cfg(all(
target_os = "linux",
not(any(target_env = "musl", feature = "jemalloc"))
))]
mod glibc;

#[cfg(feature = "jemalloc")]
mod jemalloc;

pub use interface::*;

#[cfg(all(target_os = "linux", not(target_env = "musl")))]
#[cfg(all(
target_os = "linux",
not(any(target_env = "musl", feature = "jemalloc"))
))]
mod interface {
pub use crate::glibc::configure_glibc_malloc as configure_memory_allocator;
pub use crate::glibc::scrape_mallinfo_metrics as scrape_allocator_metrics;
}

#[cfg(feature = "jemalloc")]
mod interface {
#[allow(dead_code)]
pub fn configure_memory_allocator() -> Result<(), String> {
Ok(())
}

pub use crate::jemalloc::scrape_jemalloc_metrics as scrape_allocator_metrics;
}

#[cfg(any(not(target_os = "linux"), target_env = "musl"))]
mod interface {
#[allow(dead_code, clippy::unnecessary_wraps)]
Expand Down
2 changes: 2 additions & 0 deletions lighthouse/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ gnosis = []
slasher-mdbx = ["slasher/mdbx"]
# Support slasher LMDB backend.
slasher-lmdb = ["slasher/lmdb"]
# Use jemalloc.
jemalloc = ["malloc_utils/jemalloc"]

[dependencies]
beacon_node = { "path" = "../beacon_node" }
Expand Down
10 changes: 10 additions & 0 deletions lighthouse/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ fn bls_library_name() -> &'static str {
}
}

fn allocator_name() -> &'static str {
if cfg!(feature = "jemalloc") {
"jemalloc"
} else {
"system"
}
}

fn main() {
// Enable backtraces unless a RUST_BACKTRACE value has already been explicitly provided.
if std::env::var("RUST_BACKTRACE").is_err() {
Expand All @@ -51,10 +59,12 @@ fn main() {
"{}\n\
BLS library: {}\n\
SHA256 hardware acceleration: {}\n\
Allocator: {}\n\
Specs: mainnet (true), minimal ({}), gnosis ({})",
VERSION.replace("Lighthouse/", ""),
bls_library_name(),
have_sha_extensions(),
allocator_name(),
cfg!(feature = "spec-minimal"),
cfg!(feature = "gnosis"),
).as_str()
Expand Down

0 comments on commit 69ecba7

Please sign in to comment.