Expand description
§Columned
A single, contiguous, allocation for multiple objects, that live the same lifetimes. This reduces multiple allocations, to a single one. This may improve performance, as multiple memory allocations may need multiple, slow, system calls. Further, this may alleviate memory fragmentation.
§Working Principle
Guard manages a contiguous allocation of memory. Each slice has a pointer to this contiguous allocation. The following figure illustrates the working principle.
Guard
+--------+--------+
| 0x0123 | ... |
+--------+--------+
ptr
|
V
Heap +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0.1 | 3.2 | 5 | 7 | 20 | 6 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
^ ^
| |
ptr len ptr len
+--------+--------+ +--------+--------+
| 0x0123 | 2 | | 0x012b | 4 |
+--------+--------+ +--------+--------+
Guarded<[f32]> Guarded<[u16]>The lifetimes of the type system will ensure that the Guard will outlive any slice.
§Examples
§Simple Example
use std::mem::MaybeUninit;
use columned::{Guard, GuardedBuilder};
fn main() {
//Declare size and initialization of the slices.
let mut xs = GuardedBuilder::<[u64]>::new_slice(10);
let mut ys = GuardedBuilder::<[u64]>::new_slice(10);
let mut sums = GuardedBuilder::<[MaybeUninit<u64>]>::new_slice(10);
//Initialize a "Guard", which will manage the allocation.
let mut guard: Guard = Guard::default();
guard
.subscriber()
.subscribe(&mut xs)
.subscribe(&mut ys)
.subscribe(&mut sums)
.allocate()
.unwrap();
let xs = xs.build_from_fn(|i| i as u64);
let ys = ys.build_from_fn(|i| i as u64);
let mut sums = sums.build_uninit();
//drop(guard); // This would cause a compilation error
for ((mut sum, x), y) in sums.iter_mut().zip(xs.iter()).zip(ys.iter()) {
sum.write(x + y);
}
let sums = unsafe { sums.assume_init() };
for (i, sum) in sums.iter().enumerate() {
assert_eq!(*sum, 2 * i as u64);
}
}§Structure of Array Example
use std::mem::MaybeUninit;
use columned::{Guard, Guarded, GuardedBuilder, Subscriber};
// The structure-of-array
struct Bodies<'a> {
//Position
position: Vec3<'a>,
//Velocity
velocity: Vec3<'a>,
//Mass
mass: &'a mut [f32],
}
impl <'a> Bodies<'a> {
fn new(n: usize, subscriber: Subscriber<'a, '_>, f: impl FnOnce(Subscriber<'a, '_>)) -> Self {
let mut mass = GuardedBuilder::<[f32]>::new_slice(n);
let subscriber = subscriber
.subscribe(&mut mass);
let mut position = Vec3::default();
let mut velocity = Vec3::new(n, subscriber, |subscriber| {
position = Vec3::new(n, subscriber, f);
});
let mass = mass.build_default().into_mut();
Self {
position,
velocity,
mass
}
}
}
#[derive(Default)]
struct Vec3<'a> {
x: &'a mut [f32],
y: &'a mut [f32],
z: &'a mut [f32],
}
impl <'a> Vec3<'a> {
fn new(n: usize, subscriber: Subscriber<'a, '_>, f: impl FnOnce(Subscriber<'a, '_>)) -> Self {
let mut x = GuardedBuilder::<[f32]>::new_slice(n);
let mut y = GuardedBuilder::<[f32]>::new_slice(n);
let mut z = GuardedBuilder::<[f32]>::new_slice(n);
let subscriber = subscriber
.subscribe(&mut x)
.subscribe(&mut y)
.subscribe(&mut z);
f(subscriber);
let x = x.build_default().into_mut();
let y = y.build_default().into_mut();
let z = z.build_default().into_mut();
Vec3 {
x,
y,
z,
}
}
}
fn main() {
let mut guard = Guard::new();
let bodies = Bodies::new(100, guard.subscriber(), |subscriber| {
subscriber.allocate().unwrap()
});
//drop(guard); // would cause a compile error
// use bodies here ...
}Structs§
- Guard
Guardmanages and owns a contiguous allocation of memory. AGuardshould be used only once for [allocate], [allocate_in], otherwise the allocation will fail.- Guarded
- A slice, which memory is managed by a [Guard].
- Guarded
Builder - Prepare an allocation of a slice, by specifying its size and its initialization function. The initialization function will be called upon the call of [allocate], [allocate_in], [with_allocation] or [with_allocation_in].
- Single
Allocation - Allocator which will allocate only once at a time.
- Subscriber
- Struct used to “subscribe” multiple [GuardedSliceBuilder] for their [crate::GuardedSlice] to be allocated into a single contiguous allocation.