Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Full Page Malloc

I am trying to optimize the memory allocation of my program by using entire pages at a time.

I am grabbing the page size like this: sysconf(_SC_PAGESIZE); then calculating the total number of elements that will fit in a page like this: elements=pageSize/sizeof(Node);

I was thinking that when I actually go to malloc my memory I would use malloc(elements*sizeof(Node)); It seems like the multiplication and division of sifeof(Node) would cancel out, but with integer division, I do not believe that that is the case.

Is this the best way to malloc an entire page at a time?

Thanks

like image 933
Nathan Tornquist Avatar asked Feb 21 '13 15:02

Nathan Tornquist


People also ask

Does malloc allocate a page?

malloc() must always add some metadata to every allocation, so if you do malloc(4096) it will definitely allocate more than a single page. mmap() , on the other hand, is the kernel's API to map pages into your address space.

Does malloc cause page fault?

When allocating memory with malloc and new , the memory is not loaded into the physical memory immediately. Instead, the memory is placed in RAM only when the application writes to the memory address. The process of moving pages into physical memory incurs page faults.

How big can you malloc?

The malloc() function reserves a block of storage of size bytes. Unlike the calloc() function, malloc() does not initialize all elements to 0. The maximum size for a non-teraspace malloc() is 16711568 bytes.

How do I free space allocated by malloc?

When you no longer need a block that you got with malloc , use the function free to make the block available to be allocated again. The prototype for this function is in stdlib. h .


2 Answers

The malloc function doesn't have any concept of pagesize. Unless you are allocating pages that are ALSO aligned to a page-boundary, you will not get ANY benefit from calling malloc in this way. Just malloc as many elements as you need, and stop worrying about micro-optimising something that almost certainly won't give you any benefit at all.

Yes, the Linux kernel does things like this all the time. There are two reasons for that:

  1. You don't want to allocate blocks LARGER than a page, since that significantly increases the risk of allocation failure.
  2. The kernel allocation is made on a per-page basis, rather than like the C library, which allocates a large amount of memory in one go, and then splits it into small components.

If you really want to allocate page-size amount of memory, then use the result from sysconf(_SC_PAGESIZE) as your size argument. But it is almost certain that your allocation straddles two pages.

like image 129
Mats Petersson Avatar answered Sep 28 '22 03:09

Mats Petersson


Your computation elements=pageSize/sizeof(Node); doesn't take account of the malloc() metadata that are added to any block/chunk of memory returned by malloc(). In many cases, malloc() will return a memory block likely aligned at least on min(sizeof(double),2 * sizeof(void *)) boundary (32 bytes is becoming quite common btw ...). If malloc() gets a memory block aligned on a page, adds its chunk (with padding), and you write a full page size of data, the last bytes are off the first page: so you're ending up using 2 pages.

Want a whole page, just for you, without concerns about wasting memory, without using mmap() / VirtualAlloc() as suggested in the comments ? Here you are:

int ret;
void *ptr = NULL;
size_t page_size = sysconf(_SC_PAGESIZE);

ret = posix_memalign(&ptr, page_size, page_size);
if (ret != 0 || ptr == NULL) {
    fprintf(stderr, "posix_memalign failed: %s\n", strerror(ret));
}

By the way, this is probably about micro-optimization. You probably still haven't checked your Node have a size multiple of a cache-line, nor how to improve cache-locality, nor found a way to reduce memory fragmentation. So you're probably going in the wrong way: make it works first, profil, optimize your algorithms, profil, micro-optimize at the last option.

like image 33
Yann Droneaud Avatar answered Sep 28 '22 03:09

Yann Droneaud