Author: Armin Rigo <ar...@tunes.org> Branch: stm Changeset: r52629:df6f7424b1d3 Date: 2012-02-19 12:35 +0100 http://bitbucket.org/pypy/pypy/changeset/df6f7424b1d3/
Log: A version of the cache that models a hardware L1 cache. (disabled by default because it's buggy in subtle cases) diff --git a/pypy/translator/stm/src_stm/associative.c b/pypy/translator/stm/src_stm/associative.c new file mode 100644 --- /dev/null +++ b/pypy/translator/stm/src_stm/associative.c @@ -0,0 +1,81 @@ + +/* parameters taken from my laptop's Core i5, tweaked according to + * http://en.wikipedia.org/wiki/Haswell_%28microarchitecture%29 + * + * this is not an optimized implementation at all. just for measuring + * the number of collisions that we get on some examples. + */ + + +#define HWEMULATOR_ASSOCIATIVITY_BITS 3 /* = 8 */ +#define HWEMULATOR_CACHE_LINE_BITS 7 /* = 128 */ +#define HWEMULATOR_NUMBER_OF_SETS_BITS 6 /* = 64 */ + +/* this defines a cache size of 64 KB == 1 << (sum of the three numbers) */ + + + +typedef struct { + char data[1 << HWEMULATOR_CACHE_LINE_BITS]; + long tag; + unsigned long creation; +} cacheline_t; + +typedef struct { + cacheline_t choices[1 << HWEMULATOR_ASSOCIATIVITY_BITS]; +} cacheset_t; + +static cacheset_t hwemulator_orecs[1 << HWEMULATOR_NUMBER_OF_SETS_BITS]; + + +static orec_t *get_orec(void* addr) +{ + /* find the set number */ + int setnum = (((long)addr) >> HWEMULATOR_CACHE_LINE_BITS) & + ((1 << HWEMULATOR_NUMBER_OF_SETS_BITS) - 1); + + /* grab it */ + cacheset_t *set = &hwemulator_orecs[setnum]; + + /* round down the addr to get the tag */ + long tag = ((long)addr) >> HWEMULATOR_CACHE_LINE_BITS; + + /* is the cacheline already in the set? */ + int i; + cacheline_t *line; + for (i=0; i < (1 << HWEMULATOR_ASSOCIATIVITY_BITS); i++) { + line = &set->choices[i]; + if (line->tag == tag) + goto found; + } + + /* find the oldest cacheline in the set */ + cacheline_t *oldest_line = 0; + unsigned long oldest = (unsigned long) -1; + unsigned long youngest = 0; + for (i=0; i < (1 << HWEMULATOR_ASSOCIATIVITY_BITS); i++) { + line = &set->choices[i]; + if (line->creation < oldest) { + oldest = line->creation; + oldest_line = line; + } + if (line->creation > youngest) + youngest = line->creation; + } + + /* replace it */ + line = oldest_line; + line->tag = tag; + line->creation = youngest + 1; + /* XXX this is wrong!! it can evict a line containing relevant data, + which can then be recreated at a different index! The issue is + that this operation may forget that we did some changes! But + it's probably good enough for now just to measure the effect */ + + found:; + /* return the orec_t that is in line->data at the correct offset */ + assert((((long)addr) & (sizeof(orec_t)-1)) == 0); + char *p = line->data + (((long)addr) & + ((1 << HWEMULATOR_CACHE_LINE_BITS) - 1)); + return (orec_t *)p; +} diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c --- a/pypy/translator/stm/src_stm/et.c +++ b/pypy/translator/stm/src_stm/et.c @@ -36,6 +36,10 @@ typedef volatile owner_version_t orec_t; +/*#define USE_ASSOCIATIVE_CACHE*/ + +#ifndef USE_ASSOCIATIVE_CACHE /* simple version */ + /*** Specify the number of orecs in the global array. */ #define NUM_STRIPES 1048576 @@ -53,6 +57,10 @@ return (orec_t *)p; } +#else /* USE_ASSOCIATIVE_CACHE: follows more closely what hardware would do */ +# include "src_stm/associative.c" +#endif + #include "src_stm/lists.c" /************************************************************/ _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit