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

How can mimalloc manage a piece of allocated memory? #922

Open
CS0522 opened this issue Aug 8, 2024 · 6 comments
Open

How can mimalloc manage a piece of allocated memory? #922

CS0522 opened this issue Aug 8, 2024 · 6 comments

Comments

@CS0522
Copy link

CS0522 commented Aug 8, 2024

I have already allocated a piece of big memory by mmap, the memory size (as MEM_SIZE) is large, so I want to use it as a memory pool, or a heap, so that I can use the memory efficiently. For example, every time I want a piece of memory (large but not larger than MEM_SIZE), I can just easily use a function to allocate and get a void *, and release this pointer later, and the pool/heap can collect this memory. An example:

// allocate memory
void* mem_ptr = mmap(NULL, MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

// create a heap or memory pool based on the allocated memory
// is there a function works as create_heap(...)?
auto my_heap = create_heap(mem_ptr, MEM_SIZE);

// when I need to get some memory
void* mem_for_var1 = alloc(my_heap, mem_size_for_var1);
auto var1 = new (mem_for_var1) float();

// use var1

// release
...

And if there exists any memory allocator or memory pool library for C++ that can work as above, it is appreciated if you could tell me and leave some examples or the documents of it.

@daanx
Copy link
Collaborator

daanx commented Aug 12, 2024

Yes, mimalloc has mi_manage_os_memory for this purpose:

bool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node);

This will add the memory area to the mimalloc arena's from which it will allocate its memory (use numa_node=-1 for no NUMA preference). There is no need for a specific heap, just mi_malloc will work. It is best if the area is as large as possible such that mimalloc can manage it most effectively with regard to fragmentation.

Hope this helps,
Daan

ps. There is also an extended api, mi_manage_os_memory_ex
to reserve "exclusive" memory that can only be used with heaps attached to such memory (mi_heap_new_in_arena) but I don't think that is what you are asking? (this is used for example to implement compressed pointers in the Koka language using a 4GiB exclusive area for language allocations)

@CS0522
Copy link
Author

CS0522 commented Aug 14, 2024

Thanks very much for your help! It really does me a favor. mimalloc is very useful, and my project cannot be done without it.

@gulmezmerve
Copy link

gulmezmerve commented Aug 16, 2024

@daanx I am a bit confused about how the mimalloc uses the process memory initially. As far as I know, when the process starts, it already reserves some memory area for the heap, and libc uses sbrk to extend.

But I can track mimalloc down, I understand that it does mmap do manage the memory, right?

Also, what is the alignment-requirement for the mimalloc?

@daanx
Copy link
Collaborator

daanx commented Aug 22, 2024

Ah, mimalloc generally does not use sbrk (as that doesn't allow returning (purging) memory back to the OS), and we try to use mmap on most unix systems. See https://github.com/microsoft/mimalloc/blob/dev/src/prim/unix/prim.c for the primitives. Mimalloc allocates it's OS memory with 4MiB alignment (on 64-bit systems).

@gulmezmerve
Copy link

thank you for the clarification!

@MohammadKhalaji
Copy link

MohammadKhalaji commented Oct 10, 2024

Hi @daanx

Thank you for having responded in the issue and similar issues.

I have a similar problem to the OP, and I can't get mimalloc to allocate from the mmapped file, even with mi_reserve_os_memory...

Here's the code (I've removed sanity and error message checks for brevity)

#define FILE_SIZE (16 * 1024 * 1024) // 16MB

fd = open("mmapped_file.txt", O_RDWR | O_CREAT, 0666);
char *file_in_memory = mmap(NULL, FILE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_32BIT, fd, 0);
int reserveRet = mi_reserve_os_memory(FILE_SIZE, false, true);
int manageRet = mi_manage_os_memory(file_in_memory, FILE_SIZE, true, false, false, -1);

void *p = mi_malloc(1 * 1024 * 1024); // 1MB
void *q = mi_malloc(1 * 1024 * 1024); // 1MB
void *r = mi_malloc(1 * 1024 * 1024); // 1MB
void *s = mi_malloc(1 * 1024 * 1024); // 1MB

printf("base: %p\n", file_in_memory);
printf("p   : %p\n", p);
printf("q   : %p\n", q);
printf("r   : %p\n", r);
printf("s   : %p\n", s);

Outputs:

base: 0x40000000
p   : 0x20000000200
q   : 0x20000140200
r   : 0x20000280200
s   : 0x20000400200

How do I make sure mimalloc is using my mmapped file?

I'll try your solution in #730 next, but I'm not sure where to find MIMALLOC_RESERVE_OS_MEMORY or MIMALLOC_LIMIT_OS_ALLOC

Edit: The #730 solution didn't work either, sadly. Iused mi_reserve_os_memory_ex and mi_heap_new_in_arena as well as mi_heap_set_default and mi_heap_malloc as instructed, and they're returning valid values (no errors).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants