From e777adf98534394ca005a1ca541696b06c791aa6 Mon Sep 17 00:00:00 2001 From: MahouShoujoMivutilde <14999778+MahouShoujoMivutilde@users.noreply.github.com> Date: Sat, 1 Jan 2022 11:55:59 +0300 Subject: [PATCH] Allow setting cache size based on memory percentage (#184) The problem: 1. For the most people imlib2's default 4MiB is unreasonably low; 2. Hardcoding cache size to ~256MiB has performance benefits and doesn't increase RAM usage too much on relatively modern systems; 3. But we can't do that, because that would be detrimental to low spec systems that (apparently) not (?) building nsxiv from source, as been discussed #171 Solution: Calculate cache size based on total memory. Default is set as 3%, which means: * ~245MiB for 8GiB * ~30MiB for 1GiB * and so on CACHE_SIZE_LIMIT (256MiB by default) sets the highest possible value. And in case we cannot determine the total memory (e.g since _SC_PHYS_PAGES isn't POSIX) use CACHE_SIZE_FALLBACK (32MiB by default) instead. Co-authored-by: NRK --- config.def.h | 11 +++++++---- image.c | 20 +++++++++++++++++++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/config.def.h b/config.def.h index 107c6ac..6e4b942 100644 --- a/config.def.h +++ b/config.def.h @@ -62,11 +62,14 @@ static const bool ANTI_ALIAS = true; */ static const bool ALPHA_LAYER = false; -/* cache size for imlib2, in bytes. For backwards compatibility reasons, the - * size is kept at 4MiB. For most users, it is advised to pick a value close to - * or above 128MiB for better image (re)loading performance. +/* percentage of memory to use for imlib2's cache size. + * 3 means use 3% of total memory which is about 245MiB on 8GiB machine. + * 0 or less means disable cache. + * 100 means use all available memory (but not above CACHE_SIZE_LIMIT). */ -static const int CACHE_SIZE = 4 * 1024 * 1024; /* 4MiB */ +static const int CACHE_SIZE_MEM_PERCENTAGE = 3; /* use 3% of total memory for cache */ +static const int CACHE_SIZE_LIMIT = 256 * 1024 * 1024; /* but not above 256MiB */ +static const int CACHE_SIZE_FALLBACK = 32 * 1024 * 1024; /* fallback to 32MiB if we can't determine total memory */ #endif #ifdef _THUMBS_CONFIG diff --git a/image.c b/image.c index 2cec163..800321a 100644 --- a/image.c +++ b/image.c @@ -46,12 +46,30 @@ enum { DEF_WEBP_DELAY = 75 }; #define ZOOM_MIN (zoom_levels[0] / 100) #define ZOOM_MAX (zoom_levels[ARRLEN(zoom_levels)-1] / 100) +static int calc_cache_size(void) +{ + int cache; + long pages, page_size; + + if (CACHE_SIZE_MEM_PERCENTAGE <= 0) + return 0; + + pages = sysconf(_SC_PHYS_PAGES); + page_size = sysconf(_SC_PAGE_SIZE); + if (pages < 0 || page_size < 0) + return CACHE_SIZE_FALLBACK; + cache = (pages/100) * CACHE_SIZE_MEM_PERCENTAGE; + cache *= page_size; + + return MIN(cache, CACHE_SIZE_LIMIT); +} + void img_init(img_t *img, win_t *win) { imlib_context_set_display(win->env.dpy); imlib_context_set_visual(win->env.vis); imlib_context_set_colormap(win->env.cmap); - imlib_set_cache_size(CACHE_SIZE); + imlib_set_cache_size(calc_cache_size()); img->im = NULL; img->win = win;