From 9e3b47f1e32e6c401ced031c187fd8e861f4a1b3 Mon Sep 17 00:00:00 2001 From: Lalit Date: Tue, 26 Nov 2024 22:44:13 -0800 Subject: [PATCH 1/3] add benchmark --- opentelemetry-user-events-logs/Cargo.toml | 6 +++- .../benches/benchmark.rs | 34 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 opentelemetry-user-events-logs/benches/benchmark.rs diff --git a/opentelemetry-user-events-logs/Cargo.toml b/opentelemetry-user-events-logs/Cargo.toml index 23c102ff..0cf5c8b4 100644 --- a/opentelemetry-user-events-logs/Cargo.toml +++ b/opentelemetry-user-events-logs/Cargo.toml @@ -23,8 +23,12 @@ opentelemetry-appender-tracing = { workspace = true } tracing = { version = "0.1", default-features = false, features = ["std"] } tracing-core = "0.1.31" tracing-subscriber = { version = "0.3.0", default-features = false, features = ["registry", "std"] } -microbench = "0.5" +criterion = "0.4" # Add the Criterion crate for benchmarking [features] logs_level_enabled = ["opentelemetry/logs_level_enabled", "opentelemetry_sdk/logs_level_enabled"] default = ["logs_level_enabled"] + +[[bench]] +name = "benchmark" +harness = false \ No newline at end of file diff --git a/opentelemetry-user-events-logs/benches/benchmark.rs b/opentelemetry-user-events-logs/benches/benchmark.rs new file mode 100644 index 00000000..fc5e957f --- /dev/null +++ b/opentelemetry-user-events-logs/benches/benchmark.rs @@ -0,0 +1,34 @@ +// Run as root user as access to `tracefs` is required, or ensure the current user has the necessary permissions. +// To run benchmarks with root privileges, execute: +// sudo -E /home//.cargo/bin/cargo bench +// Replace with your actual username. +// +// System Information: +// Processor: AMD EPYC 7763 64-Core Processor +// CPU Cores: 8 +// Logical Processors: 16 +// Memory: 64 GB +// time: [4.1429 ns 4.1514 ns 4.1621 ns] + +use criterion::{criterion_group, criterion_main, Criterion}; +use eventheader_dynamic::{Provider, ProviderOptions}; + +fn benchmark_find_set(c: &mut Criterion) { + // Setup the Provider + let mut options = ProviderOptions::new(); + options = *options.group_name("testprovider"); + let mut provider = Provider::new("testprovider", &options); + + // Register some dummy events with specific levels and keywords + let keyword = 0x01; // Example keyword + let mut level = 4; // Example level (Informational) + provider.register_set(eventheader::Level::Informational, keyword); + level = level.into(); + // Benchmark the `find_set` method + c.bench_function("provider_find_set", |b| { + b.iter(|| provider.find_set(level.into(), keyword)); + }); +} + +criterion_group!(benches, benchmark_find_set); +criterion_main!(benches); From 6f6d08e909f82e4483a283c6622aea26c8629dee Mon Sep 17 00:00:00 2001 From: Lalit Date: Tue, 10 Dec 2024 14:19:28 +0000 Subject: [PATCH 2/3] add benchmark for concurrent check --- .../benches/benchmark.rs | 96 +++++++++++++++---- 1 file changed, 77 insertions(+), 19 deletions(-) diff --git a/opentelemetry-user-events-logs/benches/benchmark.rs b/opentelemetry-user-events-logs/benches/benchmark.rs index fc5e957f..50423670 100644 --- a/opentelemetry-user-events-logs/benches/benchmark.rs +++ b/opentelemetry-user-events-logs/benches/benchmark.rs @@ -1,19 +1,13 @@ -// Run as root user as access to `tracefs` is required, or ensure the current user has the necessary permissions. -// To run benchmarks with root privileges, execute: -// sudo -E /home//.cargo/bin/cargo bench -// Replace with your actual username. -// -// System Information: -// Processor: AMD EPYC 7763 64-Core Processor -// CPU Cores: 8 -// Logical Processors: 16 -// Memory: 64 GB -// time: [4.1429 ns 4.1514 ns 4.1621 ns] - use criterion::{criterion_group, criterion_main, Criterion}; use eventheader_dynamic::{Provider, ProviderOptions}; +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, +}; +use std::thread; -fn benchmark_find_set(c: &mut Criterion) { +/// Benchmark `find_set` with no concurrent threads +fn benchmark_find_set_single(c: &mut Criterion) { // Setup the Provider let mut options = ProviderOptions::new(); options = *options.group_name("testprovider"); @@ -21,14 +15,78 @@ fn benchmark_find_set(c: &mut Criterion) { // Register some dummy events with specific levels and keywords let keyword = 0x01; // Example keyword - let mut level = 4; // Example level (Informational) + let level = 4; // Example level (Informational) provider.register_set(eventheader::Level::Informational, keyword); - level = level.into(); - // Benchmark the `find_set` method - c.bench_function("provider_find_set", |b| { - b.iter(|| provider.find_set(level.into(), keyword)); + + // Benchmark the `find_set` method with `enabled` check + c.bench_function("provider_find_set_single", |b| { + b.iter(|| { + if let Some(event_set) = provider.find_set(level.into(), keyword) { + event_set.enabled(); // Check if the tracepoint is being listened to + } + }); }); } -criterion_group!(benches, benchmark_find_set); +/// Benchmark `find_set` with a parameterized number of concurrent threads +fn benchmark_find_set_concurrent(c: &mut Criterion) { + let thread_counts = [2, 4, 8]; // Test with 2, 4, and 8 threads + + for &thread_count in &thread_counts { + // Setup the Provider + let mut options = ProviderOptions::new(); + options = *options.group_name("testprovider"); + let mut provider = Provider::new("testprovider", &options); + + // Register some dummy events with specific levels and keywords + let keyword = 0x01; // Example keyword + let level = 4; // Example level (Informational) + provider.register_set(eventheader::Level::Informational, keyword); + + // Shared Provider and stop flag + let provider = Arc::new(provider); + let stop_flag = Arc::new(AtomicBool::new(false)); + + // Spawn worker threads + let mut worker_handles = Vec::new(); + for _ in 0..thread_count { + let provider_clone = Arc::clone(&provider); + let stop_flag_clone = Arc::clone(&stop_flag); + worker_handles.push(thread::spawn(move || { + while !stop_flag_clone.load(Ordering::Relaxed) { + if let Some(event_set) = provider_clone.find_set(level.into(), keyword) { + event_set.enabled(); // Check if tracepoint is being listened to + } + } + })); + } + + // Dereference the `Arc` once before the benchmark to reduce overhead + let provider_ref: &Provider = &provider; + + // Benchmark the `find_set` method with `enabled` check + let benchmark_name = format!("provider_find_set_concurrent_{}threads", thread_count); + c.bench_function(&benchmark_name, |b| { + b.iter(|| { + if let Some(event_set) = provider_ref.find_set(level.into(), keyword) { + event_set.enabled(); // Check if tracepoint is being listened to + } + }); + }); + + // Signal worker threads to stop + stop_flag.store(true, Ordering::Relaxed); + + // Wait for all worker threads to complete + for handle in worker_handles { + let _ = handle.join(); + } + } +} + +criterion_group!( + benches, + benchmark_find_set_single, + benchmark_find_set_concurrent +); criterion_main!(benches); From f972a4c6f7c8cfc457fa7831945f990d285a64b9 Mon Sep 17 00:00:00 2001 From: Lalit Date: Tue, 10 Dec 2024 14:48:46 +0000 Subject: [PATCH 3/3] fix benchmark --- .../benches/benchmark.rs | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/opentelemetry-user-events-logs/benches/benchmark.rs b/opentelemetry-user-events-logs/benches/benchmark.rs index 50423670..700969dc 100644 --- a/opentelemetry-user-events-logs/benches/benchmark.rs +++ b/opentelemetry-user-events-logs/benches/benchmark.rs @@ -1,3 +1,21 @@ +// Run as root user as access to `tracefs` is required, or ensure the current user has the necessary permissions. +// To run benchmarks with root privileges, execute: +// sudo -E /home//.cargo/bin/cargo bench +// Replace with your actual username. +// +// System Information: +// Processor: AMD EPYC 7763 64-Core Processor +// CPU Cores: 8 +// Logical Processors: 16 +// Memory: 64 GB + +// provider_find_set_single time: [3.9862 ns 3.9898 ns 3.9937 ns] +// provider_find_set_concurrent_0threads time: [3.9937 ns 3.9978 ns 4.0024 ns] +// provider_find_set_concurrent_2threads: time: time: [111.52 ns 114.61 ns 117.38 ns] +// provider_find_set_concurrent_4threads: time: time: [199.18 ns 203.92 ns 208.43 ns] +// provider_find_set_concurrent_8threads time: time: [199.18 ns 203.92 ns 208.43 ns] + +use criterion::black_box; use criterion::{criterion_group, criterion_main, Criterion}; use eventheader_dynamic::{Provider, ProviderOptions}; use std::sync::{ @@ -22,7 +40,7 @@ fn benchmark_find_set_single(c: &mut Criterion) { c.bench_function("provider_find_set_single", |b| { b.iter(|| { if let Some(event_set) = provider.find_set(level.into(), keyword) { - event_set.enabled(); // Check if the tracepoint is being listened to + black_box(event_set.enabled()); // Check if the tracepoint is being listened to } }); }); @@ -30,7 +48,7 @@ fn benchmark_find_set_single(c: &mut Criterion) { /// Benchmark `find_set` with a parameterized number of concurrent threads fn benchmark_find_set_concurrent(c: &mut Criterion) { - let thread_counts = [2, 4, 8]; // Test with 2, 4, and 8 threads + let thread_counts = [0, 2, 4, 8]; // Test with 2, 4, and 8 threads for &thread_count in &thread_counts { // Setup the Provider @@ -55,7 +73,7 @@ fn benchmark_find_set_concurrent(c: &mut Criterion) { worker_handles.push(thread::spawn(move || { while !stop_flag_clone.load(Ordering::Relaxed) { if let Some(event_set) = provider_clone.find_set(level.into(), keyword) { - event_set.enabled(); // Check if tracepoint is being listened to + black_box(event_set.enabled()); // Check if tracepoint is being listened to } } })); @@ -69,7 +87,7 @@ fn benchmark_find_set_concurrent(c: &mut Criterion) { c.bench_function(&benchmark_name, |b| { b.iter(|| { if let Some(event_set) = provider_ref.find_set(level.into(), keyword) { - event_set.enabled(); // Check if tracepoint is being listened to + black_box(event_set.enabled()); // Check if tracepoint is being listened to } }); });