Go to the documentation of this file.
46 #include "debug/HtmMem.hh"
47 #include "debug/RubyCache.hh"
48 #include "debug/RubyCacheTrace.hh"
49 #include "debug/RubyResourceStalls.hh"
50 #include "debug/RubyStats.hh"
52 #include "mem/ruby/protocol/AccessPermission.hh"
65 dataArray(
p.dataArrayBanks,
p.dataAccessLatency,
66 p.start_index_bit,
p.ruby_system),
67 tagArray(
p.tagArrayBanks,
p.tagAccessLatency,
68 p.start_index_bit,
p.ruby_system),
69 cacheMemoryStats(this)
135 if (
m_cache[cacheSet][it->second]->m_Permission !=
136 AccessPermission_NotPresent)
182 DPRINTF(RubyCache,
"address: %#x\n", address);
184 if (entry !=
nullptr) {
190 if (entry->
m_Permission == AccessPermission_Read_Write) {
193 if ((entry->
m_Permission == AccessPermission_Read_Only) &&
194 (
type == RubyRequestType_LD ||
type == RubyRequestType_IFETCH)) {
207 DPRINTF(RubyCache,
"address: %#x\n", address);
209 if (entry !=
nullptr) {
215 return entry->
m_Permission != AccessPermission_NotPresent;
227 if (entry ==
nullptr) {
229 DPRINTF(RubyCache,
"No tag match for address: %#x\n", address);
232 DPRINTF(RubyCache,
"address: %#x found\n", address);
267 DPRINTF(RubyCache,
"address: %#x\n", address);
273 if (!set[
i] || set[
i]->m_Permission == AccessPermission_NotPresent) {
274 if (set[
i] && (set[
i] != entry)) {
275 warn_once(
"This protocol contains a cache entry handling bug: "
276 "Entries in the cache should never be NotPresent! If\n"
277 "this entry (%#x) is not tracked elsewhere, it will memory "
278 "leak here. Fix your protocol to eliminate these!",
282 set[
i]->m_Address = address;
283 set[
i]->m_Permission = AccessPermission_Invalid;
284 DPRINTF(RubyCache,
"Allocate clearing lock for addr: %x\n",
286 set[
i]->m_locked = -1;
288 set[
i]->setPosition(cacheSet,
i);
299 panic(
"Allocate didn't find an available entry");
305 DPRINTF(RubyCache,
"address: %#x\n", address);
307 assert(entry !=
nullptr);
309 uint32_t cache_set = entry->
getSet();
310 uint32_t way = entry->
getWay();
312 m_cache[cache_set][way] = NULL;
330 getVictim(candidates)->getWay()]->m_Address;
340 if (loc == -1)
return NULL;
351 if (loc == -1)
return NULL;
360 if (entry !=
nullptr) {
369 assert(entry !=
nullptr);
378 if (entry !=
nullptr) {
399 if (
m_cache[set][loc] != NULL) {
400 ret =
m_cache[set][loc]->getNumValidBlocks();
410 uint64_t warmedUpBlocks = 0;
418 RubyRequestType request_type = RubyRequestType_NULL;
419 if (
perm == AccessPermission_Read_Only) {
421 request_type = RubyRequestType_IFETCH;
423 request_type = RubyRequestType_LD;
425 }
else if (
perm == AccessPermission_Read_Write) {
426 request_type = RubyRequestType_ST;
429 if (request_type != RubyRequestType_NULL) {
431 lastAccessTick =
m_cache[
i][
j]->getLastAccess();
433 0, request_type, lastAccessTick,
441 DPRINTF(RubyCacheTrace,
"%s: %lli blocks of %lli total blocks"
442 "recorded %.2f%% \n",
name().c_str(), warmedUpBlocks,
443 totalBlocks, (
float(warmedUpBlocks) /
float(totalBlocks)) * 100.0);
449 out <<
"Cache dump: " <<
name() << std::endl;
453 out <<
" Index: " <<
i
455 <<
" entry: " << *
m_cache[
i][
j] << std::endl;
457 out <<
" Index: " <<
i
459 <<
" entry: NULL" << std::endl;
468 out <<
"printData() not supported" << std::endl;
474 DPRINTF(RubyCache,
"Setting Lock for addr: %#x to %d\n", address, context);
476 assert(entry !=
nullptr);
483 DPRINTF(RubyCache,
"Clear Lock for addr: %#x\n", address);
485 assert(entry !=
nullptr);
495 for (
auto j = set.begin();
j != set.end(); ++
j) {
497 if (line && line->
isLocked(context)) {
498 DPRINTF(RubyCache,
"Clear Lock for addr: %#x\n",
510 assert(entry !=
nullptr);
511 DPRINTF(RubyCache,
"Testing Lock for addr: %#llx cur %d con %d\n",
518 :
Stats::Group(parent),
519 ADD_STAT(numDataArrayReads,
"Number of data array reads"),
520 ADD_STAT(numDataArrayWrites,
"Number of data array writes"),
521 ADD_STAT(numTagArrayReads,
"Number of tag array reads"),
522 ADD_STAT(numTagArrayWrites,
"Number of tag array writes"),
523 ADD_STAT(numTagArrayStalls,
"Number of stalls caused by tag array"),
524 ADD_STAT(numDataArrayStalls,
"Number of stalls caused by data array"),
525 ADD_STAT(htmTransCommitReadSet,
"Read set size of a committed "
527 ADD_STAT(htmTransCommitWriteSet,
"Write set size of a committed "
529 ADD_STAT(htmTransAbortReadSet,
"Read set size of a aborted transaction"),
530 ADD_STAT(htmTransAbortWriteSet,
"Write set size of a aborted "
532 ADD_STAT(m_demand_hits,
"Number of cache demand hits"),
533 ADD_STAT(m_demand_misses,
"Number of cache demand misses"),
534 ADD_STAT(m_demand_accesses,
"Number of cache demand accesses",
535 m_demand_hits + m_demand_misses),
536 ADD_STAT(m_prefetch_hits,
"Number of cache prefetch hits"),
537 ADD_STAT(m_prefetch_misses,
"Number of cache prefetch misses"),
538 ADD_STAT(m_prefetch_accesses,
"Number of cache prefetch accesses",
539 m_prefetch_hits + m_prefetch_misses),
586 .
init(RubyRequestType_NUM)
589 for (
int i = 0;
i < RubyAccessMode_NUM;
i++) {
591 .
subname(
i, RubyAccessMode_to_string(RubyAccessMode(
i)))
602 DPRINTF(RubyStats,
"Recorded statistic: %s\n",
603 CacheRequestType_to_string(requestType));
604 switch(requestType) {
605 case CacheRequestType_DataArrayRead:
610 case CacheRequestType_DataArrayWrite:
615 case CacheRequestType_TagArrayRead:
620 case CacheRequestType_TagArrayWrite:
626 warn(
"CacheMemory access_type not found: %s",
627 CacheRequestType_to_string(requestType));
638 if (res == CacheResourceType_TagArray) {
642 "Tag array stall on addr %#x in set %d\n",
647 }
else if (res == CacheResourceType_DataArray) {
651 "Data array stall on addr %#x in set %d\n",
657 panic(
"Unrecognized cache resource type.");
664 return (
m_cache[cache_set][loc]->m_Permission == AccessPermission_Invalid);
670 return (
m_cache[cache_set][loc]->m_Permission != AccessPermission_Busy);
678 uint64_t htmReadSetSize = 0;
679 uint64_t htmWriteSetSize = 0;
686 for (
auto j = set.begin();
j != set.end(); ++
j)
690 if (line !=
nullptr) {
705 DPRINTF(HtmMem,
"htmAbortTransaction: read set=%u write set=%u\n",
706 htmReadSetSize, htmWriteSetSize);
712 uint64_t htmReadSetSize = 0;
713 uint64_t htmWriteSetSize = 0;
720 for (
auto j = set.begin();
j != set.end(); ++
j)
723 if (line !=
nullptr) {
735 DPRINTF(HtmMem,
"htmCommitTransaction: read set=%u write set=%u\n",
736 htmReadSetSize, htmWriteSetSize);
void recordCacheContents(int cntrl, CacheRecorder *tr) const
CacheMemory::CacheMemoryStats cacheMemoryStats
A replaceable entry is a basic entry in a 2d table-like structure that needs to have replacement func...
int findTagInSetIgnorePermissions(int64_t cacheSet, Addr tag) const
CacheMemoryStats(Stats::Group *parent)
void setInHtmWriteSet(bool val)
Stats::Scalar numDataArrayWrites
void clearLocked(Addr addr)
AbstractCacheEntry * lookup(Addr address)
static uint32_t getBlockSizeBytes()
bool isLocked(Addr addr, int context)
Addr makeLineAddress(Addr addr)
virtual void touch(const std::shared_ptr< ReplacementData > &replacement_data) const =0
Update replacement data.
void setLocked(int context)
AccessPermission m_Permission
std::vector< std::vector< AbstractCacheEntry * > > m_cache
Stats::Formula m_prefetch_accesses
Addr cacheProbe(Addr address) const
uint32_t getSet() const
Get set number.
uint64_t Tick
Tick count type.
bool getInHtmWriteSet() const
void setInHtmReadSet(bool val)
std::unordered_map< Addr, int > m_tag_index
bool getInHtmReadSet() const
bool tryAccess(int64_t idx)
void addRecord(int cntrl, Addr data_addr, Addr pc_addr, RubyRequestType type, Tick time, DataBlock &data)
void print(std::ostream &out) const
Stats::Scalar numDataArrayStalls
void setMRU(Addr address)
Stats::Scalar numTagArrayReads
void deallocate(Addr address)
Stats::Histogram htmTransAbortReadSet
bool testCacheAccess(Addr address, RubyRequestType type, DataBlock *&data_ptr)
bool m_use_occupancy
Set to true when using WeightedLRU replacement policy, otherwise, set to false.
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
virtual void invalidateEntry()
virtual void reset(const std::shared_ptr< ReplacementData > &replacement_data) const =0
Reset replacement data.
Stats::Histogram htmTransCommitReadSet
ReplacementPolicy::Base * m_replacementPolicy_ptr
We use the replacement policies from the Classic memory system.
AbstractCacheEntry * allocate(Addr address, AbstractCacheEntry *new_entry)
void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
std::vector< std::vector< ReplData > > replacement_data
We store all the ReplacementData in a 2-dimensional array.
Stats::Scalar m_prefetch_hits
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
void printData(std::ostream &out) const
CacheMemory(const Params &p)
bool cacheAvail(Addr address) const
Addr bitSelect(Addr addr, unsigned int small, unsigned int big)
Stats::Scalar m_prefetch_misses
bool isBlockInvalid(int64_t cache_set, int64_t loc)
std::shared_ptr< ReplacementPolicy::ReplacementData > replacementData
Replacement data associated to this entry.
Stats::Histogram htmTransCommitWriteSet
virtual void invalidate(const std::shared_ptr< ReplacementData > &replacement_data) const =0
Invalidate replacement data to set it as the next probable victim.
Stats::Scalar numDataArrayReads
Stats::Scalar m_demand_hits
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
int findTagInSet(int64_t line, Addr tag) const
const FlagsType dist
Print the distribution.
Derived & init(size_type size)
Set this vector to have the given size.
bool isLocked(int context) const
void clearLockedAll(int context)
Stats::Scalar m_demand_misses
const FlagsType nozero
Don't print if this is zero.
virtual std::shared_ptr< ReplacementData > instantiateEntry()=0
Instantiate a replacement data entry.
virtual const std::string name() const
void setLastAccess(Tick tick)
bool tryCacheAccess(Addr address, RubyRequestType type, DataBlock *&data_ptr)
std::enable_if_t< std::is_integral< T >::value, int > floorLog2(T x)
void htmCommitTransaction()
void setLocked(Addr addr, int context)
std::ostream & operator<<(std::ostream &out, const CacheMemory &obj)
const FlagsType pdf
Print the percent of the total that this entry represents.
bool isTagPresent(Addr address) const
void profilePrefetchHit()
Stats::Vector m_accessModeType
Addr getAddressAtIdx(int idx) const
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
bool m_is_instruction_only_cache
int64_t addressToCacheSet(Addr address) const
Stats::Scalar numTagArrayWrites
Derived & subname(off_type index, const std::string &name)
Set the subfield name for the given index, and marks this stat to print at the end of simulation.
Tick curTick()
The universal simulation clock.
void profilePrefetchMiss()
Histogram & init(size_type size)
Set the parameters of this histogram.
bool checkResourceAvailable(CacheResourceType res, Addr addr)
Stats::Histogram htmTransAbortWriteSet
const FlagsType total
Print the total.
void reserve(int64_t idx)
Stats::Scalar numTagArrayStalls
void recordRequestType(CacheRequestType requestType, Addr addr)
void htmAbortTransaction()
int getReplacementWeight(int64_t set, int64_t loc)
const FlagsType nonan
Don't print if this is NAN.
virtual DataBlock & getDataBlk()
#define panic(...)
This implements a cprintf based panic() function.
bool isBlockNotBusy(int64_t cache_set, int64_t loc)
uint32_t getWay() const
Get way number.
Abstract superclass for simulation objects.
Generated on Tue Jun 22 2021 15:28:30 for gem5 by doxygen 1.8.17