diff --git a/chapters/compute/copy-on-write/drills/questions/huge-page-allocation.md b/chapters/compute/copy-on-write/drills/questions/huge-page-allocation.md new file mode 100644 index 0000000000..008ba2536f --- /dev/null +++ b/chapters/compute/copy-on-write/drills/questions/huge-page-allocation.md @@ -0,0 +1,25 @@ +# Huge Page Allocation + +## Question Text + +How many page faults are registered between step 1 and step 2 after changing `NUM_PAGES` to 1024? + +## Question Answers + +- 1024 + +- 1023 + +- 0 + ++ 2 + +- 512 + +## Feedback + +The code maps 1024 pages of 4 kb each for a total of 4 mb. +The kernel attempts to merge them into 2 huge pages of 2 mb each. +This way, we only need 2 TLB entries (instead of 1024) to manage them. +Those 2 entries are then mapped to physical memory, causing the page faults. +You may read more about THP in these [docs from RedHat](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/6/html/performance_tuning_guide/s-memory-transhuge) or from the [Linux kernel](https://www.kernel.org/doc/Documentation/vm/transhuge.txt) diff --git a/chapters/compute/copy-on-write/guides/fork-faults/README.md b/chapters/compute/copy-on-write/guides/fork-faults/README.md index aa06880aaa..c44c465e6a 100644 --- a/chapters/compute/copy-on-write/guides/fork-faults/README.md +++ b/chapters/compute/copy-on-write/guides/fork-faults/README.md @@ -21,6 +21,31 @@ The first one still corresponds to the parent. [Quiz 2](../tasks/questions/child-faults-after-write.md) +As a **bonus**, you are going to learn about a Linux memory optimization mechanism called [Transparent Huge Pages (THP)](https://docs.kernel.org/admin-guide/mm/transhuge.html) and its effects on the TLB. +If we were to `mmap`, for example, 1024 _contiguous_ pages (of 4 kb each) in memory, they would occupy 1024 entries in the page table and, in turn, in the TLB. +However, they can be managed much more efficiently using THP. +It works by taking that memory region and remapping it using **huge pages** of a fixed size each (for example: 2mb). +This way, we may address the same memory using a lot less TLB entries, boosting performance. + +To enable this mechanism on your system, run the following command: + +```console +student@os:~/.../fork-faults/support$ sudo bash -c "echo always > /sys/kernel/mm/transparent_hugepage/enabled" +``` + +No need to worry about breaking anything. +It lasts only for this session (i.e. it resets on reboot). + +Now, enable THP for pages of a specific size, such as 2 mb: + +```console +student@os:~/.../fork-faults/support$ sudo bash -c "echo always > /sys/kernel/mm/transparent_hugepage/hugepages-2048kB/enabled" +``` + +Set `NUM_PAGES` to 1024 in `fork-faults.c`, recompile the program and see the results. + +[Quiz 3](../tasks/questions/huge-page-allocation.md) + Now it should be clear how demand paging differs from copy-on-write. Shared memory is a similar concept. It's a way of marking certain allocated pages so that copy-on-write is disabled. diff --git a/chapters/compute/copy-on-write/guides/fork-faults/support/fork_faults.c b/chapters/compute/copy-on-write/guides/fork-faults/support/fork_faults.c index 4db7478e57..6144ef4008 100644 --- a/chapters/compute/copy-on-write/guides/fork-faults/support/fork_faults.c +++ b/chapters/compute/copy-on-write/guides/fork-faults/support/fork_faults.c @@ -9,7 +9,7 @@ #include "utils/utils.h" -#define NUM_PAGES 1024 +#define NUM_PAGES 256 static void wait_for_input(const char *msg) { diff --git a/config.yaml b/config.yaml index ad19dd9289..2ff8ec4144 100644 --- a/config.yaml +++ b/config.yaml @@ -337,6 +337,7 @@ docusaurus: - Semaphore Equivalent: semaphore-equivalent.md - Coarse vs Granular Critical Section: coarse-vs-granular-critical-section.md - Not Race Condition: not-race-condition.md + - Huge Page Allocation: huge-page-allocation.md - Lab 6 - Multiprocess and Multithread: lab6.md - Lab 7 - Copy-on-Write: lab7.md - Lab 8 - Synchronization: lab8.md