[pypy-commit] pypy stm-thread-2: Hack hack hack at the caching logic. Gives 10%.

arigo noreply at buildbot.pypy.org
Tue Feb 19 08:39:55 CET 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-thread-2
Changeset: r61437:5ea34af55891
Date: 2013-02-19 08:23 +0100
http://bitbucket.org/pypy/pypy/changeset/5ea34af55891/

Log:	Hack hack hack at the caching logic. Gives 10%.

diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c
--- a/rpython/translator/stm/src_stm/et.c
+++ b/rpython/translator/stm/src_stm/et.c
@@ -134,18 +134,17 @@
 
 static inline gcptr AddInReadSet(struct tx_descriptor *d, gcptr R)
 {
-  switch (fxcache_add(&d->recent_reads_cache, R)) {
-
-  case 0:
+  if (!fxcache_add(&d->recent_reads_cache, R)) {
       /* not in the cache: it may be the first time we see it,
        * so insert it into the list */
       gcptrlist_insert(&d->list_of_read_objects, R);
-      break;
+  }
+      //      break;
 
-  case 2:
+      //  case 2:
       /* already in the cache, and FX_THRESHOLD reached */
-      return Localize(d, R);
-  }
+      //      return Localize(d, R);
+      //  }
   return R;
 }
 
@@ -387,7 +386,6 @@
   gcptrlist_clear(&d->list_of_read_objects);
   gcptrlist_clear(&d->gcroots);
   g2l_clear(&d->global_to_local);
-  fxcache_clear(&d->recent_reads_cache);
 
 #ifdef RPY_STM_DEBUG_PRINT
   PYPY_DEBUG_START("stm-abort");
@@ -419,7 +417,7 @@
   assert(d->list_of_read_objects.size == 0);
   assert(d->gcroots.size == 0);
   assert(!g2l_any_entry(&d->global_to_local));
-  assert(fxcache_is_clear(&d->recent_reads_cache));
+  fxcache_clear(&d->recent_reads_cache);
 }
 
 void BeginTransaction(jmp_buf* buf)
@@ -600,7 +598,6 @@
   /* we cannot abort any more from here */
   d->setjmp_buf = NULL;
   gcptrlist_clear(&d->list_of_read_objects);
-  fxcache_clear(&d->recent_reads_cache);
 
   UpdateChainHeads(d, cur_time);
 
diff --git a/rpython/translator/stm/src_stm/lists.c b/rpython/translator/stm/src_stm/lists.c
--- a/rpython/translator/stm/src_stm/lists.c
+++ b/rpython/translator/stm/src_stm/lists.c
@@ -216,6 +216,13 @@
 static void _gcptrlist_grow(struct GcPtrList *gcptrlist)
 {
   long newalloc = gcptrlist->alloc + (gcptrlist->alloc >> 1) + 16;
+
+  PYPY_DEBUG_START("stm-growth");
+  if (PYPY_HAVE_DEBUG_PRINTS)
+    {
+      fprintf(PYPY_DEBUG_FILE, "%ld KB\n", newalloc * sizeof(gcptr) / 1024);
+    }
+
   gcptr *newitems = malloc(newalloc * sizeof(gcptr));
   long i;
   for (i=0; i<gcptrlist->size; i++)
@@ -223,6 +230,8 @@
   free(gcptrlist->items);
   gcptrlist->items = newitems;
   gcptrlist->alloc = newalloc;
+
+  PYPY_DEBUG_STOP("stm-growth");
 }
 
 static inline void gcptrlist_insert(struct GcPtrList *gcptrlist, gcptr newitem)
@@ -252,61 +261,68 @@
    of collisions, old items are discarded.  The eviction logic is a bit
    too simple for now. */
 
-#define FX_ENTRIES    32
-#define FX_SIZE       (FX_ENTRIES * sizeof(revision_t))
-#define FX_THRESHOLD  5
-
-#if FX_THRESHOLD >= FX_ENTRIES * 4   /* == lower bound on FX_SIZE */
-#  error "if you increase FX_THRESHOLD, you must also increase FX_ENTRIES"
-#endif
+#define FX_ENTRIES    8192
+#define FX_ASSOC      1
+#define FX_SIZE       (FX_ENTRIES * FX_ASSOC * sizeof(revision_t))
 
 struct FXCache {
-  revision_t cache[FX_ENTRIES];
+  char *cache_start;
+#if FX_ASSOC > 1
+  revision_t nextadd;
+#endif
+  revision_t shift;
+  revision_t cache[FX_ENTRIES * FX_ASSOC * 2];
 };
 
-static int fxcache_is_clear(struct FXCache *fxcache)
-{
-  int i;
-  for (i=0; i<FX_ENTRIES; i++)
-    if (fxcache->cache[i])
-      return 0;
-  return 1;
-}
-
 static void fxcache_clear(struct FXCache *fxcache)
 {
-  memset(fxcache, 0, sizeof(struct FXCache));
+  fxcache->shift += FX_ASSOC;
+  if (fxcache->shift > (FX_ENTRIES - 1) * FX_ASSOC) {
+    memset(fxcache->cache, 0, 2 * FX_SIZE);
+    fxcache->shift = 0;
+  }
+  fxcache->cache_start = (char *)(fxcache->cache + fxcache->shift);
 }
 
 static inline int fxcache_add(struct FXCache *fxcache, gcptr item)
 {
-  /* If 'item' is not in the cache, add it with the value 0 and returns 0.
-     If it is already, increment its value and returns 1.
-     If it we reach FX_THRESHOLD, returns 2.
+  /* If 'item' is not in the cache, add it and returns 0.
+     If it is already, return 1.
      */
   revision_t uitem = (revision_t)item;
   revision_t *entry = (revision_t *)
-    (((char *)fxcache->cache) + (uitem & (FX_SIZE-sizeof(revision_t))));
-  revision_t stored_key = uitem & -FX_SIZE;
-  revision_t value = stored_key ^ *entry;
-  if (value >= FX_SIZE)
-    {
-      /* not in the cache: evict the colliding item (no associativity) */
-      *entry = stored_key;
-      return 0;
-    }
-  else
-    {
-      /* already in the cache */
-      if (value < FX_THRESHOLD)
-        {
-          ++value;
-          ++*entry;
-          return 1;
-        }
-      else
-        return 2;
-    }
+    (fxcache->cache_start + (uitem & (FX_SIZE-sizeof(revision_t))));
+
+  if (entry[0] == uitem
+#if FX_ASSOC >= 2
+      || entry[1] == uitem
+#if FX_ASSOC >= 4
+      || entry[2] == uitem || entry[3] == uitem
+#if FX_ASSOC >= 8
+      || entry[4] == uitem || entry[5] == uitem
+      || entry[6] == uitem || entry[7] == uitem
+#if FX_ASSOC >= 16
+      || entry[8] == uitem || entry[9] == uitem
+      || entry[10]== uitem || entry[11]== uitem
+      || entry[12]== uitem || entry[13]== uitem
+      || entry[14]== uitem || entry[15]== uitem
+#if FX_ASSOC >= 32
+#error "FX_ASSOC is too large"
+#endif /* 32 */
+#endif /* 16 */
+#endif /* 8 */
+#endif /* 4 */
+#endif /* 2 */
+      )
+    return 1;
+
+#if FX_ASSOC > 1
+  entry[fxcache->nextadd] = uitem;
+  fxcache->nextadd = (fxcache->nextadd + 1) & (FX_ASSOC-1);
+#else
+  entry[0] = uitem;
+#endif
+  return 0;
 }
 
 /************************************************************/


More information about the pypy-commit mailing list