protocol "MOESI_CMP_directory";
include "RubySlicc_interfaces.slicc";
include "MOESI_CMP_directory-msg.sm";
-include "MOESI_CMP_directory-L2cache.sm";
include "MOESI_CMP_directory-L1cache.sm";
+include "MOESI_CMP_directory-L2cache.sm";
include "MOESI_CMP_directory-dma.sm";
include "MOESI_CMP_directory-dir.sm";
#include "mem/ruby/common/Global.hh"
+using namespace std;
+
RubySystem* g_system_ptr = 0;
+vector<map<uint32_t, AbstractController *> > g_abs_controls;
#ifndef __MEM_RUBY_COMMON_GLOBAL_HH__
#define __MEM_RUBY_COMMON_GLOBAL_HH__
+#include <map>
+#include <vector>
+
#include "base/str.hh"
class RubySystem;
extern RubySystem* g_system_ptr;
+class AbstractController;
+extern std::vector<std::map<uint32_t, AbstractController *> > g_abs_controls;
+
#endif // __MEM_RUBY_COMMON_GLOBAL_HH__
AbstractController *abs_cntrl = ext_link->params()->ext_node;
BasicRouter *router = ext_link->params()->int_node;
- // Store the controller and ExtLink pointers for later
- m_controller_vector.push_back(abs_cntrl);
+ // Store the ExtLink pointers for later
m_ext_link_vector.push_back(ext_link);
int ext_idx1 = abs_cntrl->params()->cntrl_id;
}
}
-void
-Topology::printStats(std::ostream& out) const
-{
- for (int cntrl = 0; cntrl < m_controller_vector.size(); cntrl++) {
- m_controller_vector[cntrl]->printStats(out);
- }
-}
-
-void
-Topology::clearStats()
-{
- for (int cntrl = 0; cntrl < m_controller_vector.size(); cntrl++) {
- m_controller_vector[cntrl]->clearStats();
- }
-}
-
// The following all-pairs shortest path algorithm is based on the
// discussion from Cormen et al., Chapter 26.1.
void
void initNetworkPtr(Network* net_ptr);
const std::string getName() { return m_name; }
- void printStats(std::ostream& out) const;
- void clearStats();
void print(std::ostream& out) const { out << "[Topology]"; }
protected:
NodeID m_nodes;
int m_number_of_switches;
- std::vector<AbstractController*> m_controller_vector;
std::vector<BasicExtLink*> m_ext_link_vector;
std::vector<BasicIntLink*> m_int_link_vector;
printPerformanceStats(out);
printLinkStats(out);
printPowerStats(out);
- m_topology_ptr->printStats(out);
}
void
for (int i = 0; i < m_switch_ptr_vector.size(); i++) {
m_switch_ptr_vector[i]->printStats(out);
}
- m_topology_ptr->printStats(out);
}
void
for (int i = 0; i < m_switch_ptr_vector.size(); i++) {
m_switch_ptr_vector[i]->clearStats();
}
- m_topology_ptr->clearStats();
}
void
out << "[Profiler]";
}
+void
+Profiler::printRequestProfile(ostream &out)
+{
+ out << "Request vs. RubySystem State Profile" << endl;
+ out << "--------------------------------" << endl;
+ out << endl;
+
+ map<string, uint64_t> m_requestProfileMap;
+ uint64_t m_requests = 0;
+
+ for (uint32_t i = 0; i < MachineType_NUM; i++) {
+ for (map<uint32_t, AbstractController*>::iterator it =
+ g_abs_controls[i].begin();
+ it != g_abs_controls[i].end(); ++it) {
+
+ AbstractController *ctr = (*it).second;
+ map<string, uint64_t> mp = ctr->getRequestProfileMap();
+
+ for (map<string, uint64_t>::iterator jt = mp.begin();
+ jt != mp.end(); ++jt) {
+
+ map<string, uint64_t>::iterator kt =
+ m_requestProfileMap.find((*jt).first);
+ if (kt != m_requestProfileMap.end()) {
+ (*kt).second += (*jt).second;
+ } else {
+ m_requestProfileMap[(*jt).first] = (*jt).second;
+ }
+ }
+
+ m_requests += ctr->getRequestCount();
+ }
+ }
+
+ map<string, uint64_t>::const_iterator i = m_requestProfileMap.begin();
+ map<string, uint64_t>::const_iterator end = m_requestProfileMap.end();
+ for (; i != end; ++i) {
+ const string &key = i->first;
+ uint64_t count = i->second;
+
+ double percent = (100.0 * double(count)) / double(m_requests);
+ vector<string> items;
+ tokenize(items, key, ':');
+ vector<string>::iterator j = items.begin();
+ vector<string>::iterator end = items.end();
+ for (; j != end; ++i)
+ out << setw(10) << *j;
+ out << setw(11) << count;
+ out << setw(14) << percent << endl;
+ }
+ out << endl;
+}
+
void
Profiler::printStats(ostream& out, bool short_stats)
{
if (!short_stats) {
out << "Busy Controller Counts:" << endl;
- for (int i = 0; i < MachineType_NUM; i++) {
- int size = MachineType_base_count((MachineType)i);
- for (int j = 0; j < size; j++) {
+ for (uint32_t i = 0; i < MachineType_NUM; i++) {
+ uint32_t size = MachineType_base_count((MachineType)i);
+
+ for (uint32_t j = 0; j < size; j++) {
MachineID machID;
machID.type = (MachineType)i;
machID.num = j;
- out << machID << ":" << m_busyControllerCount[i][j] << " ";
+
+ AbstractController *ctr =
+ (*(g_abs_controls[i].find(j))).second;
+ out << machID << ":" << ctr->getFullyBusyCycles() << " ";
if ((j + 1) % 8 == 0) {
out << endl;
}
}
if (!short_stats) {
- out << "Request vs. RubySystem State Profile" << endl;
- out << "--------------------------------" << endl;
- out << endl;
-
- map<string, int>::const_iterator i = m_requestProfileMap.begin();
- map<string, int>::const_iterator end = m_requestProfileMap.end();
- for (; i != end; ++i) {
- const string &key = i->first;
- int count = i->second;
-
- double percent = (100.0 * double(count)) / double(m_requests);
- vector<string> items;
- tokenize(items, key, ':');
- vector<string>::iterator j = items.begin();
- vector<string>::iterator end = items.end();
- for (; j != end; ++i)
- out << setw(10) << *j;
- out << setw(11) << count;
- out << setw(14) << percent << endl;
- }
- out << endl;
+ printRequestProfile(out);
out << "filter_action: " << m_filter_action_histogram << endl;
}
}
- m_busyControllerCount.resize(MachineType_NUM); // all machines
- for (int i = 0; i < MachineType_NUM; i++) {
- int size = MachineType_base_count((MachineType)i);
- m_busyControllerCount[i].resize(size);
- for (int j = 0; j < size; j++) {
- m_busyControllerCount[i][j] = 0;
- }
- }
m_busyBankCount = 0;
m_delayedCyclesHistogram.clear();
m_cache_to_cache = 0;
m_memory_to_cache = 0;
- // clear HashMaps
- m_requestProfileMap.clear();
-
- // count requests profiled
- m_requests = 0;
-
m_outstanding_requests.clear();
m_outstanding_persistent_requests.clear();
}
}
-// profiles original cache requests including PUTs
-void
-Profiler::profileRequest(const string& requestStr)
-{
- m_requests++;
-
- // if it doesn't exist, conveniently, it will be created with the
- // default value which is 0
- m_requestProfileMap[requestStr]++;
-}
-
-void
-Profiler::controllerBusy(MachineID machID)
-{
- m_busyControllerCount[(int)machID.type][(int)machID.num]++;
-}
-
void
Profiler::profilePFWait(Time waitTime)
{
bool getHotLines() { return m_hot_lines; }
bool getAllInstructions() { return m_all_instructions; }
+ private:
+ void printRequestProfile(std::ostream &out);
+
private:
// Private copy constructor and assignment operator
Profiler(const Profiler& obj);
Time m_ruby_start;
time_t m_real_time_start_time;
- std::vector<std::vector<int64_t> > m_busyControllerCount;
int64_t m_busyBankCount;
Histogram m_multicast_retry_histogram;
Histogram m_average_latency_estimate;
m5::hash_set<Address> m_watch_address_set;
- // counts all initiated cache request including PUTs
- int m_requests;
- std::map<std::string, int> m_requestProfileMap;
//added by SS
bool m_hot_lines;
#include "mem/ruby/system/System.hh"
AbstractController::AbstractController(const Params *p)
- : ClockedObject(p), Consumer(this)
+ : ClockedObject(p), Consumer(this), m_fully_busy_cycles(0),
+ m_request_count(0)
{
m_version = p->version;
m_transitions_per_cycle = p->transitions_per_cycle;
m_recycle_latency = p->recycle_latency;
m_number_of_TBEs = p->number_of_TBEs;
m_is_blocking = false;
- p->ruby_system->registerAbstractController(this);
+}
+
+void
+AbstractController::init()
+{
+ params()->ruby_system->registerAbstractController(this);
+}
+
+void
+AbstractController::clearStats()
+{
+ m_requestProfileMap.clear();
+ m_request_count = 0;
+}
+
+void
+AbstractController::profileRequest(const std::string &request)
+{
+ m_request_count++;
+
+ // if it doesn't exist, conveniently, it will be created with the
+ // default value which is 0
+ m_requestProfileMap[request]++;
}
public:
typedef RubyControllerParams Params;
AbstractController(const Params *p);
+ void init();
const Params *params() const { return (const Params *)_params; }
virtual MessageBuffer* getMandatoryQueue() const = 0;
virtual const int & getVersion() const = 0;
virtual void enqueuePrefetch(const Address&, const RubyRequestType&)
{ fatal("Prefetches not implemented!");}
+ public:
+ MachineID getMachineID() const { return m_machineID; }
+ uint64_t getFullyBusyCycles() const { return m_fully_busy_cycles; }
+ uint64_t getRequestCount() const { return m_request_count; }
+ const std::map<std::string, uint64_t>& getRequestProfileMap() const
+ { return m_requestProfileMap; }
+
+ protected:
+ //! Profiles original cache requests including PUTs
+ void profileRequest(const std::string &request);
+
protected:
int m_transitions_per_cycle;
int m_buffer_size;
int m_recycle_latency;
std::string m_name;
- std::map<std::string, std::string> m_cfg;
NodeID m_version;
Network* m_net_ptr;
MachineID m_machineID;
int m_max_in_port_rank;
int m_cur_in_port_rank;
int m_number_of_TBEs;
+
+ //! Counter for the number of cycles when the transitions carried out
+ //! were equal to the maximum allowed
+ uint64_t m_fully_busy_cycles;
+
+ //! Map for couting requests of different types. The controller should
+ //! call requisite function for updating the count.
+ std::map<std::string, uint64_t> m_requestProfileMap;
+ uint64_t m_request_count;
};
#endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__
using namespace std;
-void
-profile_request(const string& L1CacheState, const string& L2CacheState,
- const string& directoryState, const string& requestType)
-{
- string requestStr = L1CacheState + ":" + L2CacheState + ":" +
- directoryState + ":" + requestType;
-
- g_system_ptr->getProfiler()->profileRequest(requestStr);
-}
-
void
profile_outstanding_request(int outstanding)
{
void profile_outstanding_request(int outstanding);
void profile_sharing(const Address& addr, AccessType type, NodeID requestor,
const Set& sharers, const Set& owner);
-void profile_request(const std::string& L1CacheStateStr,
- const std::string& L2CacheStateStr,
- const std::string& directoryStateStr,
- const std::string& requestTypeStr);
void profile_miss(const RubyRequest& msg, NodeID id);
void profile_token_retry(const Address& addr, AccessType type, int count);
void profile_filter_action(int action);
struct MachineID
{
MachineType type;
- int num; // range: 0 ... number of this machine's components in system - 1
+ //! range: 0 ... number of this machine's components in system - 1
+ uint32_t num;
+
+ MachineType getType() const { return type; }
+ uint32_t getNum() const { return num; }
};
inline std::string
m_memory_size_bits = ceilLog2(m_memory_size_bytes);
}
- g_system_ptr = this;
if (p->no_mem_vec) {
m_mem_vec_ptr = NULL;
} else {
m_warmup_enabled = false;
m_cooldown_enabled = false;
+
+ // Setup the global variables used in Ruby
+ g_system_ptr = this;
+
+ // Resize to the size of different machine types
+ g_abs_controls.resize(MachineType_NUM);
}
void
RubySystem::registerAbstractController(AbstractController* cntrl)
{
m_abs_cntrl_vec.push_back(cntrl);
+
+ MachineID id = cntrl->getMachineID();
+ g_abs_controls[id.getType()][id.getNum()] = cntrl;
}
void
m_profiler_ptr->printStats(out);
m_network_ptr->printStats(out);
+
+ for (uint32_t i = 0;i < g_abs_controls.size(); ++i) {
+ for (map<uint32_t, AbstractController *>::iterator it =
+ g_abs_controls[i].begin();
+ it != g_abs_controls[i].end(); ++it) {
+
+ ((*it).second)->printStats(out);
+ }
+ }
}
void
{
m_profiler_ptr->clearStats();
m_network_ptr->clearStats();
+ for (uint32_t cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) {
+ m_abs_cntrl_vec[cntrl]->clearStats();
+ }
}
bool
code('m_profiler.possibleTransition($state, $event);')
code.dedent()
- code('}')
+ code('''
+ AbstractController::init();
+ clearStats();
+}
+''')
has_mandatory_q = False
for port in self.in_ports:
code('''
m_profiler.clearStats();
+ AbstractController::clearStats();
}
''')
assert(counter <= m_transitions_per_cycle);
if (counter == m_transitions_per_cycle) {
// Count how often we are fully utilized
- g_system_ptr->getProfiler()->controllerBusy(m_machineID);
+ m_fully_busy_cycles++;
// Wakeup in another cycle and try again
scheduleEvent(1);