Skip to content
Merged
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
3 changes: 0 additions & 3 deletions notes/coll_alloc_supertrait/arena2_vs_arena3.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ but arena3 fits more objects into the same amount of memory
arena2 is faster at every size and the gap grows as object count goes up

| objects | arena3 | arena2 |
|---------|---------|---------|
| 100 | 1.02 µs | 643 ns |
| 500 | 4.15 µs | 1.83 µs |
| 1000 | 8.36 µs | 2.77 µs |
Expand All @@ -34,7 +33,6 @@ header on every object. But this bench is measuring allocation time, not memory
writing the header is cheap, what costs time in arena3 is the size class routing.

| objects | arena3 (0-byte header) | arena2 (8-byte header) |
|---------|---------|---------|
| 100 | 781 ns | 257 ns |
| 500 | 3.56 µs | 1.08 µs |
| 1000 | 7.02 µs | 2.15 µs |
Expand Down Expand Up @@ -91,7 +89,6 @@ the whole suite
time to free all objects and reclaim dead arenas:

| objects | arena3 | arena2 |
|---------|---------|---------|
| 100 | 951 ns | 665 ns |
| 500 | 2.57 µs | 2.11 µs |
| 1000 | 4.65 µs | 4.97 µs |
Expand Down
2 changes: 1 addition & 1 deletion oscars/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ harness = false
required-features = ["gc_allocator"]

[[bench]]
name = "arena2_vs_arena3"
name = "arena2_vs_mempool3"
harness = false

