Master the fundamental concepts of memory management through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksHuge pages (commonly 2 MB on x86) reduce TLB misses for large contiguous mappings. Each TLB entry covers more virtual range, so scanning a 1 GB array touches fewer translation lookups.
Comparison points:
512 entries per GB; 2 MB needs 1mmap with MAP_HUGETLB or madvise(MADV_HUGEPAGE)For example, a random walk across a 2 GB buffer may show 40% fewer dTLB misses with transparent huge pages enabled.
Databases like PostgreSQL and Oracle explicitly enable Linux huge pages (hugetlbfs or Transparent Huge Pages) to cut TLB misses when scanning gigabytes of buffer cache during large sequential scans. Get the trade-off backwards , using 2MB pages for small, sparse allocations , and you waste RAM through internal fragmentation instead of saving CPU cycles.
Before you call the implementation done, walk failure modes on purpose. Test empty structures, single-element edge cases, maximum concurrency, and errno paths that must not crash the program. OS code usually fails in production when happy-path tests pass but invariants break under contention or memory pressure.
Keep structures small and name fields after kernel counterparts when possible. That lets you read man pages and kernel source side by side while you work. Print observable events during development; remove noisy logs once tests pass reliably.
You will benchmark identical workloads with normal and huge pages, reading /proc/self/smaps or perf counters. The task asks you to explain when huge pages hurt due to internal fragmentation.
Decide when huge pages pay off. A 2 MiB page replaces 512 ordinary 4 KiB pages: one TLB entry then covers 512 times more memory, and the page tables shrink by a factor of 512. The costs are that memory is handed out in 2 MiB pieces (internal fragmentation) and that huge-page TLBs are smaller. Build the analysis a performance engineer does before enabling hugetlbfs or transparent huge pages for a workload.
cLoading…
⌈BYTES / P⌉, page-table bytes = 8 × pages (one 8-byte entry per page, upper levels ignored), and waste = pages × P − BYTES.random (uniform accesses over the data): max(0, 1 − reach / BYTES);sequential (64-byte steps): one miss per page, i.e. 64 / P, but 0 if the whole data set fits in the reach.walk cycles per access.Verdict: use 2M pages if the 4K miss rate exceeds the 2M miss rate by more than 0.01 (one percentage point) and the 2M waste is at most 10% of BYTES; otherwise stay with 4K pages, with the reason (no TLB benefit) or (too much waste) (the first failing check, in that order).
cLoading…
Sizes: under 1 KiB print N B; under 1 MiB print X.X KiB; under 1 GiB print X.X MiB; otherwise X.X GiB. Miss rates are percentages with two decimals, and costs have one decimal. Only the 2M line shows waste. Print a blank line between data sets.
Input:
cLoading…
Output:
cLoading…
analyse(bytes, page_size, entries, pattern) function returning pages, table bytes, reach, waste, miss rate and cost, called once per page size.unsigned long long), floating point only for the rates.Hidden tests cover a small data set that fits both TLBs, a sequential scan, a data set just over 2 MiB (huge pages waste almost half), several gigabytes, and a moderate random set where both TLBs miss.