Skip to content

Commit aedb37a

Browse files
authored
Benchmark Rust code (#933)
This PR allows benchmarking mmtk-core code in DummyVM. It uses `criterion`, which is a popular framework to benchmark with a stable Rust toolchain. This PR just introduces code and two benchmarks that specifically test our allocation code in Rust and our SFT read access. This PR does not include those benchmarks in the CI.
1 parent a504184 commit aedb37a

15 files changed

+97
-13
lines changed

vmbindings/dummyvm/Cargo.toml

+14-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ edition = "2021"
77
[lib]
88
name = "mmtk_dummyvm"
99
# be careful - LTO is only allowed for certain crate types
10-
crate-type = ["cdylib"]
10+
# We know that cdylib should work for LTO.
11+
# We keep rlib here as we need to use the crate from benches.
12+
crate-type = ["cdylib", "rlib"]
1113

1214
[profile.release]
1315
lto = true
@@ -20,10 +22,21 @@ atomic_refcell = "0.1.7"
2022
atomic = "0.4.6"
2123
log = "0.4"
2224

25+
[dev-dependencies]
26+
criterion = "0.4"
27+
28+
[[bench]]
29+
name = "main"
30+
harness = false
31+
2332
[features]
2433
default = []
2534
is_mmtk_object = ["mmtk/is_mmtk_object"]
2635
malloc_counted_size = ["mmtk/malloc_counted_size"]
2736
malloc_mark_sweep = ["mmtk/malloc_mark_sweep"]
2837
vo_bit = ["mmtk/vo_bit"]
2938
extreme_assertions = ["mmtk/extreme_assertions"]
39+
40+
# Feature to control which benchmarks to run. See benches/main.rs
41+
bench_sft = []
42+
bench_alloc = []
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use criterion::{criterion_group, Criterion};
2+
3+
use mmtk::plan::AllocationSemantics;
4+
use mmtk_dummyvm::api;
5+
use mmtk_dummyvm::test_fixtures::MutatorFixture;
6+
7+
fn alloc(c: &mut Criterion) {
8+
println!("Init MMTK in alloc bench");
9+
// 1GB so we are unlikely to OOM
10+
let fixture = MutatorFixture::create_with_heapsize(1 << 30);
11+
c.bench_function("alloc", |b| {
12+
b.iter(|| {
13+
let _addr = api::mmtk_alloc(fixture.mutator, 8, 8, 0, AllocationSemantics::Default);
14+
})
15+
});
16+
}
17+
18+
criterion_group!(benches, alloc);
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use criterion::{black_box, criterion_group, Criterion};
2+
3+
use mmtk::plan::AllocationSemantics;
4+
use mmtk::vm::ObjectModel;
5+
use mmtk_dummyvm::api;
6+
use mmtk_dummyvm::test_fixtures::FixtureContent;
7+
use mmtk_dummyvm::test_fixtures::MutatorFixture;
8+
9+
fn sft(c: &mut Criterion) {
10+
println!("Init MMTK in sft bench");
11+
let fixture = MutatorFixture::create();
12+
let addr = api::mmtk_alloc(fixture.mutator, 8, 8, 0, AllocationSemantics::Default);
13+
let obj = mmtk_dummyvm::object_model::VMObjectModel::address_to_ref(addr);
14+
15+
c.bench_function("sft read", |b| {
16+
b.iter(|| api::mmtk_is_in_mmtk_spaces(black_box(obj)))
17+
});
18+
}
19+
20+
criterion_group!(benches, sft);

vmbindings/dummyvm/benches/main.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use criterion::criterion_main;
2+
3+
// As we can only initialize one MMTk instance, we have to run each benchmark separately.
4+
// Filtering like `cargo bench -- sft` won't work, as it still evalutes all the benchmark groups (which initialize MMTk).
5+
// We can use conditional compilation, and run with `cargo bench --features bench_sft`. The features are defined in the dummy VM crate.
6+
7+
#[cfg(feature = "bench_sft")]
8+
mod bench_sft;
9+
#[cfg(feature = "bench_sft")]
10+
criterion_main!(bench_sft::benches);
11+
12+
#[cfg(feature = "bench_alloc")]
13+
mod bench_alloc;
14+
#[cfg(feature = "bench_alloc")]
15+
criterion_main!(bench_alloc::benches);

vmbindings/dummyvm/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ pub mod object_model;
1414
pub mod reference_glue;
1515
pub mod scanning;
1616

17+
pub mod test_fixtures;
18+
1719
mod edges;
1820
#[cfg(test)]
1921
mod tests;

vmbindings/dummyvm/src/tests/fixtures/mod.rs renamed to vmbindings/dummyvm/src/test_fixtures.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ impl<T: FixtureContent> Fixture<T> {
4343
}
4444
}
4545

46+
impl<T: FixtureContent> Default for Fixture<T> {
47+
fn default() -> Self {
48+
Self::new()
49+
}
50+
}
51+
4652
/// SerialFixture ensures all `with_fixture()` calls will be executed serially.
4753
pub struct SerialFixture<T: FixtureContent> {
4854
content: Mutex<Option<Box<T>>>,
@@ -85,6 +91,12 @@ impl<T: FixtureContent> SerialFixture<T> {
8591
}
8692
}
8793

