[Mesa-dev] [PATCH 3/3] draw/llvm: keep some unused items in llvm cache

Frank Henigman fjhenigman at google.com
Sun Jun 16 10:59:05 PDT 2013


Cache items are small, maybe 10K on average, and take a relatively long
time to create, so it's worth keeping some unused ones around in case
they are needed again.  When an upper limit is reached, delete the one
that has been unused the longest.
---
 src/gallium/auxiliary/draw/draw_llvm.c | 32 ++++++++++++++++++++++++++++++--
 src/gallium/auxiliary/draw/draw_llvm.h | 12 ++++++++++++
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index a90b471..6249ec0 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -61,6 +61,8 @@
 
 #define DEBUG_STORE 0
 
+#define LLVM_CACHE_MAX_UNUSED 100
+
 
 static struct llvm_cache llvm_cache = { NULL };
 
@@ -613,6 +615,12 @@ static void
 llvm_cache_item_ref(struct llvm_cache_item *item)
 {
    ++item->ref_count;
+   if (item->ref_count == 1) {
+      --llvm_cache.num_unused;
+
+      /* Previously unused item has come into use.  Remove from unused list. */
+      remove_from_list(&item->list_item);
+   }
 }
 
 
@@ -622,7 +630,21 @@ llvm_cache_item_unref(struct llvm_cache_item *item)
    assert(item->ref_count > 0);
    --item->ref_count;
    if (item->ref_count == 0) {
-      llvm_cache_item_destroy(item);
+      ++llvm_cache.num_unused;
+
+      /* Item went out of use.  Insert at head of unused list. */
+      insert_at_head(&llvm_cache.unused, &item->list_item);
+
+      /* If now too many unused items in cache, get rid of oldest one. */
+      if (llvm_cache.num_unused > LLVM_CACHE_MAX_UNUSED) {
+	 struct llvm_cache_list_item *discard = last_elem(&llvm_cache.unused);
+	 assert(discard);
+	 assert(discard->base);
+	 remove_from_list(&discard->base->list_item);
+	 util_hash_table_remove(llvm_cache.ht, &discard->base->key);
+	 llvm_cache_item_destroy(discard->base);
+	 --llvm_cache.num_unused;
+      }
    }
 }
 
@@ -636,9 +658,13 @@ llvm_cache_item_get(struct draw_llvm_variant *variant, unsigned num_inputs)
    struct llvm_cache_item *item;
    struct llvm_cache_key key;
 
-   if (!llvm_cache.ht)
+   if (!llvm_cache.ht) {
       llvm_cache.ht = util_hash_table_create(&llvm_cache_key_hash,
 					     &llvm_cache_key_compare);
+      make_empty_list(&llvm_cache.unused);
+      llvm_cache.num_unused = 0;
+   }
+
    if (!llvm_cache.ht)
       return NULL;
 
@@ -707,6 +733,8 @@ llvm_cache_item_create(struct draw_llvm_variant *variant,
 
    memcpy(&item->key, key, sizeof(*key));
 
+   item->list_item.base = item;
+
    return item;
 }
 
diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h
index 95796f1..55775c9 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.h
+++ b/src/gallium/auxiliary/draw/draw_llvm.h
@@ -372,9 +372,19 @@ struct draw_gs_llvm_variant_list_item
 };
 
 
+struct llvm_cache_list_item
+{
+   struct llvm_cache_item *base;
+   struct llvm_cache_list_item *next, *prev;
+};
+
 struct llvm_cache
 {
    struct util_hash_table *ht;
+
+   /* list of currently unused items in LRU order */
+   struct llvm_cache_list_item unused;
+   unsigned num_unused;
 };
 
 struct llvm_cache_key
@@ -393,6 +403,8 @@ struct llvm_cache_item
 
    struct llvm_cache_key key;
    unsigned ref_count;
+
+   struct llvm_cache_list_item list_item;
 };
 
 struct draw_llvm_variant
-- 
1.8.3



More information about the mesa-dev mailing list