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"
66 RubyCacheParams::create()
73 dataArray(
p->dataArrayBanks,
p->dataAccessLatency,
74 p->start_index_bit,
p->ruby_system),
75 tagArray(
p->tagArrayBanks,
p->tagAccessLatency,
76 p->start_index_bit,
p->ruby_system)
142 if (
m_cache[cacheSet][it->second]->m_Permission !=
143 AccessPermission_NotPresent)
189 DPRINTF(RubyCache,
"address: %#x\n", address);
191 if (entry !=
nullptr) {
197 if (entry->
m_Permission == AccessPermission_Read_Write) {
200 if ((entry->
m_Permission == AccessPermission_Read_Only) &&
201 (
type == RubyRequestType_LD ||
type == RubyRequestType_IFETCH)) {
214 DPRINTF(RubyCache,
"address: %#x\n", address);
216 if (entry !=
nullptr) {
222 return entry->
m_Permission != AccessPermission_NotPresent;
234 if (entry ==
nullptr) {
236 DPRINTF(RubyCache,
"No tag match for address: %#x\n", address);
239 DPRINTF(RubyCache,
"address: %#x found\n", address);
274 DPRINTF(RubyCache,
"address: %#x\n", address);
280 if (!set[
i] || set[
i]->m_Permission == AccessPermission_NotPresent) {
281 if (set[
i] && (set[
i] != entry)) {
282 warn_once(
"This protocol contains a cache entry handling bug: "
283 "Entries in the cache should never be NotPresent! If\n"
284 "this entry (%#x) is not tracked elsewhere, it will memory "
285 "leak here. Fix your protocol to eliminate these!",
289 set[
i]->m_Address = address;
290 set[
i]->m_Permission = AccessPermission_Invalid;
291 DPRINTF(RubyCache,
"Allocate clearing lock for addr: %x\n",
293 set[
i]->m_locked = -1;
295 set[
i]->setPosition(cacheSet,
i);
306 panic(
"Allocate didn't find an available entry");
312 DPRINTF(RubyCache,
"address: %#x\n", address);
314 assert(entry !=
nullptr);
316 uint32_t cache_set = entry->
getSet();
317 uint32_t way = entry->
getWay();
319 m_cache[cache_set][way] = NULL;
337 getVictim(candidates)->getWay()]->m_Address;
347 if (loc == -1)
return NULL;
358 if (loc == -1)
return NULL;
367 if (entry !=
nullptr) {
376 assert(entry !=
nullptr);
385 if (entry !=
nullptr) {
405 if (
m_cache[set][loc] != NULL) {
406 ret =
m_cache[set][loc]->getNumValidBlocks();
416 uint64_t warmedUpBlocks = 0;
424 RubyRequestType request_type = RubyRequestType_NULL;
425 if (
perm == AccessPermission_Read_Only) {
427 request_type = RubyRequestType_IFETCH;
429 request_type = RubyRequestType_LD;
431 }
else if (
perm == AccessPermission_Read_Write) {
432 request_type = RubyRequestType_ST;
435 if (request_type != RubyRequestType_NULL) {
437 lastAccessTick =
m_cache[
i][
j]->getLastAccess();
439 0, request_type, lastAccessTick,
447 DPRINTF(RubyCacheTrace,
"%s: %lli blocks of %lli total blocks"
448 "recorded %.2f%% \n",
name().c_str(), warmedUpBlocks,
449 totalBlocks, (
float(warmedUpBlocks) /
float(totalBlocks)) * 100.0);
455 out <<
"Cache dump: " <<
name() << endl;
459 out <<
" Index: " <<
i
463 out <<
" Index: " <<
i
465 <<
" entry: NULL" << endl;
474 out <<
"printData() not supported" << endl;
480 DPRINTF(RubyCache,
"Setting Lock for addr: %#x to %d\n", address, context);
482 assert(entry !=
nullptr);
489 DPRINTF(RubyCache,
"Clear Lock for addr: %#x\n", address);
491 assert(entry !=
nullptr);
501 for (
auto j = set.begin();
j != set.end(); ++
j) {
503 if (line && line->
isLocked(context)) {
504 DPRINTF(RubyCache,
"Clear Lock for addr: %#x\n",
516 assert(entry !=
nullptr);
517 DPRINTF(RubyCache,
"Testing Lock for addr: %#llx cur %d con %d\n",
529 .
desc(
"Number of cache demand hits")
534 .
desc(
"Number of cache demand misses")
539 .
desc(
"Number of cache demand accesses")
545 .
name(
name() +
".total_sw_prefetches")
546 .
desc(
"Number of software prefetches")
551 .
name(
name() +
".total_hw_prefetches")
552 .
desc(
"Number of hardware prefetches")
558 .
desc(
"Number of prefetches")
565 .
init(RubyRequestType_NUM)
569 for (
int i = 0;
i < RubyAccessMode_NUM;
i++) {
571 .
subname(
i, RubyAccessMode_to_string(RubyAccessMode(
i)))
577 .
name(
name() +
".num_data_array_reads")
578 .
desc(
"number of data array reads")
583 .
name(
name() +
".num_data_array_writes")
584 .
desc(
"number of data array writes")
589 .
name(
name() +
".num_tag_array_reads")
590 .
desc(
"number of tag array reads")
595 .
name(
name() +
".num_tag_array_writes")
596 .
desc(
"number of tag array writes")
601 .
name(
name() +
".num_tag_array_stalls")
602 .
desc(
"number of stalls caused by tag array")
607 .
name(
name() +
".num_data_array_stalls")
608 .
desc(
"number of stalls caused by data array")
614 .
name(
name() +
".htm_transaction_committed_read_set")
615 .
desc(
"read set size of a committed transaction")
621 .
name(
name() +
".htm_transaction_committed_write_set")
622 .
desc(
"write set size of a committed transaction")
628 .
name(
name() +
".htm_transaction_aborted_read_set")
629 .
desc(
"read set size of a aborted transaction")
635 .
name(
name() +
".htm_transaction_aborted_write_set")
636 .
desc(
"write set size of a aborted transaction")
646 DPRINTF(RubyStats,
"Recorded statistic: %s\n",
647 CacheRequestType_to_string(requestType));
648 switch(requestType) {
649 case CacheRequestType_DataArrayRead:
654 case CacheRequestType_DataArrayWrite:
659 case CacheRequestType_TagArrayRead:
664 case CacheRequestType_TagArrayWrite:
670 warn(
"CacheMemory access_type not found: %s",
671 CacheRequestType_to_string(requestType));
682 if (res == CacheResourceType_TagArray) {
686 "Tag array stall on addr %#x in set %d\n",
691 }
else if (res == CacheResourceType_DataArray) {
695 "Data array stall on addr %#x in set %d\n",
701 panic(
"Unrecognized cache resource type.");
708 return (
m_cache[cache_set][loc]->m_Permission == AccessPermission_Invalid);
714 return (
m_cache[cache_set][loc]->m_Permission != AccessPermission_Busy);
722 uint64_t htmReadSetSize = 0;
723 uint64_t htmWriteSetSize = 0;
730 for (
auto j = set.begin();
j != set.end(); ++
j)
734 if (line !=
nullptr) {
749 DPRINTF(HtmMem,
"htmAbortTransaction: read set=%u write set=%u\n",
750 htmReadSetSize, htmWriteSetSize);
756 uint64_t htmReadSetSize = 0;
757 uint64_t htmWriteSetSize = 0;
764 for (
auto j = set.begin();
j != set.end(); ++
j)
767 if (line !=
nullptr) {
779 DPRINTF(HtmMem,
"htmCommitTransaction: read set=%u write set=%u\n",
780 htmReadSetSize, htmWriteSetSize);
void recordCacheContents(int cntrl, CacheRecorder *tr) const
A replaceable entry is a basic entry in a 2d table-like structure that needs to have replacement func...
virtual void regStats()
Callback to set stat parameters.
int findTagInSetIgnorePermissions(int64_t cacheSet, Addr tag) const
Stats::Formula m_prefetches
void setInHtmWriteSet(bool val)
Stats::Scalar m_hw_prefetches
void clearLocked(Addr addr)
AbstractCacheEntry * lookup(Addr address)
static uint32_t getBlockSizeBytes()
bool isLocked(Addr addr, int context)
Addr makeLineAddress(Addr addr)
void setLocked(int context)
AccessPermission m_Permission
std::vector< std::vector< AbstractCacheEntry * > > m_cache
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 m_demand_misses
Addr cacheProbe(Addr address) const
void regStats()
Callback to set stat parameters.
uint32_t getSet() const
Get set number.
uint64_t Tick
Tick count type.
BaseReplacementPolicy * m_replacementPolicy_ptr
We use BaseReplacementPolicy from Classic system here, hence we can use different replacement policie...
bool getInHtmWriteSet() const
Stats::Histogram htmTransCommitWriteSet
void setInHtmReadSet(bool val)
std::unordered_map< Addr, int > m_tag_index
bool getInHtmReadSet() const
std::enable_if< std::is_integral< T >::value, int >::type floorLog2(T x)
bool tryAccess(int64_t idx)
virtual std::shared_ptr< ReplacementData > instantiateEntry()=0
Instantiate a replacement data entry.
void addRecord(int cntrl, Addr data_addr, Addr pc_addr, RubyRequestType type, Tick time, DataBlock &data)
void print(std::ostream &out) const
void setMRU(Addr address)
void deallocate(Addr address)
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()
AbstractCacheEntry * allocate(Addr address, AbstractCacheEntry *new_entry)
void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
Stats::Scalar m_demand_hits
std::vector< std::vector< ReplData > > replacement_data
We store all the ReplacementData in a 2-dimensional array.
Stats::Scalar numTagArrayStalls
void printData(std::ostream &out) const
bool cacheAvail(Addr address) const
CacheMemory(const Params *p)
Addr bitSelect(Addr addr, unsigned int small, unsigned int big)
bool isBlockInvalid(int64_t cache_set, int64_t loc)
Stats::Scalar m_sw_prefetches
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
int findTagInSet(int64_t line, Addr tag) const
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
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)
const FlagsType nozero
Don't print if this is zero.
virtual const std::string name() const
void setLastAccess(Tick tick)
bool tryCacheAccess(Addr address, RubyRequestType type, DataBlock *&data_ptr)
void htmCommitTransaction()
void setLocked(Addr addr, int context)
Overload hash function for BasicBlockRange type.
Stats::Histogram htmTransAbortWriteSet
const FlagsType pdf
Print the percent of the total that this entry represents.
bool isTagPresent(Addr address) const
virtual void touch(const std::shared_ptr< ReplacementData > &replacement_data) const =0
Update replacement data.
Stats::Scalar numDataArrayWrites
Addr getAddressAtIdx(int idx) const
Stats::Scalar numDataArrayReads
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
std::shared_ptr< ReplacementData > replacementData
Replacement data associated to this entry.
bool m_is_instruction_only_cache
int64_t addressToCacheSet(Addr address) const
virtual void reset(const std::shared_ptr< ReplacementData > &replacement_data) const =0
Reset replacement data.
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.
Stats::Histogram htmTransCommitReadSet
Histogram & init(size_type size)
Set the parameters of this histogram.
ostream & operator<<(ostream &out, const CacheMemory &obj)
bool checkResourceAvailable(CacheResourceType res, Addr addr)
const FlagsType total
Print the total.
void reserve(int64_t idx)
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
void recordRequestType(CacheRequestType requestType, Addr addr)
void htmAbortTransaction()
int getReplacementWeight(int64_t set, int64_t loc)
Stats::Scalar numTagArrayWrites
Stats::Scalar numTagArrayReads
Stats::Formula m_demand_accesses
const FlagsType nonan
Don't print if this is NAN.
Stats::Scalar numDataArrayStalls
Stats::Histogram htmTransAbortReadSet
virtual DataBlock & getDataBlk()
#define panic(...)
This implements a cprintf based panic() function.
Stats::Vector m_accessModeType
Tick curTick()
The current simulated tick.
bool isBlockNotBusy(int64_t cache_set, int64_t loc)
uint32_t getWay() const
Get way number.
Abstract superclass for simulation objects.
Generated on Wed Sep 30 2020 14:02:13 for gem5 by doxygen 1.8.17