@@ -11,9 +11,14 @@ use alloc::alloc::Layout;
11
11
use buddy_system_allocator:: LockedHeap ;
12
12
use criterion:: { black_box, criterion_group, criterion_main, Criterion } ;
13
13
14
+ const LARGE_SIZE : usize = 1024 ;
15
+ const SMALL_SIZE : usize = 8 ;
16
+ const THREAD_SIZE : usize = 10 ;
17
+ const ALIGN : usize = 8 ;
18
+
14
19
#[ inline]
15
20
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 ) } ;
17
22
unsafe {
18
23
let addr = heap. alloc ( layout) ;
19
24
heap. dealloc ( addr, layout) ;
@@ -22,7 +27,7 @@ pub fn large_alloc<const ORDER: usize>(heap: &LockedHeap<ORDER>) {
22
27
23
28
#[ inline]
24
29
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 ) } ;
26
31
unsafe {
27
32
let addr = heap. alloc ( layout) ;
28
33
heap. dealloc ( addr, layout) ;
@@ -31,16 +36,81 @@ pub fn small_alloc<const ORDER: usize>(heap: &LockedHeap<ORDER>) {
31
36
32
37
#[ inline]
33
38
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 ) ;
35
40
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 ( ) ;
38
43
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 ) } ;
40
45
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) }
44
114
} ) ;
45
115
threads. push ( handle) ;
46
116
}
@@ -77,6 +147,9 @@ pub fn criterion_benchmark(c: &mut Criterion) {
77
147
c. bench_function ( "mutil thread alloc" , |b| {
78
148
b. iter ( || mutil_thread_alloc ( black_box ( & HEAP_ALLOCATOR ) ) )
79
149
} ) ;
150
+ c. bench_function ( "threadtest" , |b| {
151
+ b. iter ( || thread_test ( black_box ( & HEAP_ALLOCATOR ) ) )
152
+ } ) ;
80
153
}
81
154
82
155
criterion_group ! ( benches, criterion_benchmark) ;
0 commit comments