Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 23 additions & 42 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ on:
pull_request:
workflow_dispatch:

permissions:
contents: read
id-token: write

jobs:
lint:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -127,47 +131,20 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: cargo nextest run -p cargo-codspeed --partition hash:${{ matrix.partition }}/5

compat-integration-test-instrumentation:
runs-on: ubuntu-latest
strategy:
matrix:
build-args:
- "-p codspeed"
- "-p codspeed-bencher-compat"
- "--features async_futures -p codspeed-criterion-compat"
- "-p codspeed-divan-compat"
- "-p codspeed-divan-compat-examples"
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: moonrepo/setup-rust@v1
with:
cache-target: release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- run: cargo install --path crates/cargo-codspeed --locked

- run: cargo codspeed build ${{ matrix.build-args }}

- name: Run the benchmarks
uses: CodSpeedHQ/action@main
env:
MY_ENV_VAR: "YES"
with:
run: cargo codspeed run
mode: instrumentation
token: ${{ secrets.CODSPEED_TOKEN }}

compat-integration-test-walltime:
runs-on: codspeed-macro
compat-integration-test:
strategy:
matrix:
package:
- codspeed
- codspeed-bencher-compat
- codspeed-divan-compat
- codspeed-divan-compat-examples
- codspeed-criterion-compat
mode:
- walltime
- instrumentation
# - memory
runs-on: ${{ matrix.mode == 'walltime' && 'codspeed-macro' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -180,19 +157,24 @@ jobs:

- run: cargo install --path crates/cargo-codspeed --locked

- name: Remove .cargo/config.toml to not force instrumentation mode
if: ${{ matrix.mode != 'instrumentation' }}
run: rm -f .cargo/config.toml

- run: |
# Remove the cargo config else it forces instrumentation mode
rm -f .cargo/config.toml
cargo codspeed build -p ${{ matrix.package }}
if [ "${{ matrix.package }}" = "codspeed-criterion-compat" ]; then
cargo codspeed build -p ${{ matrix.package }} --features async_futures
else
cargo codspeed build -p ${{ matrix.package }}
fi

- name: Run the benchmarks
uses: CodSpeedHQ/action@main
env:
MY_ENV_VAR: "YES"
with:
run: cargo codspeed run
mode: walltime
token: ${{ secrets.CODSPEED_TOKEN }}
mode: ${{ matrix.mode }}

musl-build-check:
strategy:
Expand Down Expand Up @@ -228,8 +210,7 @@ jobs:
- tests-without-cargo-codspeed
- test-cargo-codspeed
- msrv-check
- compat-integration-test-instrumentation
- compat-integration-test-walltime
- compat-integration-test
- musl-build-check
steps:
- uses: re-actors/alls-green@release/v1
Expand Down
6 changes: 4 additions & 2 deletions crates/cargo-codspeed/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,10 @@ See `cargo codspeed build --help` for more information.");
"-Cstrip=none".to_owned(),
];

// Add the codspeed cfg flag if simulation mode is enabled
if measurement_mode == MeasurementMode::Simulation {
// Add the codspeed cfg flag if the benchmark should only run once
if measurement_mode == MeasurementMode::Simulation
|| measurement_mode == MeasurementMode::Analysis
{
flags.push("--cfg=codspeed".to_owned());
}

Expand Down
2 changes: 2 additions & 0 deletions crates/cargo-codspeed/src/measurement_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub enum MeasurementMode {
#[value(alias = "instrumentation")]
Simulation,
Walltime,
Analysis,
}

impl fmt::Display for MeasurementMode {
Expand All @@ -19,6 +20,7 @@ impl fmt::Display for MeasurementMode {
match self {
MeasurementMode::Simulation => "simulation",
MeasurementMode::Walltime => "walltime",
MeasurementMode::Analysis => "analysis",
}
)
}
Expand Down
9 changes: 7 additions & 2 deletions crates/codspeed/src/codspeed.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::measurement;
use crate::{instrument_hooks::InstrumentHooks, measurement};
use colored::Colorize;
use std::ffi::CString;

Expand All @@ -19,7 +19,8 @@ pub struct CodSpeed {

impl CodSpeed {
pub fn new() -> Self {
let is_instrumented = measurement::is_instrumented();
let hooks_instance = InstrumentHooks::instance();
let is_instrumented = hooks_instance.is_instrumented();
if !is_instrumented {
println!(
"{} codspeed is enabled, but no performance measurement will be made since it's running in an unknown environment.",
Expand All @@ -46,12 +47,16 @@ impl CodSpeed {
#[inline(always)]
pub fn start_benchmark(&mut self, name: &str) {
self.current_benchmark = CString::new(name).expect("CString::new failed");
let _ = InstrumentHooks::instance().start_benchmark();
measurement::start();
}

#[inline(always)]
pub fn end_benchmark(&mut self) {
measurement::stop(&self.current_benchmark);
let _ = InstrumentHooks::instance().stop_benchmark();
let _ = InstrumentHooks::instance()
.set_executed_benchmark(&self.current_benchmark.to_string_lossy());
self.benchmarked
.push(self.current_benchmark.to_str().unwrap().to_string());
let action_str = if self.is_instrumented {
Expand Down
12 changes: 12 additions & 0 deletions crates/codspeed/src/instrument_hooks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ mod linux_impl {
instance
.set_integration("codspeed-rust", env!("CARGO_PKG_VERSION"))
.expect("Failed to set integration");
InstrumentHooks::disable_callgrind_markers();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small comment to explain that we have inline assembly for rust integration therefore we do not use instrument hooks for this

instance
})
}
Expand Down Expand Up @@ -129,6 +130,15 @@ mod linux_impl {
ffi::instrument_hooks_current_timestamp()
}
}

pub fn disable_callgrind_markers() {
unsafe {
ffi::instrument_hooks_set_feature(
ffi::instrument_hooks_feature_t_FEATURE_DISABLE_CALLGRIND_MARKERS,
true,
)
};
}
}

impl Drop for InstrumentHooks {
Expand Down Expand Up @@ -175,6 +185,8 @@ mod other_impl {
pub fn current_timestamp() -> u64 {
0
}

pub fn disable_callgrind_markers() {}
}
}

Expand Down
11 changes: 0 additions & 11 deletions crates/codspeed/src/measurement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,6 @@ use std::ffi::CString;

use crate::request::{send_client_request, ClientRequest, Value};

#[inline(always)]
pub fn is_instrumented() -> bool {
let valgrind_depth = unsafe {
send_client_request(
0,
&[ClientRequest::RunningOnValgrind as Value, 0, 0, 0, 0, 0],
)
};
valgrind_depth > 0
}

#[inline(always)]
pub fn set_metadata() {
let full_metadata = CString::new(format!(
Expand Down
1 change: 0 additions & 1 deletion crates/codspeed/src/request/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ const CG_BASE: u32 = ((b'C' as u32) << 24) + ((b'T' as u32) << 16);
#[allow(non_camel_case_types)]
#[repr(u32)]
pub enum ClientRequest {
RunningOnValgrind = 0x1001,
ZeroStatistics = CG_BASE + 1,
DumpStatisticsAt = CG_BASE + 3,
StartInstrumentation = CG_BASE + 4,
Expand Down
4 changes: 4 additions & 0 deletions crates/divan_compat/examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,7 @@ harness = false
[[bench]]
name = "counters"
harness = false

[[bench]]
name = "alloc"
harness = false
40 changes: 40 additions & 0 deletions crates/divan_compat/examples/benches/alloc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use std::{
alloc::Layout,
collections::{HashMap, HashSet},
};

#[divan::bench]
fn allocate() {
println!("Hello, world!");

let vec = vec![1, 2, 3];
println!("{vec:?}");

let mut map = HashMap::new();
map.insert("key", "value");
println!("{map:?}");

let mut set = HashSet::new();
set.insert("apple");
set.insert("banana");
println!("{set:?}");

std::thread::sleep(std::time::Duration::from_secs(1));

let mut bytes_vec = vec![0u8; 0x100];
println!("{:?}", bytes_vec.len());

bytes_vec.extend(&vec![0u8; 0x1000]);

// Alloc 42 bytes of memory per iteration (4200 bytes total)
for _ in 0..100 {
let layout = Layout::new::<[u8; 42]>();
let memory = unsafe { std::alloc::alloc(layout) };
core::hint::black_box(memory);
unsafe { std::alloc::dealloc(memory, layout) };
}
}

fn main() {
divan::main();
}
Loading