[features]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ fn bench_alloc_speed(c: &mut Criterion) {

for num_objects in [100, 500, 1000].iter() {
group.bench_with_input(
BenchmarkId::new("arena3", num_objects),
BenchmarkId::new("mempool3", num_objects),
num_objects,
|b, &num_objects| {
b.iter(|| {
let mut allocator =
oscars::alloc::arena3::ArenaAllocator::default().with_arena_size(65536);
oscars::alloc::mempool3::PoolAllocator::default().with_page_size(65536);

let mut ptrs = Vec::new();
for i in 0..num_objects {
let ptr = allocator.try_alloc(i).expect("allocation failed");
ptrs.push(ptr);
}

black_box((ptrs.len(), allocator.arenas_len()))
black_box((ptrs.len(), allocator.pools_len()))
});
},
);
Expand All @@ -34,6 +34,7 @@ fn bench_alloc_speed(c: &mut Criterion) {

let mut ptrs = Vec::new();
for i in 0..num_objects {
let i: usize = i;
let ptr = allocator.try_alloc(i).expect("allocation failed");
ptrs.push(ptr);
}
Expand All @@ -59,12 +60,12 @@ fn bench_small_objects(c: &mut Criterion) {

for num_objects in [100, 500, 1000].iter() {
group.bench_with_input(
BenchmarkId::new("arena3", num_objects),
BenchmarkId::new("mempool3", num_objects),
num_objects,
|b, &num_objects| {
b.iter(|| {
let mut allocator =
oscars::alloc::arena3::ArenaAllocator::default().with_arena_size(32768);
oscars::alloc::mempool3::PoolAllocator::default().with_page_size(32768);

for i in 0..num_objects {
let obj = SmallObject {
Expand All @@ -74,7 +75,7 @@ fn bench_small_objects(c: &mut Criterion) {
let _ = allocator.try_alloc(obj).expect("allocation failed");
}

black_box(allocator.arenas_len())
black_box(allocator.pools_len())
});
},
);
Expand All @@ -88,6 +89,7 @@ fn bench_small_objects(c: &mut Criterion) {
oscars::alloc::arena2::ArenaAllocator::default().with_arena_size(32768);

for i in 0..num_objects {
let i: usize = i;
let obj = SmallObject {
_a: i as u64,
_b: i as u64 * 2,
Expand All @@ -107,10 +109,10 @@ fn bench_small_objects(c: &mut Criterion) {
fn bench_mixed(c: &mut Criterion) {
let mut group = c.benchmark_group("3_mixed_sizes");

group.bench_function("arena3", |b| {
group.bench_function("mempool3", |b| {
b.iter(|| {
let mut allocator =
oscars::alloc::arena3::ArenaAllocator::default().with_arena_size(65536);
oscars::alloc::mempool3::PoolAllocator::default().with_page_size(65536);

for _ in 0..50 {
let _ = allocator.try_alloc([0u8; 16]);
Expand All @@ -119,7 +121,7 @@ fn bench_mixed(c: &mut Criterion) {
let _ = allocator.try_alloc([0u8; 128]);
}

black_box(allocator.arenas_len())
black_box(allocator.pools_len())
});
});

Expand Down Expand Up @@ -148,20 +150,20 @@ fn bench_density(c: &mut Criterion) {

const PAGE_SIZE: usize = 4096;

group.bench_function("arena3", |b| {
group.bench_function("mempool3", |b| {
b.iter(|| {
let mut allocator =
oscars::alloc::arena3::ArenaAllocator::default().with_arena_size(PAGE_SIZE);
oscars::alloc::mempool3::PoolAllocator::default().with_page_size(PAGE_SIZE);

let mut count = 0;
while allocator.try_alloc([0u64; 2]).is_ok() {
count += 1;
if allocator.arenas_len() > 1 {
if allocator.pools_len() > 1 {
break;
}
}

black_box((count, allocator.arenas_len()))
black_box((count, allocator.pools_len()))
});
});

Expand Down Expand Up @@ -189,10 +191,10 @@ fn bench_density(c: &mut Criterion) {
fn bench_vec_growth(c: &mut Criterion) {
let mut group = c.benchmark_group("5_vec_growth");

group.bench_function("arena3", |b| {
group.bench_function("mempool3", |b| {
b.iter(|| {
let mut allocator =
oscars::alloc::arena3::ArenaAllocator::default().with_arena_size(32768);
oscars::alloc::mempool3::PoolAllocator::default().with_page_size(32768);

let mut cap = 1;
while cap <= 1024 {
Expand Down Expand Up @@ -235,7 +237,7 @@ fn bench_vec_growth(c: &mut Criterion) {
cap *= 2;
}

black_box(allocator.arenas_len())
black_box(allocator.pools_len())
});
});

Expand Down Expand Up @@ -296,16 +298,16 @@ fn bench_throughput(c: &mut Criterion) {
let mut group = c.benchmark_group("6_sustained_throughput");
group.throughput(criterion::Throughput::Elements(10000));

group.bench_function("arena3", |b| {
group.bench_function("mempool3", |b| {
b.iter(|| {
let mut allocator =
oscars::alloc::arena3::ArenaAllocator::default().with_arena_size(131072);
oscars::alloc::mempool3::PoolAllocator::default().with_page_size(131072);

for i in 0..10000 {
let _ = allocator.try_alloc(i);
}

black_box(allocator.arenas_len())
black_box(allocator.pools_len())
});
});

Expand All @@ -332,13 +334,13 @@ fn bench_dealloc_speed(c: &mut Criterion) {
// using `iter_batched` ensures we only measure the deallocation phase
for num_objects in [100, 500, 1000].iter() {
group.bench_with_input(
BenchmarkId::new("arena3", num_objects),
BenchmarkId::new("mempool3", num_objects),
num_objects,
|b, &num_objects| {
b.iter_batched(
|| {
let mut allocator =
oscars::alloc::arena3::ArenaAllocator::default().with_arena_size(65536);
oscars::alloc::mempool3::PoolAllocator::default().with_page_size(65536);

let mut ptrs = Vec::new();
for i in 0..num_objects {
Expand All @@ -347,12 +349,14 @@ fn bench_dealloc_speed(c: &mut Criterion) {
}
(allocator, ptrs)
},
|(mut allocator, ptrs)| {
|(mut allocator, ptrs): (_, _)| {
for ptr in ptrs {
allocator.free_slot(ptr.as_ptr().cast::<u8>());
unsafe {
allocator.free_slot_typed(ptr.as_ptr());
}
}
allocator.drop_dead_arenas();
black_box(allocator.arenas_len())
allocator.drop_empty_pools();
black_box(allocator.pools_len())
},
criterion::BatchSize::SmallInput,
);
Expand All @@ -370,12 +374,13 @@ fn bench_dealloc_speed(c: &mut Criterion) {

let mut ptrs = Vec::new();
for i in 0..num_objects {
let i: usize = i;
let ptr = allocator.try_alloc(i).expect("allocation failed");
ptrs.push(ptr);
}
(allocator, ptrs)
},
|(mut allocator, ptrs)| {
|(mut allocator, ptrs): (_, _)| {
for ptr in ptrs {
let mut heap_item_ptr = ptr.as_ptr();
unsafe {
Expand Down
14 changes: 7 additions & 7 deletions oscars/benches/oscars_vs_boa_gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn bench_alloc(c: &mut Criterion) {
for size in [10, 100, 1000].iter() {
group.bench_with_input(BenchmarkId::new("oscars", size), size, |b, &size| {
let collector = MarkSweepGarbageCollector::default()
.with_arena_size(65536)
.with_page_size(65536)
.with_heap_threshold(262144);

b.iter(|| {
Expand Down Expand Up @@ -56,7 +56,7 @@ fn bench_collection(c: &mut Criterion) {
b.iter_batched(
|| {
let collector = MarkSweepGarbageCollector::default()
.with_arena_size(65536)
.with_page_size(65536)
.with_heap_threshold(262144);
let mut roots = Vec::new();
for i in 0..num_objects {
Expand Down Expand Up @@ -110,7 +110,7 @@ fn bench_vec_create(c: &mut Criterion) {
size,
|b, &size| {
let collector = MarkSweepGarbageCollector::default()
.with_arena_size(65536)
.with_page_size(65536)
.with_heap_threshold(262144);

b.iter(|| {
Expand Down Expand Up @@ -153,7 +153,7 @@ fn bench_vec_ptrs(c: &mut Criterion) {
num_elements,
|b, &num_elements| {
let collector = MarkSweepGarbageCollector::default()
.with_arena_size(65536)
.with_page_size(65536)
.with_heap_threshold(262144);

b.iter(|| {
Expand Down Expand Up @@ -199,7 +199,7 @@ fn bench_mixed(c: &mut Criterion) {

group.bench_function("oscars", |b| {
let collector = MarkSweepGarbageCollector::default()
.with_arena_size(65536)
.with_page_size(65536)
.with_heap_threshold(131072);

b.iter(|| {
Expand Down Expand Up @@ -249,7 +249,7 @@ fn bench_pressure(c: &mut Criterion) {

group.bench_function("oscars", |b| {
let collector = MarkSweepGarbageCollector::default()
.with_arena_size(32768)
.with_page_size(32768)
.with_heap_threshold(65536);

b.iter(|| {
Expand Down Expand Up @@ -316,7 +316,7 @@ fn bench_deep(c: &mut Criterion) {

group.bench_function("oscars", |b| {
let collector = MarkSweepGarbageCollector::default()
.with_arena_size(131072)
.with_page_size(131072)
.with_heap_threshold(262144);

b.iter(|| {
Expand Down
2 changes: 0 additions & 2 deletions oscars/src/alloc/arena2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ impl From<LayoutError> for ArenaAllocError {
// This may also point to a different problem which is that the arena's as they
// currently exist do not have a lifetime, their lifetime is derived from the
// ArenaAllocator.
//
// But this may all be something to work on in arena3

// NOTE: Vec may actually be better here over link list.

Expand Down
Loading