Get rid of generic CacheTags object (fold back into Cache).
--HG-- extra : convert_revision : 8769bd8cc358ab3cbbdbbcd909b2e0f1515e09da
This commit is contained in:
parent
0e78386874
commit
1428b0de7d
7 changed files with 683 additions and 91 deletions
|
@ -118,7 +118,6 @@ base_sources = Split('''
|
||||||
mem/cache/prefetch/stride_prefetcher.cc
|
mem/cache/prefetch/stride_prefetcher.cc
|
||||||
mem/cache/prefetch/tagged_prefetcher.cc
|
mem/cache/prefetch/tagged_prefetcher.cc
|
||||||
mem/cache/tags/base_tags.cc
|
mem/cache/tags/base_tags.cc
|
||||||
mem/cache/tags/cache_tags.cc
|
|
||||||
mem/cache/tags/fa_lru.cc
|
mem/cache/tags/fa_lru.cc
|
||||||
mem/cache/tags/iic.cc
|
mem/cache/tags/iic.cc
|
||||||
mem/cache/tags/lru.cc
|
mem/cache/tags/lru.cc
|
||||||
|
|
22
src/mem/cache/cache.cc
vendored
22
src/mem/cache/cache.cc
vendored
|
@ -38,8 +38,6 @@
|
||||||
|
|
||||||
#include "mem/config/cache.hh"
|
#include "mem/config/cache.hh"
|
||||||
|
|
||||||
#include "mem/cache/tags/cache_tags.hh"
|
|
||||||
|
|
||||||
#if defined(USE_CACHE_LRU)
|
#if defined(USE_CACHE_LRU)
|
||||||
#include "mem/cache/tags/lru.hh"
|
#include "mem/cache/tags/lru.hh"
|
||||||
#endif
|
#endif
|
||||||
|
@ -73,28 +71,28 @@
|
||||||
|
|
||||||
|
|
||||||
#if defined(USE_CACHE_FALRU)
|
#if defined(USE_CACHE_FALRU)
|
||||||
template class Cache<CacheTags<FALRU>, SimpleCoherence>;
|
template class Cache<FALRU, SimpleCoherence>;
|
||||||
template class Cache<CacheTags<FALRU>, UniCoherence>;
|
template class Cache<FALRU, UniCoherence>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_CACHE_IIC)
|
#if defined(USE_CACHE_IIC)
|
||||||
template class Cache<CacheTags<IIC>, SimpleCoherence>;
|
template class Cache<IIC, SimpleCoherence>;
|
||||||
template class Cache<CacheTags<IIC>, UniCoherence>;
|
template class Cache<IIC, UniCoherence>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_CACHE_LRU)
|
#if defined(USE_CACHE_LRU)
|
||||||
template class Cache<CacheTags<LRU>, SimpleCoherence>;
|
template class Cache<LRU, SimpleCoherence>;
|
||||||
template class Cache<CacheTags<LRU>, UniCoherence>;
|
template class Cache<LRU, UniCoherence>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_CACHE_SPLIT)
|
#if defined(USE_CACHE_SPLIT)
|
||||||
template class Cache<CacheTags<Split>, SimpleCoherence>;
|
template class Cache<Split, SimpleCoherence>;
|
||||||
template class Cache<CacheTags<Split>, UniCoherence>;
|
template class Cache<Split, UniCoherence>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_CACHE_SPLIT_LIFO)
|
#if defined(USE_CACHE_SPLIT_LIFO)
|
||||||
template class Cache<CacheTags<SplitLIFO>, SimpleCoherence>;
|
template class Cache<SplitLIFO, SimpleCoherence>;
|
||||||
template class Cache<CacheTags<SplitLIFO>, UniCoherence>;
|
template class Cache<SplitLIFO, UniCoherence>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif //DOXYGEN_SHOULD_SKIP_THIS
|
#endif //DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
181
src/mem/cache/cache.hh
vendored
181
src/mem/cache/cache.hh
vendored
|
@ -38,10 +38,12 @@
|
||||||
#ifndef __CACHE_HH__
|
#ifndef __CACHE_HH__
|
||||||
#define __CACHE_HH__
|
#define __CACHE_HH__
|
||||||
|
|
||||||
|
#include "base/compression/base.hh"
|
||||||
#include "base/misc.hh" // fatal, panic, and warn
|
#include "base/misc.hh" // fatal, panic, and warn
|
||||||
#include "cpu/smt.hh" // SMT_MAX_THREADS
|
#include "cpu/smt.hh" // SMT_MAX_THREADS
|
||||||
|
|
||||||
#include "mem/cache/base_cache.hh"
|
#include "mem/cache/base_cache.hh"
|
||||||
|
#include "mem/cache/cache_blk.hh"
|
||||||
#include "mem/cache/miss/miss_buffer.hh"
|
#include "mem/cache/miss/miss_buffer.hh"
|
||||||
#include "mem/cache/prefetch/prefetcher.hh"
|
#include "mem/cache/prefetch/prefetcher.hh"
|
||||||
|
|
||||||
|
@ -62,6 +64,8 @@ class Cache : public BaseCache
|
||||||
public:
|
public:
|
||||||
/** Define the type of cache block to use. */
|
/** Define the type of cache block to use. */
|
||||||
typedef typename TagStore::BlkType BlkType;
|
typedef typename TagStore::BlkType BlkType;
|
||||||
|
/** A typedef for a list of BlkType pointers. */
|
||||||
|
typedef typename TagStore::BlkList BlkList;
|
||||||
|
|
||||||
bool prefetchAccess;
|
bool prefetchAccess;
|
||||||
|
|
||||||
|
@ -141,6 +145,156 @@ class Cache : public BaseCache
|
||||||
PacketPtr invalidatePkt;
|
PacketPtr invalidatePkt;
|
||||||
Request *invalidateReq;
|
Request *invalidateReq;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Policy class for performing compression.
|
||||||
|
*/
|
||||||
|
CompressionAlgorithm *compressionAlg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The block size of this cache. Set to value in the Tags object.
|
||||||
|
*/
|
||||||
|
const int16_t blkSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can this cache should allocate a block on a line-sized write miss.
|
||||||
|
*/
|
||||||
|
const bool doFastWrites;
|
||||||
|
|
||||||
|
const bool prefetchMiss;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can the data can be stored in a compressed form.
|
||||||
|
*/
|
||||||
|
const bool storeCompressed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do we need to compress blocks on writebacks (i.e. because
|
||||||
|
* writeback bus is compressed but storage is not)?
|
||||||
|
*/
|
||||||
|
const bool compressOnWriteback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The latency of a compression operation.
|
||||||
|
*/
|
||||||
|
const int16_t compLatency;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should we use an adaptive compression scheme.
|
||||||
|
*/
|
||||||
|
const bool adaptiveCompression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do writebacks need to be compressed (i.e. because writeback bus
|
||||||
|
* is compressed), whether or not they're already compressed for
|
||||||
|
* storage.
|
||||||
|
*/
|
||||||
|
const bool writebackCompressed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the internal block data to the fast access block data.
|
||||||
|
* @param blk The cache block to check.
|
||||||
|
* @return True if the data is the same.
|
||||||
|
*/
|
||||||
|
bool verifyData(BlkType *blk);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the internal data of the block. The data to write is assumed to
|
||||||
|
* be in the fast access data.
|
||||||
|
* @param blk The block with the data to update.
|
||||||
|
* @param writebacks A list to store any generated writebacks.
|
||||||
|
* @param compress_block True if we should compress this block
|
||||||
|
*/
|
||||||
|
void updateData(BlkType *blk, PacketList &writebacks, bool compress_block);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a replacement for the given request.
|
||||||
|
* @param blk A pointer to the block, usually NULL
|
||||||
|
* @param pkt The memory request to satisfy.
|
||||||
|
* @param new_state The new state of the block.
|
||||||
|
* @param writebacks A list to store any generated writebacks.
|
||||||
|
*/
|
||||||
|
BlkType* doReplacement(BlkType *blk, PacketPtr &pkt,
|
||||||
|
CacheBlk::State new_state, PacketList &writebacks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does all the processing necessary to perform the provided request.
|
||||||
|
* @param pkt The memory request to perform.
|
||||||
|
* @param lat The latency of the access.
|
||||||
|
* @param writebacks List for any writebacks that need to be performed.
|
||||||
|
* @param update True if the replacement data should be updated.
|
||||||
|
* @return Pointer to the cache block touched by the request. NULL if it
|
||||||
|
* was a miss.
|
||||||
|
*/
|
||||||
|
BlkType* handleAccess(PacketPtr &pkt, int & lat,
|
||||||
|
PacketList & writebacks, bool update = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates a cache block and handles all outstanding requests for the
|
||||||
|
* satisfied fill request. This version takes an MSHR pointer and uses its
|
||||||
|
* request to fill the cache block, while repsonding to its targets.
|
||||||
|
* @param blk The cache block if it already exists.
|
||||||
|
* @param mshr The MSHR that contains the fill data and targets to satisfy.
|
||||||
|
* @param new_state The state of the new cache block.
|
||||||
|
* @param writebacks List for any writebacks that need to be performed.
|
||||||
|
* @return Pointer to the new cache block.
|
||||||
|
*/
|
||||||
|
BlkType* handleFill(BlkType *blk, MSHR * mshr, CacheBlk::State new_state,
|
||||||
|
PacketList & writebacks, PacketPtr pkt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates a cache block and handles all outstanding requests for the
|
||||||
|
* satisfied fill request. This version takes two memory requests. One
|
||||||
|
* contains the fill data, the other is an optional target to satisfy.
|
||||||
|
* Used for Cache::probe.
|
||||||
|
* @param blk The cache block if it already exists.
|
||||||
|
* @param pkt The memory request with the fill data.
|
||||||
|
* @param new_state The state of the new cache block.
|
||||||
|
* @param writebacks List for any writebacks that need to be performed.
|
||||||
|
* @param target The memory request to perform after the fill.
|
||||||
|
* @return Pointer to the new cache block.
|
||||||
|
*/
|
||||||
|
BlkType* handleFill(BlkType *blk, PacketPtr &pkt,
|
||||||
|
CacheBlk::State new_state,
|
||||||
|
PacketList & writebacks, PacketPtr target = NULL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the blk to the new state and handles the given request.
|
||||||
|
* @param blk The cache block being snooped.
|
||||||
|
* @param new_state The new coherence state for the block.
|
||||||
|
* @param pkt The request to satisfy
|
||||||
|
*/
|
||||||
|
void handleSnoop(BlkType *blk, CacheBlk::State new_state,
|
||||||
|
PacketPtr &pkt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the blk to the new state.
|
||||||
|
* @param blk The cache block being snooped.
|
||||||
|
* @param new_state The new coherence state for the block.
|
||||||
|
*/
|
||||||
|
void handleSnoop(BlkType *blk, CacheBlk::State new_state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a writeback request for the given block.
|
||||||
|
* @param blk The block to writeback.
|
||||||
|
* @return The writeback request for the block.
|
||||||
|
*/
|
||||||
|
PacketPtr writebackBlk(BlkType *blk);
|
||||||
|
|
||||||
|
BlkType* findBlock(Addr addr)
|
||||||
|
{
|
||||||
|
return tags->findBlock(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlkType* findBlock(PacketPtr &pkt)
|
||||||
|
{
|
||||||
|
return tags->findBlock(pkt->getAddr());
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidateBlk(CacheBlk *blk)
|
||||||
|
{
|
||||||
|
tags->invalidateBlk(tags->regenerateBlkAddr(blk->tag, blk->set));
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class Params
|
class Params
|
||||||
|
@ -153,15 +307,38 @@ class Cache : public BaseCache
|
||||||
Prefetcher<TagStore> *prefetcher;
|
Prefetcher<TagStore> *prefetcher;
|
||||||
bool prefetchAccess;
|
bool prefetchAccess;
|
||||||
int hitLatency;
|
int hitLatency;
|
||||||
|
CompressionAlgorithm *compressionAlg;
|
||||||
|
const int16_t blkSize;
|
||||||
|
const bool doFastWrites;
|
||||||
|
const bool prefetchMiss;
|
||||||
|
const bool storeCompressed;
|
||||||
|
const bool compressOnWriteback;
|
||||||
|
const int16_t compLatency;
|
||||||
|
const bool adaptiveCompression;
|
||||||
|
const bool writebackCompressed;
|
||||||
|
|
||||||
Params(TagStore *_tags, MissBuffer *mq, Coherence *coh,
|
Params(TagStore *_tags, MissBuffer *mq, Coherence *coh,
|
||||||
BaseCache::Params params,
|
BaseCache::Params params,
|
||||||
Prefetcher<TagStore> *_prefetcher,
|
Prefetcher<TagStore> *_prefetcher,
|
||||||
bool prefetch_access, int hit_latency)
|
bool prefetch_access, int hit_latency,
|
||||||
|
bool do_fast_writes,
|
||||||
|
bool store_compressed, bool adaptive_compression,
|
||||||
|
bool writeback_compressed,
|
||||||
|
CompressionAlgorithm *_compressionAlg, int comp_latency,
|
||||||
|
bool prefetch_miss)
|
||||||
: tags(_tags), missQueue(mq), coherence(coh),
|
: tags(_tags), missQueue(mq), coherence(coh),
|
||||||
baseParams(params),
|
baseParams(params),
|
||||||
prefetcher(_prefetcher), prefetchAccess(prefetch_access),
|
prefetcher(_prefetcher), prefetchAccess(prefetch_access),
|
||||||
hitLatency(hit_latency)
|
hitLatency(hit_latency),
|
||||||
|
compressionAlg(_compressionAlg),
|
||||||
|
blkSize(_tags->getBlockSize()),
|
||||||
|
doFastWrites(do_fast_writes),
|
||||||
|
prefetchMiss(prefetch_miss),
|
||||||
|
storeCompressed(store_compressed),
|
||||||
|
compressOnWriteback(!store_compressed && writeback_compressed),
|
||||||
|
compLatency(comp_latency),
|
||||||
|
adaptiveCompression(adaptive_compression),
|
||||||
|
writebackCompressed(writeback_compressed)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
57
src/mem/cache/cache_builder.cc
vendored
57
src/mem/cache/cache_builder.cc
vendored
|
@ -70,9 +70,6 @@
|
||||||
#include "base/compression/null_compression.hh"
|
#include "base/compression/null_compression.hh"
|
||||||
#include "base/compression/lzss_compression.hh"
|
#include "base/compression/lzss_compression.hh"
|
||||||
|
|
||||||
// CacheTags Templates
|
|
||||||
#include "mem/cache/tags/cache_tags.hh"
|
|
||||||
|
|
||||||
// MissQueue Templates
|
// MissQueue Templates
|
||||||
#include "mem/cache/miss/miss_queue.hh"
|
#include "mem/cache/miss/miss_queue.hh"
|
||||||
#include "mem/cache/miss/blocking_buffer.hh"
|
#include "mem/cache/miss/blocking_buffer.hh"
|
||||||
|
@ -108,8 +105,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(BaseCache)
|
||||||
Param<int> tgts_per_mshr;
|
Param<int> tgts_per_mshr;
|
||||||
Param<int> write_buffers;
|
Param<int> write_buffers;
|
||||||
Param<bool> prioritizeRequests;
|
Param<bool> prioritizeRequests;
|
||||||
// SimObjectParam<Bus *> in_bus;
|
|
||||||
// SimObjectParam<Bus *> out_bus;
|
|
||||||
SimObjectParam<CoherenceProtocol *> protocol;
|
SimObjectParam<CoherenceProtocol *> protocol;
|
||||||
Param<Addr> trace_addr;
|
Param<Addr> trace_addr;
|
||||||
Param<int> hash_delay;
|
Param<int> hash_delay;
|
||||||
|
@ -122,7 +117,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(BaseCache)
|
||||||
Param<int> compression_latency;
|
Param<int> compression_latency;
|
||||||
Param<int> subblock_size;
|
Param<int> subblock_size;
|
||||||
Param<Counter> max_miss_count;
|
Param<Counter> max_miss_count;
|
||||||
// SimObjectParam<HierParams *> hier;
|
|
||||||
VectorParam<Range<Addr> > addr_range;
|
VectorParam<Range<Addr> > addr_range;
|
||||||
// SimObjectParam<MemTraceWriter *> mem_trace;
|
// SimObjectParam<MemTraceWriter *> mem_trace;
|
||||||
Param<bool> split;
|
Param<bool> split;
|
||||||
|
@ -156,9 +150,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(BaseCache)
|
||||||
INIT_PARAM_DFLT(write_buffers, "number of write buffers", 8),
|
INIT_PARAM_DFLT(write_buffers, "number of write buffers", 8),
|
||||||
INIT_PARAM_DFLT(prioritizeRequests, "always service demand misses first",
|
INIT_PARAM_DFLT(prioritizeRequests, "always service demand misses first",
|
||||||
false),
|
false),
|
||||||
/* INIT_PARAM_DFLT(in_bus, "incoming bus object", NULL),
|
|
||||||
INIT_PARAM(out_bus, "outgoing bus object"),
|
|
||||||
*/
|
|
||||||
INIT_PARAM_DFLT(protocol, "coherence protocol to use in the cache", NULL),
|
INIT_PARAM_DFLT(protocol, "coherence protocol to use in the cache", NULL),
|
||||||
INIT_PARAM_DFLT(trace_addr, "address to trace", 0),
|
INIT_PARAM_DFLT(trace_addr, "address to trace", 0),
|
||||||
|
|
||||||
|
@ -182,10 +173,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(BaseCache)
|
||||||
INIT_PARAM_DFLT(max_miss_count,
|
INIT_PARAM_DFLT(max_miss_count,
|
||||||
"The number of misses to handle before calling exit",
|
"The number of misses to handle before calling exit",
|
||||||
0),
|
0),
|
||||||
/* INIT_PARAM_DFLT(hier,
|
|
||||||
"Hierarchy global variables",
|
|
||||||
&defaultHierParams),
|
|
||||||
*/
|
|
||||||
INIT_PARAM_DFLT(addr_range, "The address range in bytes",
|
INIT_PARAM_DFLT(addr_range, "The address range in bytes",
|
||||||
vector<Range<Addr> >(1,RangeIn((Addr)0, MaxAddr))),
|
vector<Range<Addr> >(1,RangeIn((Addr)0, MaxAddr))),
|
||||||
// INIT_PARAM_DFLT(mem_trace, "Memory trace to write accesses to", NULL),
|
// INIT_PARAM_DFLT(mem_trace, "Memory trace to write accesses to", NULL),
|
||||||
|
@ -208,26 +195,31 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(BaseCache)
|
||||||
END_INIT_SIM_OBJECT_PARAMS(BaseCache)
|
END_INIT_SIM_OBJECT_PARAMS(BaseCache)
|
||||||
|
|
||||||
|
|
||||||
#define BUILD_CACHE(t, c) do { \
|
#define BUILD_CACHE(TAGS, tags, c) \
|
||||||
Prefetcher<CacheTags<t> > *pf; \
|
do { \
|
||||||
|
Prefetcher<TAGS> *pf; \
|
||||||
if (pf_policy == "tagged") { \
|
if (pf_policy == "tagged") { \
|
||||||
BUILD_TAGGED_PREFETCHER(t); \
|
BUILD_TAGGED_PREFETCHER(TAGS); \
|
||||||
} \
|
} \
|
||||||
else if (pf_policy == "stride") { \
|
else if (pf_policy == "stride") { \
|
||||||
BUILD_STRIDED_PREFETCHER(t); \
|
BUILD_STRIDED_PREFETCHER(TAGS); \
|
||||||
} \
|
} \
|
||||||
else if (pf_policy == "ghb") { \
|
else if (pf_policy == "ghb") { \
|
||||||
BUILD_GHB_PREFETCHER(t); \
|
BUILD_GHB_PREFETCHER(TAGS); \
|
||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
BUILD_NULL_PREFETCHER(t); \
|
BUILD_NULL_PREFETCHER(TAGS); \
|
||||||
} \
|
} \
|
||||||
Cache<CacheTags<t>, c>::Params params(tagStore, mq, coh, \
|
Cache<TAGS, c>::Params params(tags, mq, coh, base_params, \
|
||||||
base_params, \
|
pf, prefetch_access, hit_latency, \
|
||||||
pf, \
|
true, \
|
||||||
prefetch_access, hit_latency); \
|
store_compressed, \
|
||||||
Cache<CacheTags<t>, c> *retval = \
|
adaptive_compression, \
|
||||||
new Cache<CacheTags<t>, c>(getInstanceName(), params); \
|
compressed_bus, \
|
||||||
|
compAlg, compression_latency, \
|
||||||
|
prefetch_miss); \
|
||||||
|
Cache<TAGS, c> *retval = \
|
||||||
|
new Cache<TAGS, c>(getInstanceName(), params); \
|
||||||
return retval; \
|
return retval; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -243,12 +235,7 @@ return retval; \
|
||||||
} else { \
|
} else { \
|
||||||
compAlg = new NullCompression(); \
|
compAlg = new NullCompression(); \
|
||||||
} \
|
} \
|
||||||
CacheTags<TAGS> *tagStore = \
|
BUILD_CACHE(TAGS, tags, c); \
|
||||||
new CacheTags<TAGS>(tags, compression_latency, true, \
|
|
||||||
store_compressed, adaptive_compression, \
|
|
||||||
compressed_bus, \
|
|
||||||
compAlg, prefetch_miss); \
|
|
||||||
BUILD_CACHE(TAGS, c); \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#if defined(USE_CACHE_FALRU)
|
#if defined(USE_CACHE_FALRU)
|
||||||
|
@ -328,7 +315,7 @@ return retval; \
|
||||||
|
|
||||||
#if defined(USE_TAGGED)
|
#if defined(USE_TAGGED)
|
||||||
#define BUILD_TAGGED_PREFETCHER(t) pf = new \
|
#define BUILD_TAGGED_PREFETCHER(t) pf = new \
|
||||||
TaggedPrefetcher<CacheTags<t> >(prefetcher_size, \
|
TaggedPrefetcher<t >(prefetcher_size, \
|
||||||
!prefetch_past_page, \
|
!prefetch_past_page, \
|
||||||
prefetch_serial_squash, \
|
prefetch_serial_squash, \
|
||||||
prefetch_cache_check_push, \
|
prefetch_cache_check_push, \
|
||||||
|
@ -341,7 +328,7 @@ return retval; \
|
||||||
|
|
||||||
#if defined(USE_STRIDED)
|
#if defined(USE_STRIDED)
|
||||||
#define BUILD_STRIDED_PREFETCHER(t) pf = new \
|
#define BUILD_STRIDED_PREFETCHER(t) pf = new \
|
||||||
StridePrefetcher<CacheTags<t> >(prefetcher_size, \
|
StridePrefetcher<t >(prefetcher_size, \
|
||||||
!prefetch_past_page, \
|
!prefetch_past_page, \
|
||||||
prefetch_serial_squash, \
|
prefetch_serial_squash, \
|
||||||
prefetch_cache_check_push, \
|
prefetch_cache_check_push, \
|
||||||
|
@ -355,7 +342,7 @@ return retval; \
|
||||||
|
|
||||||
#if defined(USE_GHB)
|
#if defined(USE_GHB)
|
||||||
#define BUILD_GHB_PREFETCHER(t) pf = new \
|
#define BUILD_GHB_PREFETCHER(t) pf = new \
|
||||||
GHBPrefetcher<CacheTags<t> >(prefetcher_size, \
|
GHBPrefetcher<t >(prefetcher_size, \
|
||||||
!prefetch_past_page, \
|
!prefetch_past_page, \
|
||||||
prefetch_serial_squash, \
|
prefetch_serial_squash, \
|
||||||
prefetch_cache_check_push, \
|
prefetch_cache_check_push, \
|
||||||
|
@ -369,7 +356,7 @@ return retval; \
|
||||||
|
|
||||||
#if defined(USE_TAGGED)
|
#if defined(USE_TAGGED)
|
||||||
#define BUILD_NULL_PREFETCHER(t) pf = new \
|
#define BUILD_NULL_PREFETCHER(t) pf = new \
|
||||||
TaggedPrefetcher<CacheTags<t> >(prefetcher_size, \
|
TaggedPrefetcher<t >(prefetcher_size, \
|
||||||
!prefetch_past_page, \
|
!prefetch_past_page, \
|
||||||
prefetch_serial_squash, \
|
prefetch_serial_squash, \
|
||||||
prefetch_cache_check_push, \
|
prefetch_cache_check_push, \
|
||||||
|
|
471
src/mem/cache/cache_impl.hh
vendored
471
src/mem/cache/cache_impl.hh
vendored
|
@ -72,10 +72,18 @@ Cache(const std::string &_name,
|
||||||
prefetchAccess(params.prefetchAccess),
|
prefetchAccess(params.prefetchAccess),
|
||||||
tags(params.tags), missQueue(params.missQueue),
|
tags(params.tags), missQueue(params.missQueue),
|
||||||
coherence(params.coherence), prefetcher(params.prefetcher),
|
coherence(params.coherence), prefetcher(params.prefetcher),
|
||||||
hitLatency(params.hitLatency)
|
hitLatency(params.hitLatency),
|
||||||
|
compressionAlg(params.compressionAlg),
|
||||||
|
blkSize(params.blkSize),
|
||||||
|
doFastWrites(params.doFastWrites),
|
||||||
|
prefetchMiss(params.prefetchMiss),
|
||||||
|
storeCompressed(params.storeCompressed),
|
||||||
|
compressOnWriteback(params.compressOnWriteback),
|
||||||
|
compLatency(params.compLatency),
|
||||||
|
adaptiveCompression(params.adaptiveCompression),
|
||||||
|
writebackCompressed(params.writebackCompressed)
|
||||||
{
|
{
|
||||||
tags->setCache(this);
|
tags->setCache(this);
|
||||||
tags->setPrefetcher(prefetcher);
|
|
||||||
missQueue->setCache(this);
|
missQueue->setCache(this);
|
||||||
missQueue->setPrefetcher(prefetcher);
|
missQueue->setPrefetcher(prefetcher);
|
||||||
coherence->setCache(this);
|
coherence->setCache(this);
|
||||||
|
@ -97,6 +105,433 @@ Cache<TagStore,Coherence>::regStats()
|
||||||
prefetcher->regStats(name());
|
prefetcher->regStats(name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class TagStore, class Coherence>
|
||||||
|
typename Cache<TagStore,Coherence>::BlkType*
|
||||||
|
Cache<TagStore,Coherence>::handleAccess(PacketPtr &pkt, int & lat,
|
||||||
|
PacketList & writebacks, bool update)
|
||||||
|
{
|
||||||
|
// Set the block offset here
|
||||||
|
int offset = tags->extractBlkOffset(pkt->getAddr());
|
||||||
|
|
||||||
|
BlkType *blk = NULL;
|
||||||
|
if (update) {
|
||||||
|
blk = tags->findBlock(pkt, lat);
|
||||||
|
} else {
|
||||||
|
blk = tags->findBlock(pkt->getAddr());
|
||||||
|
lat = 0;
|
||||||
|
}
|
||||||
|
if (blk != NULL) {
|
||||||
|
|
||||||
|
if (!update) {
|
||||||
|
if (pkt->isWrite()){
|
||||||
|
assert(offset < blkSize);
|
||||||
|
assert(pkt->getSize() <= blkSize);
|
||||||
|
assert(offset+pkt->getSize() <= blkSize);
|
||||||
|
memcpy(blk->data + offset, pkt->getPtr<uint8_t>(),
|
||||||
|
pkt->getSize());
|
||||||
|
} else if (!(pkt->flags & SATISFIED)) {
|
||||||
|
pkt->flags |= SATISFIED;
|
||||||
|
pkt->result = Packet::Success;
|
||||||
|
assert(offset < blkSize);
|
||||||
|
assert(pkt->getSize() <= blkSize);
|
||||||
|
assert(offset + pkt->getSize() <=blkSize);
|
||||||
|
memcpy(pkt->getPtr<uint8_t>(), blk->data + offset,
|
||||||
|
pkt->getSize());
|
||||||
|
}
|
||||||
|
return blk;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hit
|
||||||
|
if (blk->isPrefetch()) {
|
||||||
|
//Signal that this was a hit under prefetch (no need for
|
||||||
|
//use prefetch (only can get here if true)
|
||||||
|
DPRINTF(HWPrefetch, "Hit a block that was prefetched\n");
|
||||||
|
blk->status &= ~BlkHWPrefetched;
|
||||||
|
if (prefetchMiss) {
|
||||||
|
//If we are using the miss stream, signal the
|
||||||
|
//prefetcher otherwise the access stream would have
|
||||||
|
//already signaled this hit
|
||||||
|
prefetcher->handleMiss(pkt, curTick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pkt->isWrite() && blk->isWritable()) ||
|
||||||
|
(pkt->isRead() && blk->isValid())) {
|
||||||
|
|
||||||
|
// We are satisfying the request
|
||||||
|
pkt->flags |= SATISFIED;
|
||||||
|
|
||||||
|
if (blk->isCompressed()) {
|
||||||
|
// If the data is compressed, need to increase the latency
|
||||||
|
lat += (compLatency/4);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool write_data = false;
|
||||||
|
|
||||||
|
assert(verifyData(blk));
|
||||||
|
|
||||||
|
assert(offset < blkSize);
|
||||||
|
assert(pkt->getSize() <= blkSize);
|
||||||
|
assert(offset+pkt->getSize() <= blkSize);
|
||||||
|
|
||||||
|
if (pkt->isWrite()) {
|
||||||
|
if (blk->checkWrite(pkt->req)) {
|
||||||
|
write_data = true;
|
||||||
|
blk->status |= BlkDirty;
|
||||||
|
memcpy(blk->data + offset, pkt->getPtr<uint8_t>(),
|
||||||
|
pkt->getSize());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(pkt->isRead());
|
||||||
|
if (pkt->req->isLocked()) {
|
||||||
|
blk->trackLoadLocked(pkt->req);
|
||||||
|
}
|
||||||
|
memcpy(pkt->getPtr<uint8_t>(), blk->data + offset,
|
||||||
|
pkt->getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write_data ||
|
||||||
|
(adaptiveCompression && blk->isCompressed()))
|
||||||
|
{
|
||||||
|
// If we wrote data, need to update the internal block
|
||||||
|
// data.
|
||||||
|
updateData(blk, writebacks,
|
||||||
|
!(adaptiveCompression &&
|
||||||
|
blk->isReferenced()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// permission violation, treat it as a miss
|
||||||
|
blk = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// complete miss (no matching block)
|
||||||
|
if (pkt->req->isLocked() && pkt->isWrite()) {
|
||||||
|
// miss on store conditional... just give up now
|
||||||
|
pkt->req->setScResult(0);
|
||||||
|
pkt->flags |= SATISFIED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return blk;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class TagStore, class Coherence>
|
||||||
|
typename Cache<TagStore,Coherence>::BlkType*
|
||||||
|
Cache<TagStore,Coherence>::handleFill(BlkType *blk, PacketPtr &pkt,
|
||||||
|
CacheBlk::State new_state,
|
||||||
|
PacketList & writebacks,
|
||||||
|
PacketPtr target)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
BlkType *tmp_blk = findBlock(pkt->getAddr());
|
||||||
|
assert(tmp_blk == blk);
|
||||||
|
#endif
|
||||||
|
blk = doReplacement(blk, pkt, new_state, writebacks);
|
||||||
|
|
||||||
|
|
||||||
|
if (pkt->isRead()) {
|
||||||
|
memcpy(blk->data, pkt->getPtr<uint8_t>(), blkSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
blk->whenReady = pkt->finishTime;
|
||||||
|
|
||||||
|
// Respond to target, if any
|
||||||
|
if (target) {
|
||||||
|
|
||||||
|
target->flags |= SATISFIED;
|
||||||
|
|
||||||
|
if (target->cmd == Packet::InvalidateReq) {
|
||||||
|
invalidateBlk(blk);
|
||||||
|
blk = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blk && (target->isWrite() ? blk->isWritable() : blk->isValid())) {
|
||||||
|
assert(target->isWrite() || target->isRead());
|
||||||
|
assert(target->getOffset(blkSize) + target->getSize() <= blkSize);
|
||||||
|
if (target->isWrite()) {
|
||||||
|
if (blk->checkWrite(pkt->req)) {
|
||||||
|
blk->status |= BlkDirty;
|
||||||
|
memcpy(blk->data + target->getOffset(blkSize),
|
||||||
|
target->getPtr<uint8_t>(), target->getSize());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pkt->req->isLocked()) {
|
||||||
|
blk->trackLoadLocked(pkt->req);
|
||||||
|
}
|
||||||
|
memcpy(target->getPtr<uint8_t>(),
|
||||||
|
blk->data + target->getOffset(blkSize),
|
||||||
|
target->getSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blk) {
|
||||||
|
// Need to write the data into the block
|
||||||
|
updateData(blk, writebacks, !adaptiveCompression || true);
|
||||||
|
}
|
||||||
|
return blk;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class TagStore, class Coherence>
|
||||||
|
typename Cache<TagStore,Coherence>::BlkType*
|
||||||
|
Cache<TagStore,Coherence>::handleFill(BlkType *blk, MSHR * mshr,
|
||||||
|
CacheBlk::State new_state,
|
||||||
|
PacketList & writebacks, PacketPtr pkt)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
#ifndef NDEBUG
|
||||||
|
BlkType *tmp_blk = findBlock(mshr->pkt->getAddr());
|
||||||
|
assert(tmp_blk == blk);
|
||||||
|
#endif
|
||||||
|
PacketPtr pkt = mshr->pkt;*/
|
||||||
|
blk = doReplacement(blk, pkt, new_state, writebacks);
|
||||||
|
|
||||||
|
if (pkt->isRead()) {
|
||||||
|
memcpy(blk->data, pkt->getPtr<uint8_t>(), blkSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
blk->whenReady = pkt->finishTime;
|
||||||
|
|
||||||
|
|
||||||
|
// respond to MSHR targets, if any
|
||||||
|
|
||||||
|
// First offset for critical word first calculations
|
||||||
|
int initial_offset = 0;
|
||||||
|
|
||||||
|
if (mshr->hasTargets()) {
|
||||||
|
initial_offset = mshr->getTarget()->getOffset(blkSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (mshr->hasTargets()) {
|
||||||
|
PacketPtr target = mshr->getTarget();
|
||||||
|
|
||||||
|
target->flags |= SATISFIED;
|
||||||
|
|
||||||
|
// How many bytes pass the first request is this one
|
||||||
|
int transfer_offset = target->getOffset(blkSize) - initial_offset;
|
||||||
|
if (transfer_offset < 0) {
|
||||||
|
transfer_offset += blkSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If critical word (no offset) return first word time
|
||||||
|
Tick completion_time = tags->getHitLatency() +
|
||||||
|
transfer_offset ? pkt->finishTime : pkt->firstWordTime;
|
||||||
|
|
||||||
|
if (target->cmd == Packet::InvalidateReq) {
|
||||||
|
//Mark the blk as invalid now, if it hasn't been already
|
||||||
|
if (blk) {
|
||||||
|
invalidateBlk(blk);
|
||||||
|
blk = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Also get rid of the invalidate
|
||||||
|
mshr->popTarget();
|
||||||
|
|
||||||
|
DPRINTF(Cache, "Popping off a Invalidate for addr %x\n",
|
||||||
|
pkt->getAddr());
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blk && (target->isWrite() ? blk->isWritable() : blk->isValid())) {
|
||||||
|
assert(target->isWrite() || target->isRead());
|
||||||
|
assert(target->getOffset(blkSize) + target->getSize() <= blkSize);
|
||||||
|
if (target->isWrite()) {
|
||||||
|
if (blk->checkWrite(pkt->req)) {
|
||||||
|
blk->status |= BlkDirty;
|
||||||
|
memcpy(blk->data + target->getOffset(blkSize),
|
||||||
|
target->getPtr<uint8_t>(), target->getSize());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pkt->req->isLocked()) {
|
||||||
|
blk->trackLoadLocked(pkt->req);
|
||||||
|
}
|
||||||
|
memcpy(target->getPtr<uint8_t>(),
|
||||||
|
blk->data + target->getOffset(blkSize),
|
||||||
|
target->getSize());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Invalid access, need to do another request
|
||||||
|
// can occur if block is invalidated, or not correct
|
||||||
|
// permissions
|
||||||
|
// mshr->pkt = pkt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
respondToMiss(target, completion_time);
|
||||||
|
mshr->popTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blk) {
|
||||||
|
// Need to write the data into the block
|
||||||
|
updateData(blk, writebacks, !adaptiveCompression || true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return blk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class TagStore, class Coherence>
|
||||||
|
void
|
||||||
|
Cache<TagStore,Coherence>::handleSnoop(BlkType *blk,
|
||||||
|
CacheBlk::State new_state,
|
||||||
|
PacketPtr &pkt)
|
||||||
|
{
|
||||||
|
//Must have the block to supply
|
||||||
|
assert(blk);
|
||||||
|
// Can only supply data, and if it hasn't already been supllied
|
||||||
|
assert(pkt->isRead());
|
||||||
|
assert(!(pkt->flags & SATISFIED));
|
||||||
|
pkt->flags |= SATISFIED;
|
||||||
|
Addr offset = pkt->getOffset(blkSize);
|
||||||
|
assert(offset < blkSize);
|
||||||
|
assert(pkt->getSize() <= blkSize);
|
||||||
|
assert(offset + pkt->getSize() <=blkSize);
|
||||||
|
memcpy(pkt->getPtr<uint8_t>(), blk->data + offset, pkt->getSize());
|
||||||
|
|
||||||
|
handleSnoop(blk, new_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class TagStore, class Coherence>
|
||||||
|
void
|
||||||
|
Cache<TagStore,Coherence>::handleSnoop(BlkType *blk,
|
||||||
|
CacheBlk::State new_state)
|
||||||
|
{
|
||||||
|
if (blk && blk->status != new_state) {
|
||||||
|
if ((new_state && BlkValid) == 0) {
|
||||||
|
invalidateBlk(blk);
|
||||||
|
} else {
|
||||||
|
assert(new_state >= 0 && new_state < 128);
|
||||||
|
blk->status = new_state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class TagStore, class Coherence>
|
||||||
|
PacketPtr
|
||||||
|
Cache<TagStore,Coherence>::writebackBlk(BlkType *blk)
|
||||||
|
{
|
||||||
|
assert(blk && blk->isValid() && blk->isModified());
|
||||||
|
int data_size = blkSize;
|
||||||
|
data_size = blk->size;
|
||||||
|
if (compressOnWriteback) {
|
||||||
|
// not already compressed
|
||||||
|
// need to compress to ship it
|
||||||
|
assert(data_size == blkSize);
|
||||||
|
uint8_t *tmp_data = new uint8_t[blkSize];
|
||||||
|
data_size = compressionAlg->compress(tmp_data,blk->data,
|
||||||
|
data_size);
|
||||||
|
delete [] tmp_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PacketPtr writeback =
|
||||||
|
buildWritebackReq(tags->regenerateBlkAddr(blk->tag, blk->set),
|
||||||
|
blk->asid, blkSize,
|
||||||
|
blk->data, data_size);
|
||||||
|
*/
|
||||||
|
|
||||||
|
Request *writebackReq =
|
||||||
|
new Request(tags->regenerateBlkAddr(blk->tag, blk->set), blkSize, 0);
|
||||||
|
PacketPtr writeback = new Packet(writebackReq, Packet::Writeback, -1);
|
||||||
|
writeback->allocate();
|
||||||
|
memcpy(writeback->getPtr<uint8_t>(),blk->data,blkSize);
|
||||||
|
|
||||||
|
blk->status &= ~BlkDirty;
|
||||||
|
return writeback;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class TagStore, class Coherence>
|
||||||
|
bool
|
||||||
|
Cache<TagStore,Coherence>::verifyData(BlkType *blk)
|
||||||
|
{
|
||||||
|
bool retval;
|
||||||
|
// The data stored in the blk
|
||||||
|
uint8_t *blk_data = new uint8_t[blkSize];
|
||||||
|
tags->readData(blk, blk_data);
|
||||||
|
// Pointer for uncompressed data, assumed uncompressed
|
||||||
|
uint8_t *tmp_data = blk_data;
|
||||||
|
// The size of the data being stored, assumed uncompressed
|
||||||
|
int data_size = blkSize;
|
||||||
|
|
||||||
|
// If the block is compressed need to uncompress to access
|
||||||
|
if (blk->isCompressed()){
|
||||||
|
// Allocate new storage for the data
|
||||||
|
tmp_data = new uint8_t[blkSize];
|
||||||
|
data_size = compressionAlg->uncompress(tmp_data,blk_data, blk->size);
|
||||||
|
assert(data_size == blkSize);
|
||||||
|
// Don't need to keep blk_data around
|
||||||
|
delete [] blk_data;
|
||||||
|
} else {
|
||||||
|
assert(blkSize == blk->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = memcmp(tmp_data, blk->data, blkSize) == 0;
|
||||||
|
delete [] tmp_data;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class TagStore, class Coherence>
|
||||||
|
void
|
||||||
|
Cache<TagStore,Coherence>::updateData(BlkType *blk, PacketList &writebacks,
|
||||||
|
bool compress_block)
|
||||||
|
{
|
||||||
|
if (storeCompressed && compress_block) {
|
||||||
|
uint8_t *comp_data = new uint8_t[blkSize];
|
||||||
|
int new_size = compressionAlg->compress(comp_data, blk->data, blkSize);
|
||||||
|
if (new_size > (blkSize - tags->getSubBlockSize())){
|
||||||
|
// no benefit to storing it compressed
|
||||||
|
blk->status &= ~BlkCompressed;
|
||||||
|
tags->writeData(blk, blk->data, blkSize,
|
||||||
|
writebacks);
|
||||||
|
} else {
|
||||||
|
// Store the data compressed
|
||||||
|
blk->status |= BlkCompressed;
|
||||||
|
tags->writeData(blk, comp_data, new_size,
|
||||||
|
writebacks);
|
||||||
|
}
|
||||||
|
delete [] comp_data;
|
||||||
|
} else {
|
||||||
|
blk->status &= ~BlkCompressed;
|
||||||
|
tags->writeData(blk, blk->data, blkSize, writebacks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class TagStore, class Coherence>
|
||||||
|
typename Cache<TagStore,Coherence>::BlkType*
|
||||||
|
Cache<TagStore,Coherence>::doReplacement(BlkType *blk, PacketPtr &pkt,
|
||||||
|
CacheBlk::State new_state,
|
||||||
|
PacketList &writebacks)
|
||||||
|
{
|
||||||
|
if (blk == NULL) {
|
||||||
|
// need to do a replacement
|
||||||
|
BlkList compress_list;
|
||||||
|
blk = tags->findReplacement(pkt, writebacks, compress_list);
|
||||||
|
while (adaptiveCompression && !compress_list.empty()) {
|
||||||
|
updateData(compress_list.front(), writebacks, true);
|
||||||
|
compress_list.pop_front();
|
||||||
|
}
|
||||||
|
if (blk->isValid()) {
|
||||||
|
DPRINTF(Cache, "replacement: replacing %x with %x: %s\n",
|
||||||
|
tags->regenerateBlkAddr(blk->tag,blk->set), pkt->getAddr(),
|
||||||
|
(blk->isModified()) ? "writeback" : "clean");
|
||||||
|
|
||||||
|
if (blk->isModified()) {
|
||||||
|
// Need to write the data back
|
||||||
|
writebacks.push_back(writebackBlk(blk));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
blk->tag = tags->extractTag(pkt->getAddr(), blk);
|
||||||
|
} else {
|
||||||
|
// must be a status change
|
||||||
|
// assert(blk->status != new_state);
|
||||||
|
if (blk->status == new_state) warn("Changing state to same value\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
blk->status = new_state;
|
||||||
|
return blk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class TagStore, class Coherence>
|
template<class TagStore, class Coherence>
|
||||||
bool
|
bool
|
||||||
Cache<TagStore,Coherence>::access(PacketPtr &pkt)
|
Cache<TagStore,Coherence>::access(PacketPtr &pkt)
|
||||||
|
@ -112,7 +547,7 @@ Cache<TagStore,Coherence>::access(PacketPtr &pkt)
|
||||||
prefetcher->handleMiss(pkt, curTick);
|
prefetcher->handleMiss(pkt, curTick);
|
||||||
}
|
}
|
||||||
if (!pkt->req->isUncacheable()) {
|
if (!pkt->req->isUncacheable()) {
|
||||||
blk = tags->handleAccess(pkt, lat, writebacks);
|
blk = handleAccess(pkt, lat, writebacks);
|
||||||
} else {
|
} else {
|
||||||
size = pkt->getSize();
|
size = pkt->getSize();
|
||||||
}
|
}
|
||||||
|
@ -130,7 +565,7 @@ Cache<TagStore,Coherence>::access(PacketPtr &pkt)
|
||||||
warn("WriteInv doing a fastallocate"
|
warn("WriteInv doing a fastallocate"
|
||||||
"with an outstanding miss to the same address\n");
|
"with an outstanding miss to the same address\n");
|
||||||
}
|
}
|
||||||
blk = tags->handleFill(NULL, pkt, BlkValid | BlkWritable,
|
blk = handleFill(NULL, pkt, BlkValid | BlkWritable,
|
||||||
writebacks);
|
writebacks);
|
||||||
++fastWrites;
|
++fastWrites;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +630,7 @@ Cache<TagStore,Coherence>::getPacket()
|
||||||
if (!pkt->req->isUncacheable()) {
|
if (!pkt->req->isUncacheable()) {
|
||||||
if (pkt->cmd == Packet::HardPFReq)
|
if (pkt->cmd == Packet::HardPFReq)
|
||||||
misses[Packet::HardPFReq][0/*pkt->req->getThreadNum()*/]++;
|
misses[Packet::HardPFReq][0/*pkt->req->getThreadNum()*/]++;
|
||||||
BlkType *blk = tags->findBlock(pkt);
|
BlkType *blk = findBlock(pkt);
|
||||||
Packet::Command cmd = coherence->getBusCmd(pkt->cmd,
|
Packet::Command cmd = coherence->getBusCmd(pkt->cmd,
|
||||||
(blk)? blk->status : 0);
|
(blk)? blk->status : 0);
|
||||||
missQueue->setBusCmd(pkt, cmd);
|
missQueue->setBusCmd(pkt, cmd);
|
||||||
|
@ -224,7 +659,7 @@ Cache<TagStore,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr,
|
||||||
if (upgrade) {
|
if (upgrade) {
|
||||||
assert(pkt); //Upgrades need to be fixed
|
assert(pkt); //Upgrades need to be fixed
|
||||||
pkt->flags &= ~CACHE_LINE_FILL;
|
pkt->flags &= ~CACHE_LINE_FILL;
|
||||||
BlkType *blk = tags->findBlock(pkt);
|
BlkType *blk = findBlock(pkt);
|
||||||
CacheBlk::State old_state = (blk) ? blk->status : 0;
|
CacheBlk::State old_state = (blk) ? blk->status : 0;
|
||||||
CacheBlk::State new_state = coherence->getNewState(pkt,old_state);
|
CacheBlk::State new_state = coherence->getNewState(pkt,old_state);
|
||||||
if (old_state != new_state)
|
if (old_state != new_state)
|
||||||
|
@ -233,7 +668,7 @@ Cache<TagStore,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr,
|
||||||
//Set the state on the upgrade
|
//Set the state on the upgrade
|
||||||
memcpy(pkt->getPtr<uint8_t>(), blk->data, blkSize);
|
memcpy(pkt->getPtr<uint8_t>(), blk->data, blkSize);
|
||||||
PacketList writebacks;
|
PacketList writebacks;
|
||||||
tags->handleFill(blk, mshr, new_state, writebacks, pkt);
|
handleFill(blk, mshr, new_state, writebacks, pkt);
|
||||||
assert(writebacks.empty());
|
assert(writebacks.empty());
|
||||||
missQueue->handleResponse(pkt, curTick + hitLatency);
|
missQueue->handleResponse(pkt, curTick + hitLatency);
|
||||||
}
|
}
|
||||||
|
@ -275,7 +710,7 @@ Cache<TagStore,Coherence>::handleResponse(PacketPtr &pkt)
|
||||||
if (pkt->isCacheFill() && !pkt->isNoAllocate()) {
|
if (pkt->isCacheFill() && !pkt->isNoAllocate()) {
|
||||||
DPRINTF(Cache, "Block for addr %x being updated in Cache\n",
|
DPRINTF(Cache, "Block for addr %x being updated in Cache\n",
|
||||||
pkt->getAddr());
|
pkt->getAddr());
|
||||||
blk = tags->findBlock(pkt);
|
blk = findBlock(pkt);
|
||||||
CacheBlk::State old_state = (blk) ? blk->status : 0;
|
CacheBlk::State old_state = (blk) ? blk->status : 0;
|
||||||
PacketList writebacks;
|
PacketList writebacks;
|
||||||
CacheBlk::State new_state = coherence->getNewState(pkt,old_state);
|
CacheBlk::State new_state = coherence->getNewState(pkt,old_state);
|
||||||
|
@ -284,7 +719,7 @@ Cache<TagStore,Coherence>::handleResponse(PacketPtr &pkt)
|
||||||
"state %i to %i\n",
|
"state %i to %i\n",
|
||||||
pkt->getAddr(),
|
pkt->getAddr(),
|
||||||
old_state, new_state);
|
old_state, new_state);
|
||||||
blk = tags->handleFill(blk, (MSHR*)pkt->senderState,
|
blk = handleFill(blk, (MSHR*)pkt->senderState,
|
||||||
new_state, writebacks, pkt);
|
new_state, writebacks, pkt);
|
||||||
while (!writebacks.empty()) {
|
while (!writebacks.empty()) {
|
||||||
missQueue->doWriteback(writebacks.front());
|
missQueue->doWriteback(writebacks.front());
|
||||||
|
@ -332,7 +767,7 @@ Cache<TagStore,Coherence>::snoop(PacketPtr &pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
|
Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
|
||||||
BlkType *blk = tags->findBlock(pkt);
|
BlkType *blk = findBlock(pkt);
|
||||||
MSHR *mshr = missQueue->findMSHR(blk_addr);
|
MSHR *mshr = missQueue->findMSHR(blk_addr);
|
||||||
if (coherence->hasProtocol() || pkt->isInvalidate()) {
|
if (coherence->hasProtocol() || pkt->isInvalidate()) {
|
||||||
//@todo Move this into handle bus req
|
//@todo Move this into handle bus req
|
||||||
|
@ -435,7 +870,7 @@ Cache<TagStore,Coherence>::snoop(PacketPtr &pkt)
|
||||||
"now supplying data, new state is %i\n",
|
"now supplying data, new state is %i\n",
|
||||||
pkt->cmdString(), blk_addr, new_state);
|
pkt->cmdString(), blk_addr, new_state);
|
||||||
|
|
||||||
tags->handleSnoop(blk, new_state, pkt);
|
handleSnoop(blk, new_state, pkt);
|
||||||
respondToSnoop(pkt, curTick + hitLatency);
|
respondToSnoop(pkt, curTick + hitLatency);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -443,7 +878,7 @@ Cache<TagStore,Coherence>::snoop(PacketPtr &pkt)
|
||||||
DPRINTF(Cache, "Cache snooped a %s request for addr %x, "
|
DPRINTF(Cache, "Cache snooped a %s request for addr %x, "
|
||||||
"new state is %i\n", pkt->cmdString(), blk_addr, new_state);
|
"new state is %i\n", pkt->cmdString(), blk_addr, new_state);
|
||||||
|
|
||||||
tags->handleSnoop(blk, new_state);
|
handleSnoop(blk, new_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class TagStore, class Coherence>
|
template<class TagStore, class Coherence>
|
||||||
|
@ -501,7 +936,7 @@ Cache<TagStore,Coherence>::probe(PacketPtr &pkt, bool update,
|
||||||
PacketList writebacks;
|
PacketList writebacks;
|
||||||
int lat;
|
int lat;
|
||||||
|
|
||||||
BlkType *blk = tags->handleAccess(pkt, lat, writebacks, update);
|
BlkType *blk = handleAccess(pkt, lat, writebacks, update);
|
||||||
|
|
||||||
DPRINTF(Cache, "%s %x %s\n", pkt->cmdString(),
|
DPRINTF(Cache, "%s %x %s\n", pkt->cmdString(),
|
||||||
pkt->getAddr(), (blk) ? "hit" : "miss");
|
pkt->getAddr(), (blk) ? "hit" : "miss");
|
||||||
|
@ -557,7 +992,7 @@ Cache<TagStore,Coherence>::probe(PacketPtr &pkt, bool update,
|
||||||
if (!pkt->req->isUncacheable() /*Uncacheables just go through*/
|
if (!pkt->req->isUncacheable() /*Uncacheables just go through*/
|
||||||
&& (pkt->cmd != Packet::Writeback)/*Writebacks on miss fall through*/) {
|
&& (pkt->cmd != Packet::Writeback)/*Writebacks on miss fall through*/) {
|
||||||
// Fetch the cache block to fill
|
// Fetch the cache block to fill
|
||||||
BlkType *blk = tags->findBlock(pkt);
|
BlkType *blk = findBlock(pkt);
|
||||||
Packet::Command temp_cmd = coherence->getBusCmd(pkt->cmd,
|
Packet::Command temp_cmd = coherence->getBusCmd(pkt->cmd,
|
||||||
(blk)? blk->status : 0);
|
(blk)? blk->status : 0);
|
||||||
|
|
||||||
|
@ -593,7 +1028,7 @@ return 0;
|
||||||
DPRINTF(Cache, "Block for blk addr %x moving from state "
|
DPRINTF(Cache, "Block for blk addr %x moving from state "
|
||||||
"%i to %i\n", busPkt->getAddr(), old_state, new_state);
|
"%i to %i\n", busPkt->getAddr(), old_state, new_state);
|
||||||
|
|
||||||
tags->handleFill(blk, busPkt, new_state, writebacks, pkt);
|
handleFill(blk, busPkt, new_state, writebacks, pkt);
|
||||||
//Free the packet
|
//Free the packet
|
||||||
delete busPkt;
|
delete busPkt;
|
||||||
|
|
||||||
|
@ -639,7 +1074,7 @@ Cache<TagStore,Coherence>::snoopProbe(PacketPtr &pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
|
Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
|
||||||
BlkType *blk = tags->findBlock(pkt);
|
BlkType *blk = findBlock(pkt);
|
||||||
MSHR *mshr = missQueue->findMSHR(blk_addr);
|
MSHR *mshr = missQueue->findMSHR(blk_addr);
|
||||||
CacheBlk::State new_state = 0;
|
CacheBlk::State new_state = 0;
|
||||||
bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
|
bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
|
||||||
|
@ -648,14 +1083,14 @@ Cache<TagStore,Coherence>::snoopProbe(PacketPtr &pkt)
|
||||||
"now supplying data, new state is %i\n",
|
"now supplying data, new state is %i\n",
|
||||||
pkt->cmdString(), blk_addr, new_state);
|
pkt->cmdString(), blk_addr, new_state);
|
||||||
|
|
||||||
tags->handleSnoop(blk, new_state, pkt);
|
handleSnoop(blk, new_state, pkt);
|
||||||
return hitLatency;
|
return hitLatency;
|
||||||
}
|
}
|
||||||
if (blk)
|
if (blk)
|
||||||
DPRINTF(Cache, "Cache snooped a %s request for addr %x, "
|
DPRINTF(Cache, "Cache snooped a %s request for addr %x, "
|
||||||
"new state is %i\n",
|
"new state is %i\n",
|
||||||
pkt->cmdString(), blk_addr, new_state);
|
pkt->cmdString(), blk_addr, new_state);
|
||||||
tags->handleSnoop(blk, new_state);
|
handleSnoop(blk, new_state);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
src/mem/cache/prefetch/ghb_prefetcher.cc
vendored
4
src/mem/cache/prefetch/ghb_prefetcher.cc
vendored
|
@ -34,8 +34,6 @@
|
||||||
* GHB Prefetcher template instantiations.
|
* GHB Prefetcher template instantiations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mem/cache/tags/cache_tags.hh"
|
|
||||||
|
|
||||||
#include "mem/cache/tags/lru.hh"
|
#include "mem/cache/tags/lru.hh"
|
||||||
|
|
||||||
#include "mem/cache/prefetch/ghb_prefetcher.hh"
|
#include "mem/cache/prefetch/ghb_prefetcher.hh"
|
||||||
|
@ -43,6 +41,6 @@
|
||||||
// Template Instantiations
|
// Template Instantiations
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
template class GHBPrefetcher<CacheTags<LRU> >;
|
template class GHBPrefetcher<LRU >;
|
||||||
|
|
||||||
#endif //DOXYGEN_SHOULD_SKIP_THIS
|
#endif //DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
4
src/mem/cache/prefetch/stride_prefetcher.cc
vendored
4
src/mem/cache/prefetch/stride_prefetcher.cc
vendored
|
@ -34,8 +34,6 @@
|
||||||
* Stride Prefetcher template instantiations.
|
* Stride Prefetcher template instantiations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mem/cache/tags/cache_tags.hh"
|
|
||||||
|
|
||||||
#include "mem/cache/tags/lru.hh"
|
#include "mem/cache/tags/lru.hh"
|
||||||
|
|
||||||
#include "mem/cache/prefetch/stride_prefetcher.hh"
|
#include "mem/cache/prefetch/stride_prefetcher.hh"
|
||||||
|
@ -43,6 +41,6 @@
|
||||||
// Template Instantiations
|
// Template Instantiations
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
template class StridePrefetcher<CacheTags<LRU> >;
|
template class StridePrefetcher<LRU >;
|
||||||
|
|
||||||
#endif //DOXYGEN_SHOULD_SKIP_THIS
|
#endif //DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
Loading…
Reference in a new issue