Skip to content

Commit

Permalink
fix #15: 64-bit addresses are now respected
Browse files Browse the repository at this point in the history
  • Loading branch information
cod3monk committed Jul 14, 2022
1 parent f94d79c commit 1741d35
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 21 deletions.
38 changes: 19 additions & 19 deletions cachesim/backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,22 +106,22 @@ static PyMemberDef Cache_members[] = {
};
#endif

inline static long Cache__get_cacheline_id(Cache* self, long addr) {
inline static long Cache__get_cacheline_id(Cache* self, long long addr) {
return addr >> self->cl_bits;
}

inline static long Cache__get_set_id(Cache* self, long cl_id) {
return cl_id % self->sets;
}

inline static addr_range __range_from_addrs(long addr, long last_addr) {
inline static addr_range __range_from_addrs(long long addr, long long last_addr) {
addr_range range;
range.addr = addr;
range.length = last_addr-addr-1;
return range;
}

inline static long Cache__get_addr_from_cl_id(Cache* self, long cl_id) {
inline static long long Cache__get_addr_from_cl_id(Cache* self, long cl_id) {
return cl_id << self->cl_bits;
}

Expand Down Expand Up @@ -321,7 +321,7 @@ int Cache__load(Cache* self, addr_range range) {
#ifndef NO_PYTHON
if(self->verbosity >= 4) {
PySys_WriteStdout(
"%s LOAD=%lli addr=%li length=%li cl_id=%li set_id=%li\n",
"%s LOAD=%lli addr=%lli length=%lli cl_id=%li set_id=%li\n",
self->name, self->LOAD.count, range.addr, range.length, cl_id, set_id);
}
#endif
Expand All @@ -335,7 +335,7 @@ int Cache__load(Cache* self, addr_range range) {
self->HIT.byte += self->cl_size < range.length ? self->cl_size : range.length;
#ifndef NO_PYTHON
if(self->verbosity >= 3) {
PySys_WriteStdout("%s HIT self->LOAD=%lli addr=%li cl_id=%li set_id=%li\n",
PySys_WriteStdout("%s HIT self->LOAD=%lli addr=%lli cl_id=%li set_id=%li\n",
self->name, self->LOAD.count, range.addr, cl_id, set_id);
}
#endif
Expand Down Expand Up @@ -395,7 +395,7 @@ int Cache__load(Cache* self, addr_range range) {
}
if(self->verbosity >= 1) {
PySys_WriteStdout(
"%s MISS self->LOAD=%lli addr=%li length=%li cl_id=%li set_id=%li\n",
"%s MISS self->LOAD=%lli addr=%lli length=%lli cl_id=%li set_id=%li\n",
self->name, self->LOAD.count, range.addr, range.length, cl_id, set_id);
}
#endif
Expand Down Expand Up @@ -468,7 +468,7 @@ void Cache__store(Cache* self, addr_range range, int non_temporal) {
#ifndef NO_PYTHON
if(self->verbosity >= 2) {
PySys_WriteStdout(
"%s STORE=%lli NT=%i addr=%li length=%li cl_id=%li sets=%li location=%i\n",
"%s STORE=%lli NT=%i addr=%lli length=%lli cl_id=%li sets=%li location=%i\n",
self->name, self->LOAD.count, non_temporal, range.addr, range.length,
cl_id, self->sets, location);
}
Expand Down Expand Up @@ -499,12 +499,12 @@ void Cache__store(Cache* self, addr_range range, int non_temporal) {
if(self->write_combining == 1) {
// If write_combining is active, set the touched bits:
// Extract local range
long cl_start = Cache__get_addr_from_cl_id(self, cl_id);
long start = range.addr > cl_start ? range.addr : cl_start;
long end = range.addr+range.length < cl_start+self->cl_size ?
long long cl_start = Cache__get_addr_from_cl_id(self, cl_id);
long long start = range.addr > cl_start ? range.addr : cl_start;
long long end = range.addr+range.length < cl_start+self->cl_size ?
range.addr+range.length : cl_start+self->cl_size;
// PySys_WriteStdout("cl_start=%i start=%i end=%i\n", cl_start, start, end);
for(long i=start-cl_start; i<end-cl_start; i++) {
// PySys_WriteStdout("cl_start=%lli start=%lli end=%lli\n", cl_start, start, end);
for(long long i=start-cl_start; i<end-cl_start; i++) {
BITSET(self->subblock_bitfield,
set_id*self->ways*self->subblock_bits + location*self->subblock_bits + i);
}
Expand Down Expand Up @@ -567,7 +567,7 @@ static PyObject* Cache_load(Cache* self, PyObject *args, PyObject *kwds)
range.length = 1; // default to 1

static char *kwlist[] = {"addr", "length", NULL};
PyArg_ParseTupleAndKeywords(args, kwds, "I|I", kwlist, &range.addr, &range.length);
PyArg_ParseTupleAndKeywords(args, kwds, "L|I", kwlist, &range.addr, &range.length);

Cache__load(self, range); // TODO , 0);
// Swap cl_id is irrelevant here, since this is only called on first level cache
Expand All @@ -582,7 +582,7 @@ static PyObject* Cache_iterload(Cache* self, PyObject *args, PyObject *kwds)
range.length = 1; // default to 1

static char *kwlist[] = {"addrs", "length", NULL};
PyArg_ParseTupleAndKeywords(args, kwds, "O|I", kwlist, &addrs, &range.length);
PyArg_ParseTupleAndKeywords(args, kwds, "O|L", kwlist, &addrs, &range.length);
Py_INCREF(addrs);

// Get and check iterator
Expand Down Expand Up @@ -617,7 +617,7 @@ static PyObject* Cache_store(Cache* self, PyObject *args, PyObject *kwds)
range.length = 1; // default to 1

static char *kwlist[] = {"addr", "length", NULL};
PyArg_ParseTupleAndKeywords(args, kwds, "I|I", kwlist, &range.addr, &range.length);
PyArg_ParseTupleAndKeywords(args, kwds, "L|L", kwlist, &range.addr, &range.length);

// Handling ranges in c tremendously increases the speed for multiple elements
Cache__store(self, range, 0);
Expand All @@ -632,7 +632,7 @@ static PyObject* Cache_iterstore(Cache* self, PyObject *args, PyObject *kwds)
range.length = 1; // default to 1

static char *kwlist[] = {"addrs", "length", NULL};
PyArg_ParseTupleAndKeywords(args, kwds, "O|I", kwlist, &addrs, &range.length);
PyArg_ParseTupleAndKeywords(args, kwds, "O|L", kwlist, &addrs, &range.length);
Py_INCREF(addrs);

// Get and check iterator
Expand Down Expand Up @@ -667,7 +667,7 @@ static PyObject* Cache_loadstore(Cache* self, PyObject *args, PyObject *kwds)
range.length = 1; // default to 1

static char *kwlist[] = {"addrs", "length", NULL};
PyArg_ParseTupleAndKeywords(args, kwds, "O|I", kwlist, &addrs, &range.length);
PyArg_ParseTupleAndKeywords(args, kwds, "O|L", kwlist, &addrs, &range.length);
Py_INCREF(addrs);

// Get and check iterator
Expand Down Expand Up @@ -763,10 +763,10 @@ static PyObject* Cache_loadstore(Cache* self, PyObject *args, PyObject *kwds)
}

static PyObject* Cache_contains(Cache* self, PyObject *args, PyObject *kwds) {
long addr;
long long addr;

static char *kwlist[] = {"addr", NULL};
PyArg_ParseTupleAndKeywords(args, kwds, "I", kwlist, &addr);
PyArg_ParseTupleAndKeywords(args, kwds, "L", kwlist, &addr);

long cl_id = Cache__get_cacheline_id(self, addr);
long set_id = Cache__get_set_id(self, cl_id);
Expand Down
4 changes: 2 additions & 2 deletions cachesim/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ typedef struct cache_entry {
typedef struct addr_range {
// Address range used to communicate consecutive accesses
// last addr of range is addr+length-1
long addr;
long length;
long long addr;
long long length;
} addr_range;

struct stats {
Expand Down
24 changes: 24 additions & 0 deletions tests/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -826,3 +826,27 @@ def test_from_dict_victims(self):
self.assertEqual(cs.first_level.backend.load_from, caches['L2'].backend)
self.assertEqual(caches['L2'].backend.victims_to, mem.last_level_store.backend)
self.assertEqual(caches['L2'].backend.load_from, None)

def test_64bit(self):
mem = MainMemory()
l1 = Cache("L1", 1, 1, 32, "LRU")
mem.load_to(l1)
mem.store_from(l1)
cs = CacheSimulator(l1, mem)
#l1.backend.verbosity = 4

cs.load(0xf, 4)
self.assertEqual(l1.stats()['MISS_count'], 1)
self.assertEqual(l1.stats()['HIT_count'], 0)

cs.load(0xf, 4)
self.assertEqual(l1.stats()['MISS_count'], 1)
self.assertEqual(l1.stats()['HIT_count'], 1)

cs.load(0xf | (1<<32), 4)
self.assertEqual(l1.stats()['MISS_count'], 2)
self.assertEqual(l1.stats()['HIT_count'], 1)

cs.load(0xf | (1<<32), 4)
self.assertEqual(l1.stats()['MISS_count'], 2)
self.assertEqual(l1.stats()['HIT_count'], 2)

0 comments on commit 1741d35

Please sign in to comment.