5

I'm trying to understand the relation between huge page size and how data is actually being written to RAM.

What happens when a process uses a 1GB huge page - does writing occur in 1GB chunks? I guessing I'm completely wrong with this assumption?

Faheem Mitha
  • 34,649
  • 32
  • 119
  • 183
BlackBeret
  • 85
  • 5

2 Answers2

5

Huge pages are for allocating chunks of memory, not writing them.

Normally when applications need large amounts of memory, they have to allocate many "pages". A page is simply a chunk of physical memory. Normally this chunk is only a few KB. So when an application is doing a lot of memory intensive operations that span many pages, it's expensive for the kernel to have to translate all those virtual memory pages to physical memory.

To optimize this, the kernel offers huge pages, which are basically allocations larger than the default page size. So instead of having to allocate thousands of pages, it just gets a few. The reads and writes are still of whatever size is being read or written. If the application writes a 10 byte string into a huge page, it's still going to be a 10 byte write.

phemmer
  • 70,657
  • 19
  • 188
  • 223
  • Thanks Patrick. I understand the general motivation for using huge pages btw and the relation to TLB etc. Following your example, what happens if an app writes a 10 byte string to a 1GB huge page? 10 byte will be used and the rest is free for additional writing? If so, how does the app knows the physical address for the 10 bytes, within the 1GB, what manages the address ranges within a huge page? – BlackBeret Jun 05 '14 at 15:07
  • If the app writes 10 bytes, 10 bytes is written. Applications obtain memory in chunks. If it requests a 1 byte allocation, it will receive a chunk. If that chunk is 8kb, then it receives 8kb even though it only needs 1 byte. Then when it allocates a second byte, it just grabs another byte from that existing 8kb. It doesn't get another chunk. The app doesn't know the physical address of the memory. That's the kernel's job. – phemmer Jun 05 '14 at 15:33
  • My mistake, the app/process obviously doesn't know anything about physical memory addresses. Still I can't clearly understand what's the benefit of a huge page, if process mem. r/w are in chunks smaller then the huge page size, as this means an additional level of translation, virtual mem. chunk --> chunk within huge page space? I probably miss something.. – BlackBeret Jun 05 '14 at 16:04
  • Lets say the application has an 8mb string, and the page size is 8kb, that'll require traversing a thousand pages. Where as if you've got huge pages on, that will be contained within a single page. – phemmer Jun 05 '14 at 16:07
5

There is more than one definition of the chunk size for memory writes. You could consider it to be:

  • the width of the store instruction (store byte, store word, …), typically 1, 2, 4, 8 or 16;
  • the width of a cache line, typically something like 16 or 64 bytes (and different cache levels may have different line widths);
  • the width of the memory bus, which is not directly observable in software;
  • and possibly a few more reasonable senses.

None of these are related to a page size.

The page size is an attribute of a page in the MMU. The MMU translates virtual addresses (used by programs) into physical addresses (which designate a physical location in memory). The process to translate a virtual address into a physical address goes something like this:

  • Look up the address of the first-level descriptor table.
  • Extract the highest-order bits of the virtual address and use them as an index in the first-level descriptor table.
  • Decode the L1 descriptor at that index, which yields the address of a second-level descriptor table.
  • Extract more bits from the virtual address and use them as an index in the second-level descriptor table.
  • Decode the L2 descriptor at that index, which yields the address of the start of a page. A page is a unit of physically contiguous memory which is described by one entry in the MMU table.
  • Mask the remaining bits of the virtual address with the page start address to get the physical address.

Common 32-bit architectures go through two table levels; common 64-bit architectures go through 3. Linux supports up to 4 levels.

Some CPU architectures support making some pages larger, going through fewer levels of indirection. This makes accesses faster, and keeps the size of the page tables down, at the expense of less flexibility in memory allocation. The time gain is minimal for most applications, but can be felt with some performance-sensitive applications that don't benefit from the flexibility of small pages, such as databases. Huge pages are pages which go through fewer levels than the normal amount, and are correspondingly larger.

The software that is using large pages typically requests them specifically (via flags to mmap, see how is page size determined in virtual address space? for a few more details). After this initial request, it doesn't need to know or care about the page size. In particular, memory accesses are handled by the MMU: software is not involved at the time of access.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • Very useful answer. Thanks. In your other answer you stated "A larger page size means more waste when a page is partially used, so the system runs out of memory sooner." From this I conclude that it would be most efficient for a process to ask for a 1gb huge page when it has a s close as possible to a 1gb of data to actually write to ram, otherwise it would be a waste of memory space, just the same as with disk cluster size, and that you cannot "append" data to a huge page? – BlackBeret Jun 08 '14 at 09:05
  • @BlackBeret Huge pages are typically used by programs that know from the start that they're using a large amount of memory anyway, such as databases and some large calculations. Indeed, a page cannot be shared between processes, which would make 1GB pages unsuitable for most applications on today's computers. – Gilles 'SO- stop being evil' Jun 08 '14 at 10:54
  • Currently 57-bit address in x86-64 needs [5 levels](https://en.wikipedia.org/wiki/Intel_5-level_paging) and Linux also supports that – phuclv Jan 07 '21 at 08:44