Skip to content

Commit eb1329d

Browse files
committed
feat: add bench case(threadtest) based on Hoard benchmarks
1 parent d5037f8 commit eb1329d

File tree

1 file changed

+82
-9
lines changed

1 file changed

+82
-9
lines changed

benches/memory_allocator_benchmark.rs

Lines changed: 82 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,14 @@ use alloc::alloc::Layout;
1111
use buddy_system_allocator::LockedHeap;
1212
use criterion::{black_box, criterion_group, criterion_main, Criterion};
1313

14+
const LARGE_SIZE: usize = 1024;
15+
const SMALL_SIZE: usize = 8;
16+
const THREAD_SIZE: usize = 10;
17+
const ALIGN: usize = 8;
18+
1419
#[inline]
1520
pub fn large_alloc<const ORDER: usize>(heap: &LockedHeap<ORDER>) {
16-
let layout = unsafe { Layout::from_size_align_unchecked(1024, 8) };
21+
let layout = unsafe { Layout::from_size_align_unchecked(LARGE_SIZE, ALIGN) };
1722
unsafe {
1823
let addr = heap.alloc(layout);
1924
heap.dealloc(addr, layout);
@@ -22,7 +27,7 @@ pub fn large_alloc<const ORDER: usize>(heap: &LockedHeap<ORDER>) {
2227

2328
#[inline]
2429
pub fn small_alloc<const ORDER: usize>(heap: &LockedHeap<ORDER>) {
25-
let layout = unsafe { Layout::from_size_align_unchecked(8, 8) };
30+
let layout = unsafe { Layout::from_size_align_unchecked(SMALL_SIZE, ALIGN) };
2631
unsafe {
2732
let addr = heap.alloc(layout);
2833
heap.dealloc(addr, layout);
@@ -31,16 +36,81 @@ pub fn small_alloc<const ORDER: usize>(heap: &LockedHeap<ORDER>) {
3136

3237
#[inline]
3338
pub fn mutil_thread_alloc<const ORDER: usize>(heap: &'static LockedHeap<ORDER>) {
34-
let mut threads = vec![];
39+
let mut threads = Vec::with_capacity(THREAD_SIZE);
3540
let alloc = Arc::new(heap);
36-
for i in 0..10 {
37-
let a = alloc.clone();
41+
for i in 0..THREAD_SIZE {
42+
let prethread_alloc = alloc.clone();
3843
let handle = thread::spawn(move || {
39-
let layout = unsafe { Layout::from_size_align_unchecked(i * 10, 8) };
44+
let layout = unsafe { Layout::from_size_align_unchecked(i * THREAD_SIZE, ALIGN) };
4045
let addr;
41-
unsafe { addr = a.alloc(layout) }
42-
sleep(Duration::from_nanos(10 - i as u64));
43-
unsafe { a.dealloc(addr, layout) }
46+
unsafe { addr = prethread_alloc.alloc(layout) }
47+
sleep(Duration::from_nanos((THREAD_SIZE - i) as u64));
48+
unsafe { prethread_alloc.dealloc(addr, layout) }
49+
});
50+
threads.push(handle);
51+
}
52+
drop(alloc);
53+
54+
for t in threads {
55+
t.join().unwrap();
56+
}
57+
}
58+
59+
/// # From **Hoard** benchmark: threadtest.cpp, rewrite in Rust
60+
///
61+
/// # Warnning
62+
///
63+
/// This benchmark generally needs long time to finish
64+
///
65+
/// ----------------------------------------------------------------------
66+
/// Hoard: A Fast, Scalable, and Memory-Efficient Allocator
67+
/// for Shared-Memory Multiprocessors
68+
/// Contact author: Emery Berger, http://www.cs.utexas.edu/users/emery
69+
//
70+
/// Copyright (c) 1998-2000, The University of Texas at Austin.
71+
///
72+
/// This library is free software; you can redistribute it and/or modify
73+
/// it under the terms of the GNU Library General Public License as
74+
/// published by the Free Software Foundation, http://www.fsf.org.
75+
///
76+
/// This library is distributed in the hope that it will be useful, but
77+
/// WITHOUT ANY WARRANTY; without even the implied warranty of
78+
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
79+
/// Library General Public License for more details.
80+
/// ----------------------------------------------------------------------
81+
///
82+
#[inline]
83+
pub fn thread_test<const ORDER: usize>(heap: &'static LockedHeap<ORDER>) {
84+
const N_ITERATIONS: usize = 50;
85+
const N_OBJECTS: usize = 30000;
86+
const N_THREADS: usize = 10;
87+
const OBJECT_SIZE: usize = 1;
88+
89+
let mut threads = Vec::with_capacity(THREAD_SIZE);
90+
let alloc = Arc::new(heap);
91+
92+
for i in 0..THREAD_SIZE {
93+
let prethread_alloc = alloc.clone();
94+
let handle = thread::spawn(move || {
95+
// a = new Foo * [nobjects / nthreads];
96+
let layout = unsafe {
97+
Layout::from_size_align_unchecked(SMALL_SIZE * (N_OBJECTS / N_THREADS), ALIGN)
98+
};
99+
let addr = unsafe { prethread_alloc.alloc(layout) };
100+
for j in 0..N_ITERATIONS {
101+
// inner object:
102+
// a[i] = new Foo[objSize];
103+
let mut addrs = vec![];
104+
let layout =
105+
unsafe { Layout::from_size_align_unchecked(SMALL_SIZE * OBJECT_SIZE, ALIGN) };
106+
for i in 0..(N_OBJECTS / N_THREADS) {
107+
addrs.push(unsafe { prethread_alloc.alloc(layout) });
108+
}
109+
for addr in addrs {
110+
unsafe { prethread_alloc.dealloc(addr, layout) }
111+
}
112+
}
113+
unsafe { prethread_alloc.dealloc(addr, layout) }
44114
});
45115
threads.push(handle);
46116
}
@@ -77,6 +147,9 @@ pub fn criterion_benchmark(c: &mut Criterion) {
77147
c.bench_function("mutil thread alloc", |b| {
78148
b.iter(|| mutil_thread_alloc(black_box(&HEAP_ALLOCATOR)))
79149
});
150+
c.bench_function("threadtest", |b| {
151+
b.iter(|| thread_test(black_box(&HEAP_ALLOCATOR)))
152+
});
80153
}
81154

82155
criterion_group!(benches, criterion_benchmark);

0 commit comments

Comments
 (0)