[gegl] buffer: over-trim cache when it fills up frequently
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] buffer: over-trim cache when it fills up frequently
- Date: Sun, 9 Dec 2018 20:56:45 +0000 (UTC)
commit a64637b3d10e5c1f1025315433d638e3fc732823
Author: Ell <ell_se yahoo com>
Date: Sun Dec 9 15:01:52 2018 -0500
buffer: over-trim cache when it fills up frequently
Trimming the tile cache can have a high overhead, since we need to
scan the tile list for an eligible/worthwhile tile to trim. If
trimming happens frequently, we end up re-scanning the list each
time.
In order to amortize the cost of scanning the tile list, over-trim
the cache by a certain amount, instead of only trimming the excess.
When trimming happens frequently, we progressively increase the
over-trimming ratio, up to 50% of the cache size limit.
gegl/buffer/gegl-tile-handler-cache.c | 47 +++++++++++++++++++++++++++--------
1 file changed, 36 insertions(+), 11 deletions(-)
---
diff --git a/gegl/buffer/gegl-tile-handler-cache.c b/gegl/buffer/gegl-tile-handler-cache.c
index 547c9cf65..5b3719f8f 100644
--- a/gegl/buffer/gegl-tile-handler-cache.c
+++ b/gegl/buffer/gegl-tile-handler-cache.c
@@ -33,6 +33,11 @@
#define GEGL_DEBUG_CACHE_HITS
*/
+#define GEGL_CACHE_TRIM_INTERVAL 100000 /* microseconds */
+#define GEGL_CACHE_TRIM_RATIO_MIN 0.01
+#define GEGL_CACHE_TRIM_RATIO_MAX 0.50
+#define GEGL_CACHE_TRIM_RATIO_RATE 2.0
+
typedef struct CacheItem
{
GeglTile *tile; /* The tile */
@@ -512,16 +517,34 @@ gegl_tile_handler_cache_has_tile (GeglTileHandlerCache *cache,
static gboolean
gegl_tile_handler_cache_trim (GeglTileHandlerCache *cache)
{
- GList *link;
- static guint counter;
+ GList *link;
+ gint64 time;
+ static gint64 last_time;
+ static gdouble ratio = GEGL_CACHE_TRIM_RATIO_MIN;
+ guint64 target_size;
+ static guint counter;
cache = NULL;
link = NULL;
g_mutex_lock (&mutex);
- while ((guintptr) g_atomic_pointer_get (&cache_total) >
- gegl_buffer_config ()->tile_cache_size)
+ time = g_get_monotonic_time ();
+
+ if (time - last_time < GEGL_CACHE_TRIM_INTERVAL)
+ {
+ ratio = MIN (ratio * GEGL_CACHE_TRIM_RATIO_RATE,
+ GEGL_CACHE_TRIM_RATIO_MAX);
+ }
+ else if (time - last_time >= 2 * GEGL_CACHE_TRIM_INTERVAL)
+ {
+ ratio = GEGL_CACHE_TRIM_RATIO_MIN;
+ }
+
+ target_size = gegl_buffer_config ()->tile_cache_size;
+ target_size -= target_size * ratio;
+
+ while ((guintptr) g_atomic_pointer_get (&cache_total) > target_size)
{
CacheItem *last_writable;
GeglTile *tile;
@@ -553,11 +576,7 @@ gegl_tile_handler_cache_trim (GeglTileHandlerCache *cache)
! g_rec_mutex_trylock (&cache->tile_storage->mutex));
if (! cache)
- {
- g_mutex_unlock (&mutex);
-
- return FALSE;
- }
+ break;
link = g_queue_peek_tail_link (&cache->queue);
}
@@ -620,9 +639,11 @@ gegl_tile_handler_cache_trim (GeglTileHandlerCache *cache)
if (cache)
g_rec_mutex_unlock (&cache->tile_storage->mutex);
+ last_time = g_get_monotonic_time ();
+
g_mutex_unlock (&mutex);
- return TRUE;
+ return cache != NULL;
}
static void
@@ -1004,7 +1025,11 @@ gegl_buffer_config_tile_cache_size_notify (GObject *gobject,
GParamSpec *pspec,
gpointer user_data)
{
- gegl_tile_handler_cache_trim (NULL);
+ if ((guintptr) g_atomic_pointer_get (&cache_total) >
+ gegl_buffer_config () ->tile_cache_size)
+ {
+ gegl_tile_handler_cache_trim (NULL);
+ }
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]