Skip to content

Commit

Permalink
Pass affinity to allocator.
Browse files Browse the repository at this point in the history
  • Loading branch information
ankitbhrdwj committed Dec 5, 2023
1 parent 0d07ebc commit ab178bd
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 29 deletions.
31 changes: 21 additions & 10 deletions usr/init/src/dynrep/allocator.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use core::slice::from_raw_parts_mut;
use x86::bits64::paging::LARGE_PAGE_SIZE;
use lazy_static::lazy_static;
use core::sync::atomic::AtomicU8;
use core::sync::atomic::Ordering;

use log::info;
use core::{
Expand All @@ -10,47 +13,55 @@ use core::{
pub const BASE: u64 = 0x0510_0000_0000;
pub const MAX_FRAMES: u64 = 600;

lazy_static!{
static ref NODE_ID: AtomicU8 = AtomicU8::new(1);
}

#[derive(Clone, Copy)]
pub struct MyAllocator;

impl Default for MyAllocator {
fn default() -> Self {
impl MyAllocator {
fn allocate_pages(node_id: u8) {
let mut allocated = 0;
let node_offset = (node_id - 1) as u64 * LARGE_PAGE_SIZE as u64 * MAX_FRAMES;
while allocated < MAX_FRAMES {
// Allocate a large page of physical memory
// Note that even if you allocate a base page, behind the scenes a large page is allocated
// because DCM (and thus DiNOS) only allocates at large page granularity
// 1 is the client machine id we want to allocate from
let (frame_id, paddr) = vibrio::syscalls::PhysicalMemory::allocate_large_page(1)
let (frame_id, paddr) = vibrio::syscalls::PhysicalMemory::allocate_large_page(node_id as usize)
.expect("Failed to get physical memory large page");
info!("large frame id={:?}, paddr={:?}", frame_id, paddr);

// Map allocated physical memory into user space so we can actually access it.
unsafe {
vibrio::syscalls::VSpace::map_frame(frame_id, BASE + (allocated * LARGE_PAGE_SIZE as u64)).expect("Failed to map base page");
vibrio::syscalls::VSpace::map_frame(frame_id, BASE + node_offset + (allocated * LARGE_PAGE_SIZE as u64)).expect("Failed to map base page");
}
allocated += 1;
}
info!("# Allocated {} frames", allocated);
MyAllocator{}
info!("# Allocated {} frames on {}", allocated, node_id);
}
}

unsafe impl Allocator for MyAllocator {
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
let node_id = NODE_ID.fetch_add(1, Ordering::SeqCst);
let node_offset = (node_id - 1) as u64 * LARGE_PAGE_SIZE as u64 * MAX_FRAMES;
MyAllocator::allocate_pages(node_id);
info!("# Allocating {:?}", layout);
if layout.size() > LARGE_PAGE_SIZE * MAX_FRAMES as usize {
return Err(AllocError);
}

let slice = unsafe {from_raw_parts_mut(BASE as *mut u8, layout.size()) };
// DO we need to zero the memory for mapping to work?
let slice = unsafe {from_raw_parts_mut((BASE + node_offset) as *mut u8, layout.size()) };
Ok(NonNull::from(slice))
}

unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
info!("# Deallocating {:?}", layout);
vibrio::syscalls::VSpace::unmap(ptr.as_ptr() as u64, layout.size() as u64)
.expect("Failed to unmap base page");
for i in 0..MAX_FRAMES {
vibrio::syscalls::VSpace::unmap((BASE + (i * LARGE_PAGE_SIZE as u64)) as u64, LARGE_PAGE_SIZE as u64)
.expect("Failed to unmap base page");
}
}
}
46 changes: 27 additions & 19 deletions usr/init/src/dynrep/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct HashTable {

impl Default for HashTable {
fn default() -> Self {
let allocator = MyAllocator::default();
let allocator = MyAllocator{};
let map = HashMap::<u64, u64, DefaultHashBuilder, MyAllocator>::with_capacity_in(NUM_ENTRIES as usize, allocator);
HashTable { map }
}
Expand Down Expand Up @@ -60,27 +60,35 @@ impl Dispatch for HashTable {
}
}

pub fn userspace_dynrep_test() {
let replicas = NonZeroUsize::new(1).unwrap();
let nrht = NodeReplicated::<HashTable>::new(replicas, |_| { 0 }).unwrap();
let ttkn = nrht.register(0).unwrap();

let mut ops = 0;
let batch_size = 64;
fn run_bench(core_id : usize, replica: Arc<NodeReplicated<HashTable>>) {
let ttkn = replica.register(core_id).unwrap();
let mut random_key :u64 = 0;
let batch_size = 64;
let duration = 5;

let start = Instant::now();
while start.elapsed().as_secs() < 1 {
for i in 0..batch_size {
unsafe { rdrand64(&mut random_key) };
random_key = random_key % NUM_ENTRIES;
let _ = nrht.execute(OpRd::Get(random_key), ttkn).unwrap();
ops += 1;
}
let mut iterations = 0;
while iterations <= duration {
let mut ops = 0;
let start = Instant::now();
while start.elapsed().as_secs() < 1 {
for i in 0..batch_size {
unsafe { rdrand64(&mut random_key) };
random_key = random_key % NUM_ENTRIES;
let _ = replica.execute(OpRd::Get(random_key), ttkn).unwrap();
ops += 1;
}
}
info!(
"dynhash,{}", ops
);
iterations += 1;
}
info!(
"dynhash,{}", ops
);
}

pub fn userspace_dynrep_test() {
let replicas = NonZeroUsize::new(1).unwrap();
let nrht = Arc::new(NodeReplicated::<HashTable>::new(replicas, |_| { 0 }).unwrap());
let core_id = 0;
run_bench(core_id, nrht.clone());
info!("dynrep_test OK");
}

0 comments on commit ab178bd

Please sign in to comment.