51 #include "debug/RubyCacheTrace.hh" 52 #include "debug/RubySystem.hh" 74 :
ClockedObject(p), m_access_backing_store(p->access_backing_store),
75 m_cache_recorder(NULL)
116 uint64_t cache_trace_size,
117 uint64_t block_size_bytes)
124 if (sequencer_ptr == NULL) {
125 sequencer_ptr = sequencer_map[cntrl];
129 assert(sequencer_ptr != NULL);
132 if (sequencer_map[cntrl] == NULL) {
133 sequencer_map[cntrl] = sequencer_ptr;
144 sequencer_map, block_size_bytes);
153 DPRINTF(RubyCacheTrace,
"Recording Cache Trace\n");
158 DPRINTF(RubyCacheTrace,
"Cache Trace Complete\n");
162 DPRINTF(RubyCacheTrace,
"Recording current tick %ld\n", curtick_original);
170 DPRINTF(RubyCacheTrace,
"Event %s auto-deletes when descheduled," 171 " not recording\n", curr_head->
name());
173 original_events.push_back(make_pair(curr_head, curr_head->
when()));
179 DPRINTF(RubyCacheTrace,
"Starting cache flush\n");
182 DPRINTF(RubyCacheTrace,
"Cache flush complete\n");
195 while (!original_events.empty()) {
198 original_events.pop_back();
212 warn_once(
"Ruby memory writeback is experimental. Continuing simulation " 213 "afterwards may not always work as intended.");
221 uint64_t uncompressed_trace_size)
226 int fd = creat(thefile.c_str(), 0664);
229 fatal(
"Can't open memory trace file '%s'\n", filename);
232 gzFile compressedMemory = gzdopen(fd,
"wb");
233 if (compressedMemory == NULL)
234 fatal(
"Insufficient memory to allocate compression state for %s\n",
237 if (gzwrite(compressedMemory, raw_data, uncompressed_trace_size) !=
238 uncompressed_trace_size) {
239 fatal(
"Write failed on memory trace file '%s'\n", filename);
242 if (gzclose(compressedMemory)) {
243 fatal(
"Close failed on memory trace file '%s'\n", filename);
261 fatal(
"Call memWriteback() before serialize() to create ruby trace");
265 uint8_t *raw_data =
new uint8_t[4096];
268 string cache_trace_file =
name() +
".cache.gz";
288 uint64_t &uncompressed_trace_size)
291 gzFile compressedTrace;
294 int fd = open(filename.c_str(), O_RDONLY);
297 fatal(
"Unable to open trace file %s", filename);
300 compressedTrace = gzdopen(fd,
"rb");
301 if (compressedTrace == NULL) {
302 fatal(
"Insufficient memory to allocate compression state for %s\n",
306 raw_data =
new uint8_t[uncompressed_trace_size];
307 if (gzread(compressedTrace, raw_data, uncompressed_trace_size) <
308 uncompressed_trace_size) {
309 fatal(
"Unable to read complete trace from file %s\n", filename);
312 if (gzclose(compressedTrace)) {
313 fatal(
"Failed to close cache trace file '%s'\n", filename);
320 uint8_t *uncompressed_trace = NULL;
328 string cache_trace_file;
329 uint64_t cache_trace_size = 0;
333 cache_trace_file = cp.
getCptDir() +
"/" + cache_trace_file;
365 DPRINTF(RubyCacheTrace,
"Starting ruby cache warmup\n");
410 network->resetStats();
420 AccessPermission access_perm = AccessPermission_NotPresent;
425 unsigned int num_ro = 0;
426 unsigned int num_rw = 0;
427 unsigned int num_busy = 0;
428 unsigned int num_maybe_stale = 0;
429 unsigned int num_backing_store = 0;
430 unsigned int num_invalid = 0;
438 for (
unsigned int i = 0;
i < num_controllers; ++
i) {
440 if (access_perm == AccessPermission_Read_Only){
444 else if (access_perm == AccessPermission_Read_Write){
448 else if (access_perm == AccessPermission_Busy)
450 else if (access_perm == AccessPermission_Maybe_Stale)
452 else if (access_perm == AccessPermission_Backing_Store) {
458 if (ctrl_backing_store ==
nullptr)
461 else if (access_perm == AccessPermission_Invalid ||
462 access_perm == AccessPermission_NotPresent)
474 if (num_invalid == (num_controllers - 1) && num_backing_store == 1) {
478 }
else if (num_ro > 0 || num_rw >= 1) {
483 warn(
"More than one Abstract Controller with RW permission for " 484 "addr: %#x on cacheline: %#x.", address, line_address);
492 num_maybe_stale, num_busy, num_ro, num_rw);
502 }
else if ((num_busy + num_maybe_stale) > 0) {
507 "(num_maybe_stale=%d, num_busy = %d)\n",
508 num_maybe_stale, num_busy);
509 for (
unsigned int i = 0;
i < num_controllers;++
i) {
514 "(num_maybe_stale=%d, num_busy = %d)\n",
515 num_maybe_stale, num_busy);
517 if (network->functionalRead(pkt))
534 AccessPermission access_perm = AccessPermission_NotPresent;
539 uint32_t M5_VAR_USED num_functional_writes = 0;
541 for (
unsigned int i = 0;
i < num_controllers;++
i) {
542 num_functional_writes +=
546 if (access_perm != AccessPermission_Invalid &&
547 access_perm != AccessPermission_NotPresent) {
548 num_functional_writes +=
555 num_functional_writes +=
559 num_functional_writes +=
565 num_functional_writes += network->functionalWrite(pkt);
573 RubySystemParams::create()
EventQueue * eventq
A pointer to this object's event queue.
void enqueueNextFetchRequest()
Function for fetching warming up the memory and the caches.
static void readCompressedTrace(std::string filename, uint8_t *&raw_data, uint64_t &uncompressed_trace_size)
static void writeCompressedTrace(uint8_t *raw_data, std::string file, uint64_t uncompressed_trace_size)
GlobalSimLoopExitEvent * simulate(Tick num_cycles)
Simulate for num_cycles additional cycles.
void serialize(CheckpointOut &cp) const override
Serialize an object.
bool isAutoDelete() const
#define fatal(...)
This implements a cprintf based fatal() function.
SimpleMemory * m_phys_mem
bool empty() const
Returns true if no events are queued.
static bool m_randomization
void makeCacheRecorder(uint8_t *uncompressed_trace, uint64_t cache_trace_size, uint64_t block_size_bytes)
CacheRecorder * m_cache_recorder
static uint32_t m_block_size_bytes
RubySystem(const Params *p)
uint64_t aggregateRecords(uint8_t **data, uint64_t size)
std::vector< std::unique_ptr< Network > > m_networks
bool functionalRead(Packet *ptr)
static bool m_warmup_enabled
void schedule(Event *event, Tick when, bool global=false)
Schedule the given event on this queue.
void deschedule(Event *event)
Deschedule the specified event.
Overload hash function for BasicBlockRange type.
virtual void functionalRead(const Addr &addr, PacketPtr)=0
bool functionalWrite(Packet *ptr)
void drainResume() override
Resume execution after a successful drain.
Declaration of Statistics objects.
void enqueueRubyEvent(Tick tick)
SimpleMemory declaration.
std::enable_if< std::is_integral< T >::value, int >::type floorLog2(T x)
static bool getWarmupEnabled()
#define UNSERIALIZE_SCALAR(scalar)
void resetClock() const
Reset the object's clock using the current global tick value.
Tick curTick()
The current simulated tick.
void enqueueNextFlushRequest()
Function for flushing the memory contents of the caches to the main memory.
virtual const std::string name() const
void registerNetwork(Network *)
MachineID getMachineID() const
uint64_t Tick
Tick count type.
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
#define UNSERIALIZE_OPT_SCALAR(scalar)
std::vector< std::map< uint32_t, AbstractController * > > m_abstract_controls
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
bool isPowerOf2(const T &n)
void startup() override
startup() is the final initialization call before simulation.
void setCurTick(Tick newVal)
void memWriteback() override
Write back dirty buffers to memory using functional writes.
static bool getCooldownEnabled()
static uint32_t m_memory_size_bits
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Addr makeLineAddress(Addr addr)
void resetStats() override
Callback to reset stats.
static uint32_t m_block_size_bits
std::vector< AbstractController * > m_abs_cntrl_vec
void registerDumpCallback(Callback *cb)
Register a callback that should be called whenever statistics are about to be dumped.
#define SERIALIZE_SCALAR(scalar)
static std::string dir()
Get the current checkout directory name.
Event * replaceHead(Event *s)
function for replacing the head of the event queue, so that a different set of events can run without...
virtual const std::string name() const
std::ostream CheckpointOut
const std::string getCptDir()
static bool m_cooldown_enabled
Tick when() const
Get the time that the event is scheduled.
static unsigned m_systems_to_warmup
static uint32_t getBlockSizeBytes()
void registerAbstractController(AbstractController *)
void unserialize(CheckpointIn &cp) override
Unserialize an object.