diff options
author | Phil Jones <philj56@gmail.com> | 2022-08-09 11:12:13 +0100 |
---|---|---|
committer | Phil Jones <philj56@gmail.com> | 2022-08-09 12:30:24 +0100 |
commit | 81025108db445ab31d7506a88e8919a5eebcadcb (patch) | |
tree | 19901e9897b7305fe553089cd05837295ce4bbfc | |
parent | 33ec439ca9d1f6a2467703333d8a6189e42bd446 (diff) |
Add Transparent HugePage support on Linux.
Currently, this is unlikely to be enabled for shared memory mappings on
any user's system, so will not make a difference. If
`/sys/kernel/mm/transparent_hugepage/shmem_enabled` is set to `advise`
or higher, however, this commit should enable the use of hugepages. This
can greatly speed up startup for large windows - for a 2880x1800
fullscreen window on my laptop, enabling hugepages halves startup time.
From the kernel mailing lists, it looks like there's some work towards
allowing applications to opt-in to THP support regardless of whether
they're enabled, via `madvise(MADV_COLLAPSE)`, so this may be more
useful in future.
-rw-r--r-- | src/shm.c | 12 | ||||
-rw-r--r-- | src/surface.c | 14 |
2 files changed, 26 insertions, 0 deletions
@@ -34,7 +34,19 @@ static int create_shm_file(void) int shm_allocate_file(size_t size) { +#ifdef __linux__ + /* + * On linux, we can just use memfd_create(). This is both simpler and + * potentially allows usage of Transparent HugePages, which speed up + * the first paint of a large screen buffer. + * + * This isn't available on *BSD, which we could conceivably be running + * on. + */ + int fd = memfd_create("wl_shm", 0); +#else int fd = create_shm_file(); +#endif if (fd < 0) return -1; int ret; diff --git a/src/surface.c b/src/surface.c index e640c40..b8ed88e 100644 --- a/src/surface.c +++ b/src/surface.c @@ -32,6 +32,20 @@ void surface_init( MAP_SHARED, surface->shm_pool_fd, 0); +#ifdef __linux__ + /* + * On linux, ask for Transparent HugePages if available and our + * buffer's at least 2MiB. This can greatly speed up the first + * cairo_paint() by reducing page faults, but unfortunately is disabled + * for shared memory at the time of writing. + * + * MADV_HUGEPAGE isn't available on *BSD, which we could conceivably be + * running on. + */ + if (surface->shm_pool_size >= (2 << 20)) { + madvise(surface->shm_pool_data, surface->shm_pool_size, MADV_HUGEPAGE); + } +#endif surface->wl_shm_pool = wl_shm_create_pool( wl_shm, surface->shm_pool_fd, |