[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