94+
impl<T: FixtureContent> Default for SerialFixture<T> {
95+
fn default() -> Self {
96+
Self::new()
97+
}
98+
}
99+
88100
pub struct SingleObject {
89101
pub objref: ObjectReference,
90102
}
@@ -171,8 +183,13 @@ pub struct MutatorFixture {
171183
impl FixtureContent for MutatorFixture {
172184
fn create() -> Self {
173185
const MB: usize = 1024 * 1024;
174-
// 1MB heap
175-
mmtk_init(MB);
186+
Self::create_with_heapsize(MB)
187+
}
188+
}
189+
190+
impl MutatorFixture {
191+
pub fn create_with_heapsize(size: usize) -> Self {
192+
mmtk_init(size);
176193
mmtk_initialize_collection(VMThread::UNINITIALIZED);
177194
// Make sure GC does not run during test.
178195
mmtk_disable_collection();

vmbindings/dummyvm/src/tests/allocate_align_offset.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// GITHUB-CI: MMTK_PLAN=all
22

33
use crate::api;
4-
use crate::tests::fixtures::{MutatorFixture, SerialFixture};
4+
use crate::test_fixtures::{MutatorFixture, SerialFixture};
55
use crate::DummyVM;
66
use log::info;
77
use mmtk::plan::AllocationSemantics;

vmbindings/dummyvm/src/tests/barrier_slow_path_assertion.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
// Run the test with any plan that uses object barrier, and we also need both VO bit and extreme assertions.
55

66
use crate::object_model::OBJECT_REF_OFFSET;
7-
use crate::tests::fixtures::FixtureContent;
8-
use crate::tests::fixtures::MMTKSingleton;
7+
use crate::test_fixtures::FixtureContent;
8+
use crate::test_fixtures::MMTKSingleton;
99
use crate::{api::*, edges};
1010
use atomic::Atomic;
1111
use mmtk::util::{Address, ObjectReference};

vmbindings/dummyvm/src/tests/conservatism.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use crate::api::*;
55
use crate::object_model::OBJECT_REF_OFFSET;
6-
use crate::tests::fixtures::{Fixture, SingleObject};
6+
use crate::test_fixtures::{Fixture, SingleObject};
77
use mmtk::util::constants::LOG_BITS_IN_WORD;
88
use mmtk::util::is_mmtk_object::VO_BIT_REGION_SIZE;
99
use mmtk::util::*;

vmbindings/dummyvm/src/tests/edges_test.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use mmtk::{
88

99
use crate::{
1010
edges::{DummyVMEdge, OffsetEdge, TaggedEdge},
11-
tests::fixtures::{Fixture, TwoObjects},
11+
test_fixtures::{Fixture, TwoObjects},
1212
};
1313

1414
#[cfg(target_pointer_width = "64")]

vmbindings/dummyvm/src/tests/is_in_mmtk_spaces.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// GITHUB-CI: MMTK_PLAN=all
22

33
use crate::api::mmtk_is_in_mmtk_spaces as is_in_mmtk_spaces;
4-
use crate::tests::fixtures::{Fixture, SingleObject};
4+
use crate::test_fixtures::{Fixture, SingleObject};
55
use mmtk::util::*;
66

77
lazy_static! {

vmbindings/dummyvm/src/tests/issue867_allocate_unrealistically_large_object.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// GITHUB-CI: MMTK_PLAN=all
22

33
use crate::api;
4-
use crate::tests::fixtures::{MutatorFixture, SerialFixture};
4+
use crate::test_fixtures::{MutatorFixture, SerialFixture};
55
use mmtk::plan::AllocationSemantics;
66

77
lazy_static! {

vmbindings/dummyvm/src/tests/malloc_counted.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// GITHUB-CI: FEATURES=malloc_counted_size
22

33
use crate::api::*;
4-
use crate::tests::fixtures::{MMTKSingleton, SerialFixture};
4+
use crate::test_fixtures::{MMTKSingleton, SerialFixture};
55

66
lazy_static! {
77
static ref MMTK_SINGLETON: SerialFixture<MMTKSingleton> = SerialFixture::new();

vmbindings/dummyvm/src/tests/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ mod barrier_slow_path_assertion;
1313
#[cfg(feature = "is_mmtk_object")]
1414
mod conservatism;
1515
mod edges_test;
16-
mod fixtures;
1716
#[cfg(target_os = "linux")]
1817
mod handle_mmap_conflict;
1918
mod handle_mmap_oom;

vmbindings/dummyvm/src/tests/vm_layout_default.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use mmtk::util::heap::vm_layout::VMLayout;
44

55
pub fn test_with_vm_layout(layout: Option<VMLayout>) {
66
use crate::api;
7-
use crate::tests::fixtures::VMLayoutFixture;
7+
use crate::test_fixtures::VMLayoutFixture;
88
use mmtk::plan::AllocationSemantics;
99
use mmtk::vm::ObjectModel;
1010

0 commit comments

Comments
 (0)