Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mmap impl for MemoryInstance #45

Closed
pepyakin opened this issue Feb 8, 2018 · 8 comments
Closed

mmap impl for MemoryInstance #45

pepyakin opened this issue Feb 8, 2018 · 8 comments
Labels
enhancement New feature or request

Comments

@pepyakin
Copy link
Collaborator

pepyakin commented Feb 8, 2018

When the heap grows from, say, 1GB to 3GB, in naive vector implementation of MemoryInstance we need to reallocate vector, copy 1GB worth of data into the new vector and then fill with zeroes newly allocated 2GB worth of data.

On 64-bit machines (and maybe in some cases on 32-bit ones) we might allocate virtual memory up to memory instance's limit, and then just move the heap_end pointer upon call to grow, thus avoiding memory copying. Maybe it is possible to do zero-filling in a lazy way, i.e upon the first access to the page, however, i'm not sure how to do this in robust and portable manner.

@pepyakin pepyakin added the enhancement New feature or request label Mar 20, 2018
@eira-fransham
Copy link
Contributor

Lazily zero-filling can be done with calloc, but there is no sound way to call it in Rust right now.

@pepyakin
Copy link
Collaborator Author

Yeah, calloc could help with that, but wouldn't it be better to use directly memory mapping instead of dealing with allocator, since we know that we will allocate no less than 64k?

@eira-fransham
Copy link
Contributor

eira-fransham commented Apr 12, 2018

What we can do is make a huge mmap and then madvise WILLNEED on the bits that will be used (i.e. start of heap to end of heap) and then madvise WONTNEED on the rest. That way we don't need to worry about paying the cost of mmaps being paged to disk.

@eira-fransham
Copy link
Contributor

It looks like Rust has a seperate mechanism for allocating zeroed memory, which would imply that it uses calloc at least with alloc_system (jemalloc has calloc but it's unclear if it can access kernel magic like the system allocator, I'd guess not).

@eira-fransham
Copy link
Contributor

Just to come back to this, you can definitely calloc in stable Rust with:

use std::mem;

unsafe fn calloc(size: usize, count: usize) -> *mut u8 {
    let mut allocation: Vec<u8> = vec![0; size * count];
    let ptr = allocation.as_mut_ptr();
    assert!(ptr as usize % mem::size_of::<usize>() == 0);
    mem::forget(allocation);
    ptr
}

@pepyakin
Copy link
Collaborator Author

pepyakin commented Jul 3, 2019

Notes from working on #190

  1. calloc (the one from libsystem/libmalloc.dylib) actually uses bzero on macOS (tested on 10.14) which leads to massive slowdowns on some workloads.
  2. I am not sure why would we need madvise tricks if the memory allocated by mmap by default starts in uncommited state which means that this virtual memory is backed by neither swap nor physical memory.

@Robbepop
Copy link
Member

Robbepop commented Dec 9, 2021

On 64-bit machines (and maybe in some cases on 32-bit ones) we might allocate virtual memory up to memory instance's limit, and then just move the heap_end pointer upon call to grow, thus avoiding memory copying. Maybe it is possible to do zero-filling in a lazy way, i.e upon the first access to the page, however, i'm not sure how to do this in robust and portable manner.

#274 implements exactly this on 64-bit platforms. Therefore this issue can be closed as soon as it has been merged.

@Robbepop
Copy link
Member

Robbepop commented Dec 9, 2021

Closed since #274 has been merged.

@Robbepop Robbepop closed this as completed Dec 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants