Reduce trace cache memory footprint using naive memory pool trace allocation

This commit is contained in:
Stanislav Shwartsman 2008-05-04 05:37:36 +00:00
parent 8e3b0ea1af
commit 06e3615239
3 changed files with 40 additions and 26 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.cc,v 1.226 2008-05-01 20:08:37 sshwarts Exp $
// $Id: cpu.cc,v 1.227 2008-05-04 05:37:36 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -167,6 +167,7 @@ no_async_event:
// is in the iCache.
InstrICache_Increment(iCacheMisses);
serveICacheMiss(entry, eipBiased, pAddr);
i = entry->i;
}
#else
bxInstruction_c iStorage, *i = &iStorage;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: icache.cc,v 1.11 2008-03-29 21:01:25 sshwarts Exp $
// $Id: icache.cc,v 1.12 2008-05-04 05:37:36 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007 Stanislav Shwartsman
@ -81,11 +81,12 @@ void stopTraceExecution(void)
void BX_CPU_C::serveICacheMiss(bxICacheEntry_c *cache_entry, Bit32u eipBiased, bx_phy_address pAddr)
{
BX_CPU_THIS_PTR iCache.alloc_trace(cache_entry);
// Cache miss. We weren't so lucky, but let's be optimistic - try to build
// trace from incoming instruction bytes stream !
cache_entry->pAddr = pAddr;
cache_entry->writeStamp = *(BX_CPU_THIS_PTR currPageWriteStampPtr);
cache_entry->ilen = 0;
unsigned remainingInPage = BX_CPU_THIS_PTR eipPageWindowSize - eipBiased;
const Bit8u *fetchPtr = BX_CPU_THIS_PTR eipFetchPtr + eipBiased;
@ -115,7 +116,7 @@ void BX_CPU_C::serveICacheMiss(bxICacheEntry_c *cache_entry, Bit32u eipBiased, b
cache_entry->writeStamp = ICacheWriteStampInvalid;
cache_entry->ilen = 1;
boundaryFetch(fetchPtr, remainingInPage, i);
break;
return;
}
// add instruction to the trace
@ -132,6 +133,8 @@ void BX_CPU_C::serveICacheMiss(bxICacheEntry_c *cache_entry, Bit32u eipBiased, b
// try to find a trace starting from current pAddr and merge
if (mergeTraces(cache_entry, i, pAddr)) break;
}
BX_CPU_THIS_PTR iCache.commit_trace(cache_entry->ilen);
}
bx_bool BX_CPU_C::mergeTraces(bxICacheEntry_c *entry, bxInstruction_c *i, bx_phy_address pAddr)

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: icache.h,v 1.33 2008-04-19 22:29:44 sshwarts Exp $
// $Id: icache.h,v 1.34 2008-05-04 05:37:36 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -111,10 +111,11 @@ BX_CPP_INLINE void bxPageWriteStampTable::purgeWriteStamps(void)
extern bxPageWriteStampTable pageWriteStampTable;
#define BxICacheEntries (32 * 1024) // Must be a power of 2.
#define BxICacheEntries (64 * 1024) // Must be a power of 2.
#define BxICacheMemPool (384 * 1024)
#if BX_SUPPORT_TRACE_CACHE
#define BX_MAX_TRACE_LENGTH 15
#define BX_MAX_TRACE_LENGTH 32
#endif
struct bxICacheEntry_c
@ -124,7 +125,7 @@ struct bxICacheEntry_c
// decrements this value
#if BX_SUPPORT_TRACE_CACHE
Bit32u ilen; // Trace length in instructions
bxInstruction_c i[BX_MAX_TRACE_LENGTH];
bxInstruction_c *i;
#else
// ... define as array of 1 to simplify merge with trace cache code
bxInstruction_c i[1];
@ -134,6 +135,10 @@ struct bxICacheEntry_c
class BOCHSAPI bxICache_c {
public:
bxICacheEntry_c entry[BxICacheEntries];
#if BX_SUPPORT_TRACE_CACHE
bxInstruction_c pool[BxICacheMemPool];
Bit32u mempool;
#endif
public:
bxICache_c() { flushICacheEntries(); }
@ -141,9 +146,20 @@ public:
BX_CPP_INLINE unsigned hash(bx_phy_address pAddr) const
{
// A pretty dumb hash function for now.
return (pAddr + (pAddr>>6)) & (BxICacheEntries-1);
return (pAddr + (pAddr << 2) + (pAddr>>6)) & (BxICacheEntries-1);
}
#if BX_SUPPORT_TRACE_CACHE
BX_CPP_INLINE void alloc_trace(bxICacheEntry_c *e)
{
if (mempool + BX_MAX_TRACE_LENGTH > BxICacheMemPool) flushICacheEntries();
e->i = &pool[mempool];
e->ilen = 0;
}
BX_CPP_INLINE void commit_trace(unsigned len) { mempool += len; }
#endif
BX_CPP_INLINE void purgeICacheEntries(void);
BX_CPP_INLINE void flushICacheEntries(void);
@ -151,31 +167,25 @@ public:
{
return &(entry[hash(pAddr)]);
}
};
BX_CPP_INLINE void bxICache_c::flushICacheEntries(void)
{
bxICacheEntry_c* e = entry;
for (unsigned i=0; i<BxICacheEntries; i++, e++) {
e->writeStamp = ICacheWriteStampInvalid;
}
bxICacheEntry_c* e = entry;
for (unsigned i=0; i<BxICacheEntries; i++, e++) {
e->writeStamp = ICacheWriteStampInvalid;
}
#if BX_SUPPORT_TRACE_CACHE
mempool = 0;
#endif
}
// Since the write stamps may overflow if we always simply decrese them,
// this function has to be called often enough that we can reset them.
BX_CPP_INLINE void bxICache_c::purgeICacheEntries(void)
{
bxICacheEntry_c* e = entry;
// Since the write stamps may overflow if we always simply decrese them,
// this function has to be called often enough that we can reset them
// (without invalidating the cache).
for (unsigned i=0;i<BxICacheEntries;i++,e++)
{
Bit32u pageWriteStamp = pageWriteStampTable.getPageWriteStamp(e->pAddr);
if (e->writeStamp != pageWriteStamp)
e->writeStamp = ICacheWriteStampInvalid; // invalidate entry
else
e->writeStamp |= ICacheWriteStampStart;
}
flushICacheEntries();
}
extern void purgeICaches(void);