ruby: network: convert to gem5 style stats
This commit is contained in:
parent
e9ae8b7d29
commit
90bfbd9793
28 changed files with 401 additions and 542 deletions
|
@ -331,6 +331,12 @@ class DataWrapVec : public DataWrap<Derived, InfoProxyType>
|
||||||
public:
|
public:
|
||||||
typedef InfoProxyType<Derived> Info;
|
typedef InfoProxyType<Derived> Info;
|
||||||
|
|
||||||
|
DataWrapVec()
|
||||||
|
{}
|
||||||
|
|
||||||
|
DataWrapVec(const DataWrapVec &ref)
|
||||||
|
{}
|
||||||
|
|
||||||
// The following functions are specific to vectors. If you use them
|
// The following functions are specific to vectors. If you use them
|
||||||
// in a non vector context, you will get a nice compiler error!
|
// in a non vector context, you will get a nice compiler error!
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,9 @@ Network::Network(const Params *p)
|
||||||
AbstractController *abs_cntrl = ext_link->params()->ext_node;
|
AbstractController *abs_cntrl = ext_link->params()->ext_node;
|
||||||
abs_cntrl->initNetworkPtr(this);
|
abs_cntrl->initNetworkPtr(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register a callback function for combining the statistics
|
||||||
|
Stats::registerDumpCallback(new StatsCallback(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -88,8 +88,7 @@ class Network : public ClockedObject
|
||||||
LinkDirection direction,
|
LinkDirection direction,
|
||||||
const NetDest& routing_table_entry) = 0;
|
const NetDest& routing_table_entry) = 0;
|
||||||
|
|
||||||
virtual void printStats(std::ostream& out) const = 0;
|
virtual void collateStats() = 0;
|
||||||
virtual void clearStats() = 0;
|
|
||||||
virtual void print(std::ostream& out) const = 0;
|
virtual void print(std::ostream& out) const = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -107,13 +106,30 @@ class Network : public ClockedObject
|
||||||
Network(const Network& obj);
|
Network(const Network& obj);
|
||||||
Network& operator=(const Network& obj);
|
Network& operator=(const Network& obj);
|
||||||
|
|
||||||
protected:
|
uint32_t m_nodes;
|
||||||
const std::string m_name;
|
|
||||||
int m_nodes;
|
|
||||||
static uint32_t m_virtual_networks;
|
static uint32_t m_virtual_networks;
|
||||||
Topology* m_topology_ptr;
|
Topology* m_topology_ptr;
|
||||||
static uint32_t m_control_msg_size;
|
static uint32_t m_control_msg_size;
|
||||||
static uint32_t m_data_msg_size;
|
static uint32_t m_data_msg_size;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Callback class used for collating statistics from all the
|
||||||
|
//! controller of this type.
|
||||||
|
class StatsCallback : public Callback
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Network *ctr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~StatsCallback() {}
|
||||||
|
|
||||||
|
StatsCallback(Network *_ctr)
|
||||||
|
: ctr(_ctr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void process() {ctr->collateStats();}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream&
|
inline std::ostream&
|
||||||
|
|
|
@ -71,17 +71,9 @@ BaseGarnetNetwork::BaseGarnetNetwork(const Params *p)
|
||||||
|
|
||||||
m_in_use.resize(m_virtual_networks);
|
m_in_use.resize(m_virtual_networks);
|
||||||
m_ordered.resize(m_virtual_networks);
|
m_ordered.resize(m_virtual_networks);
|
||||||
m_flits_received.resize(m_virtual_networks);
|
|
||||||
m_flits_injected.resize(m_virtual_networks);
|
|
||||||
m_network_latency.resize(m_virtual_networks);
|
|
||||||
m_queueing_latency.resize(m_virtual_networks);
|
|
||||||
for (int i = 0; i < m_virtual_networks; i++) {
|
for (int i = 0; i < m_virtual_networks; i++) {
|
||||||
m_in_use[i] = false;
|
m_in_use[i] = false;
|
||||||
m_ordered[i] = false;
|
m_ordered[i] = false;
|
||||||
m_flits_received[i] = 0;
|
|
||||||
m_flits_injected[i] = 0;
|
|
||||||
m_network_latency[i] = 0.0;
|
|
||||||
m_queueing_latency[i] = 0.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int node = 0; node < m_nodes; node++) {
|
for (int node = 0; node < m_nodes; node++) {
|
||||||
|
@ -121,60 +113,55 @@ BaseGarnetNetwork::getFromNetQueue(NodeID id, bool ordered, int network_num,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BaseGarnetNetwork::clearStats()
|
BaseGarnetNetwork::regStats()
|
||||||
{
|
{
|
||||||
}
|
m_flits_received
|
||||||
|
.init(m_virtual_networks)
|
||||||
|
.name(name() + ".flits_received")
|
||||||
|
.flags(Stats::pdf | Stats::total | Stats::nozero | Stats::oneline)
|
||||||
|
;
|
||||||
|
|
||||||
void
|
m_flits_injected
|
||||||
BaseGarnetNetwork::printStats(ostream& out) const
|
.init(m_virtual_networks)
|
||||||
{
|
.name(name() + ".flits_injected")
|
||||||
out << endl;
|
.flags(Stats::pdf | Stats::total | Stats::nozero | Stats::oneline)
|
||||||
out << "Network Stats" << endl;
|
;
|
||||||
out << "-------------" << endl;
|
|
||||||
out << endl;
|
|
||||||
printPerformanceStats(out);
|
|
||||||
printLinkStats(out);
|
|
||||||
printPowerStats(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
m_network_latency
|
||||||
BaseGarnetNetwork::printPerformanceStats(ostream& out) const
|
.init(m_virtual_networks)
|
||||||
{
|
.name(name() + ".network_latency")
|
||||||
int total_flits_injected = 0;
|
.flags(Stats::oneline)
|
||||||
int total_flits_received = 0;
|
;
|
||||||
int total_network_latency = 0.0;
|
|
||||||
int total_queueing_latency = 0.0;
|
m_queueing_latency
|
||||||
|
.init(m_virtual_networks)
|
||||||
|
.name(name() + ".queueing_latency")
|
||||||
|
.flags(Stats::oneline)
|
||||||
|
;
|
||||||
|
|
||||||
for (int i = 0; i < m_virtual_networks; i++) {
|
for (int i = 0; i < m_virtual_networks; i++) {
|
||||||
if (!m_in_use[i])
|
m_flits_received.subname(i, csprintf("vnet-%i", i));
|
||||||
continue;
|
m_flits_injected.subname(i, csprintf("vnet-%i", i));
|
||||||
|
m_network_latency.subname(i, csprintf("vnet-%i", i));
|
||||||
out << "[Vnet " << i << "]: flits injected = "
|
m_queueing_latency.subname(i, csprintf("vnet-%i", i));
|
||||||
<< m_flits_injected[i] << endl;
|
|
||||||
out << "[Vnet " << i << "]: flits received = "
|
|
||||||
<< m_flits_received[i] << endl;
|
|
||||||
out << "[Vnet " << i << "]: average network latency = "
|
|
||||||
<< ((double) m_network_latency[i] / (double) m_flits_received[i])
|
|
||||||
<< endl;
|
|
||||||
out << "[Vnet " << i << "]: average queueing (at source NI) latency = "
|
|
||||||
<< ((double) m_queueing_latency[i] / (double) m_flits_received[i])
|
|
||||||
<< endl;
|
|
||||||
|
|
||||||
out << endl;
|
|
||||||
total_flits_injected += m_flits_injected[i];
|
|
||||||
total_flits_received += m_flits_received[i];
|
|
||||||
total_network_latency += m_network_latency[i];
|
|
||||||
total_queueing_latency += m_queueing_latency[i];
|
|
||||||
}
|
}
|
||||||
out << "Total flits injected = " << total_flits_injected << endl;
|
|
||||||
out << "Total flits received = " << total_flits_received << endl;
|
m_avg_vnet_latency
|
||||||
out << "Average network latency = "
|
.name(name() + ".average_vnet_latency")
|
||||||
<< ((double) total_network_latency/ (double) total_flits_received) << endl;
|
.flags(Stats::oneline);
|
||||||
out << "Average queueing (at source NI) latency = "
|
m_avg_vnet_latency = m_network_latency / m_flits_received;
|
||||||
<< ((double) total_queueing_latency/ (double) total_flits_received) << endl;
|
|
||||||
out << "Average latency = "
|
m_avg_vqueue_latency
|
||||||
<< ((double) (total_queueing_latency + total_network_latency) /
|
.name(name() + ".average_vqueue_latency")
|
||||||
(double) total_flits_received)<< endl;
|
.flags(Stats::oneline);
|
||||||
out << "-------------" << endl;
|
m_avg_vqueue_latency = m_queueing_latency / m_flits_received;
|
||||||
out << endl;
|
|
||||||
|
m_avg_network_latency.name(name() + ".average_network_latency");
|
||||||
|
m_avg_network_latency = sum(m_network_latency) / sum(m_flits_received);
|
||||||
|
|
||||||
|
m_avg_queueing_latency.name(name() + ".average_queueing_latency");
|
||||||
|
m_avg_queueing_latency = sum(m_queueing_latency) / sum(m_flits_received);
|
||||||
|
|
||||||
|
m_avg_latency.name(name() + ".average_latency");
|
||||||
|
m_avg_latency = m_avg_network_latency + m_avg_queueing_latency;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,27 +80,31 @@ class BaseGarnetNetwork : public Network
|
||||||
virtual void checkNetworkAllocation(NodeID id, bool ordered,
|
virtual void checkNetworkAllocation(NodeID id, bool ordered,
|
||||||
int network_num, std::string vnet_type) = 0;
|
int network_num, std::string vnet_type) = 0;
|
||||||
|
|
||||||
void clearStats();
|
virtual void regStats();
|
||||||
void printStats(std::ostream& out) const;
|
virtual void collateStats() {}
|
||||||
void printPerformanceStats(std::ostream& out) const;
|
|
||||||
virtual void printLinkStats(std::ostream& out) const = 0;
|
|
||||||
virtual void printPowerStats(std::ostream& out) const = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int m_ni_flit_size;
|
int m_ni_flit_size;
|
||||||
int m_vcs_per_vnet;
|
int m_vcs_per_vnet;
|
||||||
bool m_enable_fault_model;
|
bool m_enable_fault_model;
|
||||||
|
|
||||||
std::vector<int> m_flits_received;
|
|
||||||
std::vector<int> m_flits_injected;
|
|
||||||
std::vector<double> m_network_latency;
|
|
||||||
std::vector<double> m_queueing_latency;
|
|
||||||
|
|
||||||
std::vector<bool> m_in_use;
|
std::vector<bool> m_in_use;
|
||||||
std::vector<bool> m_ordered;
|
std::vector<bool> m_ordered;
|
||||||
|
|
||||||
std::vector<std::vector<MessageBuffer*> > m_toNetQueues;
|
std::vector<std::vector<MessageBuffer*> > m_toNetQueues;
|
||||||
std::vector<std::vector<MessageBuffer*> > m_fromNetQueues;
|
std::vector<std::vector<MessageBuffer*> > m_fromNetQueues;
|
||||||
|
|
||||||
|
// Statistical variables
|
||||||
|
Stats::Vector m_flits_received;
|
||||||
|
Stats::Vector m_flits_injected;
|
||||||
|
Stats::Vector m_network_latency;
|
||||||
|
Stats::Vector m_queueing_latency;
|
||||||
|
|
||||||
|
Stats::Formula m_avg_vnet_latency;
|
||||||
|
Stats::Formula m_avg_vqueue_latency;
|
||||||
|
Stats::Formula m_avg_network_latency;
|
||||||
|
Stats::Formula m_avg_queueing_latency;
|
||||||
|
Stats::Formula m_avg_latency;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __MEM_RUBY_NETWORK_GARNET_BASEGARNETNETWORK_HH__
|
#endif // __MEM_RUBY_NETWORK_GARNET_BASEGARNETNETWORK_HH__
|
||||||
|
|
|
@ -221,81 +221,82 @@ GarnetNetwork_d::checkNetworkAllocation(NodeID id, bool ordered,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GarnetNetwork_d::printLinkStats(ostream& out) const
|
GarnetNetwork_d::regStats()
|
||||||
{
|
{
|
||||||
double average_link_utilization = 0;
|
BaseGarnetNetwork::regStats();
|
||||||
vector<double> average_vc_load;
|
regLinkStats();
|
||||||
average_vc_load.resize(m_virtual_networks*m_vcs_per_vnet);
|
regPowerStats();
|
||||||
|
|
||||||
for (int i = 0; i < m_virtual_networks*m_vcs_per_vnet; i++) {
|
|
||||||
average_vc_load[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
out << endl;
|
|
||||||
for (int i = 0; i < m_links.size(); i++) {
|
|
||||||
average_link_utilization +=
|
|
||||||
(double(m_links[i]->getLinkUtilization())) /
|
|
||||||
(double(curCycle() - g_ruby_start));
|
|
||||||
|
|
||||||
vector<int> vc_load = m_links[i]->getVcLoad();
|
|
||||||
for (int j = 0; j < vc_load.size(); j++) {
|
|
||||||
assert(vc_load.size() == m_vcs_per_vnet*m_virtual_networks);
|
|
||||||
average_vc_load[j] += vc_load[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
average_link_utilization =
|
|
||||||
average_link_utilization/m_links.size();
|
|
||||||
out << "Average Link Utilization :: " << average_link_utilization
|
|
||||||
<< " flits/cycle" << endl;
|
|
||||||
out << "-------------" << endl;
|
|
||||||
|
|
||||||
for (int i = 0; i < m_vcs_per_vnet*m_virtual_networks; i++) {
|
|
||||||
if (!m_in_use[i/m_vcs_per_vnet])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
average_vc_load[i] = (double(average_vc_load[i])) /
|
|
||||||
(double(curCycle() - g_ruby_start));
|
|
||||||
out << "Average VC Load [" << i << "] = " << average_vc_load[i]
|
|
||||||
<< " flits/cycle " << endl;
|
|
||||||
}
|
|
||||||
out << "-------------" << endl;
|
|
||||||
out << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GarnetNetwork_d::printPowerStats(ostream& out) const
|
GarnetNetwork_d::regLinkStats()
|
||||||
{
|
{
|
||||||
out << "Network Power" << endl;
|
m_average_link_utilization.name(name() + ".avg_link_utilization");
|
||||||
out << "-------------" << endl;
|
|
||||||
double m_total_link_power = 0.0;
|
|
||||||
double m_dynamic_link_power = 0.0;
|
|
||||||
double m_static_link_power = 0.0;
|
|
||||||
double m_total_router_power = 0.0;
|
|
||||||
double m_dynamic_router_power = 0.0;
|
|
||||||
double m_static_router_power = 0.0;
|
|
||||||
double m_clk_power = 0.0;
|
|
||||||
|
|
||||||
|
m_average_vc_load
|
||||||
|
.init(m_virtual_networks * m_vcs_per_vnet)
|
||||||
|
.name(name() + ".avg_vc_load")
|
||||||
|
.flags(Stats::pdf | Stats::total | Stats::nozero | Stats::oneline)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GarnetNetwork_d::regPowerStats()
|
||||||
|
{
|
||||||
|
m_dynamic_link_power.name(name() + ".link_dynamic_power");
|
||||||
|
m_static_link_power.name(name() + ".link_static_power");
|
||||||
|
|
||||||
|
m_total_link_power.name(name() + ".link_total_power");
|
||||||
|
m_total_link_power = m_dynamic_link_power + m_static_link_power;
|
||||||
|
|
||||||
|
m_dynamic_router_power.name(name() + ".router_dynamic_power");
|
||||||
|
m_static_router_power.name(name() + ".router_static_power");
|
||||||
|
m_clk_power.name(name() + ".clk_power");
|
||||||
|
|
||||||
|
m_total_router_power.name(name() + ".router_total_power");
|
||||||
|
m_total_router_power = m_dynamic_router_power +
|
||||||
|
m_static_router_power +
|
||||||
|
m_clk_power;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GarnetNetwork_d::collateStats()
|
||||||
|
{
|
||||||
|
collateLinkStats();
|
||||||
|
collatePowerStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GarnetNetwork_d::collateLinkStats()
|
||||||
|
{
|
||||||
for (int i = 0; i < m_links.size(); i++) {
|
for (int i = 0; i < m_links.size(); i++) {
|
||||||
m_total_link_power += m_links[i]->calculate_power();
|
m_average_link_utilization +=
|
||||||
|
(double(m_links[i]->getLinkUtilization())) /
|
||||||
|
(double(curCycle() - g_ruby_start));
|
||||||
|
|
||||||
|
vector<unsigned int> vc_load = m_links[i]->getVcLoad();
|
||||||
|
for (int j = 0; j < vc_load.size(); j++) {
|
||||||
|
m_average_vc_load[j] +=
|
||||||
|
((double)vc_load[j] / (double)(curCycle() - g_ruby_start));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GarnetNetwork_d::collatePowerStats()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_links.size(); i++) {
|
||||||
|
m_links[i]->calculate_power();
|
||||||
m_dynamic_link_power += m_links[i]->get_dynamic_power();
|
m_dynamic_link_power += m_links[i]->get_dynamic_power();
|
||||||
m_static_link_power += m_links[i]->get_static_power();
|
m_static_link_power += m_links[i]->get_static_power();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < m_routers.size(); i++) {
|
for (int i = 0; i < m_routers.size(); i++) {
|
||||||
m_total_router_power += m_routers[i]->calculate_power();
|
m_routers[i]->calculate_power();
|
||||||
m_dynamic_router_power += m_routers[i]->get_dynamic_power();
|
m_dynamic_router_power += m_routers[i]->get_dynamic_power();
|
||||||
m_static_router_power += m_routers[i]->get_static_power();
|
m_static_router_power += m_routers[i]->get_static_power();
|
||||||
m_clk_power += m_routers[i]->get_clk_power();
|
m_clk_power += m_routers[i]->get_clk_power();
|
||||||
}
|
}
|
||||||
out << "Link Dynamic Power = " << m_dynamic_link_power << " W" << endl;
|
|
||||||
out << "Link Static Power = " << m_static_link_power << " W" << endl;
|
|
||||||
out << "Total Link Power = " << m_total_link_power << " W " << endl;
|
|
||||||
out << "Router Dynamic Power = " << m_dynamic_router_power << " W" << endl;
|
|
||||||
out << "Router Clock Power = " << m_clk_power << " W" << endl;
|
|
||||||
out << "Router Static Power = " << m_static_router_power << " W" << endl;
|
|
||||||
out << "Total Router Power = " << m_total_router_power << " W " <<endl;
|
|
||||||
out << "-------------" << endl;
|
|
||||||
out << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -63,8 +63,8 @@ class GarnetNetwork_d : public BaseGarnetNetwork
|
||||||
int getBuffersPerDataVC() {return m_buffers_per_data_vc; }
|
int getBuffersPerDataVC() {return m_buffers_per_data_vc; }
|
||||||
int getBuffersPerCtrlVC() {return m_buffers_per_ctrl_vc; }
|
int getBuffersPerCtrlVC() {return m_buffers_per_ctrl_vc; }
|
||||||
|
|
||||||
void printLinkStats(std::ostream& out) const;
|
void collateStats();
|
||||||
void printPowerStats(std::ostream& out) const;
|
void regStats();
|
||||||
void print(std::ostream& out) const;
|
void print(std::ostream& out) const;
|
||||||
|
|
||||||
VNET_type
|
VNET_type
|
||||||
|
@ -96,6 +96,11 @@ class GarnetNetwork_d : public BaseGarnetNetwork
|
||||||
GarnetNetwork_d(const GarnetNetwork_d& obj);
|
GarnetNetwork_d(const GarnetNetwork_d& obj);
|
||||||
GarnetNetwork_d& operator=(const GarnetNetwork_d& obj);
|
GarnetNetwork_d& operator=(const GarnetNetwork_d& obj);
|
||||||
|
|
||||||
|
void collateLinkStats();
|
||||||
|
void collatePowerStats();
|
||||||
|
void regLinkStats();
|
||||||
|
void regPowerStats();
|
||||||
|
|
||||||
std::vector<VNET_type > m_vnet_type;
|
std::vector<VNET_type > m_vnet_type;
|
||||||
|
|
||||||
std::vector<Router_d *> m_routers; // All Routers in Network
|
std::vector<Router_d *> m_routers; // All Routers in Network
|
||||||
|
@ -105,6 +110,20 @@ class GarnetNetwork_d : public BaseGarnetNetwork
|
||||||
|
|
||||||
int m_buffers_per_data_vc;
|
int m_buffers_per_data_vc;
|
||||||
int m_buffers_per_ctrl_vc;
|
int m_buffers_per_ctrl_vc;
|
||||||
|
|
||||||
|
// Statistical variables for power
|
||||||
|
Stats::Scalar m_dynamic_link_power;
|
||||||
|
Stats::Scalar m_static_link_power;
|
||||||
|
Stats::Formula m_total_link_power;
|
||||||
|
|
||||||
|
Stats::Scalar m_dynamic_router_power;
|
||||||
|
Stats::Scalar m_static_router_power;
|
||||||
|
Stats::Scalar m_clk_power;
|
||||||
|
Stats::Formula m_total_router_power;
|
||||||
|
|
||||||
|
// Statistical variables for performance
|
||||||
|
Stats::Scalar m_average_link_utilization;
|
||||||
|
Stats::Vector m_average_vc_load;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream&
|
inline std::ostream&
|
||||||
|
|
|
@ -161,17 +161,10 @@ class InputUnit_d : public Consumer
|
||||||
m_credit_link = credit_link;
|
m_credit_link = credit_link;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double
|
double get_buf_read_count(unsigned int vnet) const
|
||||||
get_buf_read_count(int vnet)
|
{ return m_num_buffer_reads[vnet]; }
|
||||||
{
|
double get_buf_write_count(unsigned int vnet) const
|
||||||
return m_num_buffer_reads[vnet];
|
{ return m_num_buffer_writes[vnet]; }
|
||||||
}
|
|
||||||
|
|
||||||
inline double
|
|
||||||
get_buf_write_count(int vnet)
|
|
||||||
{
|
|
||||||
return m_num_buffer_writes[vnet];
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t functionalWrite(Packet *pkt);
|
uint32_t functionalWrite(Packet *pkt);
|
||||||
|
|
||||||
|
@ -179,8 +172,6 @@ class InputUnit_d : public Consumer
|
||||||
int m_id;
|
int m_id;
|
||||||
int m_num_vcs;
|
int m_num_vcs;
|
||||||
int m_vc_per_vnet;
|
int m_vc_per_vnet;
|
||||||
std::vector<double> m_num_buffer_writes;
|
|
||||||
std::vector<double> m_num_buffer_reads;
|
|
||||||
|
|
||||||
Router_d *m_router;
|
Router_d *m_router;
|
||||||
NetworkLink_d *m_in_link;
|
NetworkLink_d *m_in_link;
|
||||||
|
@ -189,6 +180,10 @@ class InputUnit_d : public Consumer
|
||||||
|
|
||||||
// Virtual channels
|
// Virtual channels
|
||||||
std::vector<VirtualChannel_d *> m_vcs;
|
std::vector<VirtualChannel_d *> m_vcs;
|
||||||
|
|
||||||
|
// Statistical variables
|
||||||
|
std::vector<double> m_num_buffer_writes;
|
||||||
|
std::vector<double> m_num_buffer_reads;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_INPUT_UNIT_D_HH__
|
#endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_INPUT_UNIT_D_HH__
|
||||||
|
|
|
@ -76,18 +76,6 @@ NetworkLink_d::wakeup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int>
|
|
||||||
NetworkLink_d::getVcLoad()
|
|
||||||
{
|
|
||||||
return m_vc_load;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
NetworkLink_d::getLinkUtilization()
|
|
||||||
{
|
|
||||||
return m_link_utilized;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworkLink_d *
|
NetworkLink_d *
|
||||||
NetworkLink_dParams::create()
|
NetworkLink_dParams::create()
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,14 +53,15 @@ class NetworkLink_d : public ClockedObject, public Consumer
|
||||||
void setLinkConsumer(Consumer *consumer);
|
void setLinkConsumer(Consumer *consumer);
|
||||||
void setSourceQueue(flitBuffer_d *srcQueue);
|
void setSourceQueue(flitBuffer_d *srcQueue);
|
||||||
void print(std::ostream& out) const{}
|
void print(std::ostream& out) const{}
|
||||||
int getLinkUtilization();
|
|
||||||
std::vector<int> getVcLoad();
|
|
||||||
int get_id(){return m_id;}
|
int get_id(){return m_id;}
|
||||||
double get_dynamic_power(){return m_power_dyn;}
|
|
||||||
double get_static_power(){return m_power_sta;}
|
|
||||||
void wakeup();
|
void wakeup();
|
||||||
|
|
||||||
double calculate_power();
|
void calculate_power();
|
||||||
|
double get_dynamic_power() const { return m_power_dyn; }
|
||||||
|
double get_static_power()const { return m_power_sta; }
|
||||||
|
|
||||||
|
unsigned int getLinkUtilization() const { return m_link_utilized; }
|
||||||
|
const std::vector<unsigned int> & getVcLoad() const { return m_vc_load; }
|
||||||
|
|
||||||
inline bool isReady(Cycles curTime)
|
inline bool isReady(Cycles curTime)
|
||||||
{ return linkBuffer->isReady(curTime); }
|
{ return linkBuffer->isReady(curTime); }
|
||||||
|
@ -71,7 +72,7 @@ class NetworkLink_d : public ClockedObject, public Consumer
|
||||||
void init_net_ptr(GarnetNetwork_d* net_ptr) { m_net_ptr = net_ptr; }
|
void init_net_ptr(GarnetNetwork_d* net_ptr) { m_net_ptr = net_ptr; }
|
||||||
uint32_t functionalWrite(Packet *);
|
uint32_t functionalWrite(Packet *);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
int m_id;
|
int m_id;
|
||||||
Cycles m_latency;
|
Cycles m_latency;
|
||||||
int channel_width;
|
int channel_width;
|
||||||
|
@ -80,10 +81,12 @@ class NetworkLink_d : public ClockedObject, public Consumer
|
||||||
flitBuffer_d *linkBuffer;
|
flitBuffer_d *linkBuffer;
|
||||||
Consumer *link_consumer;
|
Consumer *link_consumer;
|
||||||
flitBuffer_d *link_srcQueue;
|
flitBuffer_d *link_srcQueue;
|
||||||
int m_link_utilized;
|
|
||||||
std::vector<int> m_vc_load;
|
|
||||||
int m_flit_width;
|
int m_flit_width;
|
||||||
|
|
||||||
|
// Statistical variables
|
||||||
|
unsigned int m_link_utilized;
|
||||||
|
std::vector<unsigned int> m_vc_load;
|
||||||
|
|
||||||
double m_power_dyn;
|
double m_power_dyn;
|
||||||
double m_power_sta;
|
double m_power_sta;
|
||||||
};
|
};
|
||||||
|
|
|
@ -186,7 +186,7 @@ Router_d::printFaultVector(ostream& out)
|
||||||
for (int fault_type_index = 0; fault_type_index < num_fault_types;
|
for (int fault_type_index = 0; fault_type_index < num_fault_types;
|
||||||
fault_type_index++){
|
fault_type_index++){
|
||||||
out << " - probability of (";
|
out << " - probability of (";
|
||||||
out <<
|
out <<
|
||||||
m_network_ptr->fault_model->fault_type_to_string(fault_type_index);
|
m_network_ptr->fault_model->fault_type_to_string(fault_type_index);
|
||||||
out << ") = ";
|
out << ") = ";
|
||||||
out << fault_vector[fault_type_index] << endl;
|
out << fault_vector[fault_type_index] << endl;
|
||||||
|
@ -198,7 +198,7 @@ Router_d::printAggregateFaultProbability(std::ostream& out)
|
||||||
{
|
{
|
||||||
int temperature_celcius = BASELINE_TEMPERATURE_CELCIUS;
|
int temperature_celcius = BASELINE_TEMPERATURE_CELCIUS;
|
||||||
float aggregate_fault_prob;
|
float aggregate_fault_prob;
|
||||||
get_aggregate_fault_probability(temperature_celcius,
|
get_aggregate_fault_probability(temperature_celcius,
|
||||||
&aggregate_fault_prob);
|
&aggregate_fault_prob);
|
||||||
out << "Router-" << m_id << " fault probability: ";
|
out << "Router-" << m_id << " fault probability: ";
|
||||||
out << aggregate_fault_prob << endl;
|
out << aggregate_fault_prob << endl;
|
||||||
|
|
|
@ -89,12 +89,12 @@ class Router_d : public BasicRouter
|
||||||
void printFaultVector(std::ostream& out);
|
void printFaultVector(std::ostream& out);
|
||||||
void printAggregateFaultProbability(std::ostream& out);
|
void printAggregateFaultProbability(std::ostream& out);
|
||||||
|
|
||||||
double calculate_power();
|
void calculate_power();
|
||||||
void calculate_performance_numbers();
|
void calculate_performance_numbers();
|
||||||
|
double get_dynamic_power() const { return m_power_dyn; }
|
||||||
|
double get_static_power() const { return m_power_sta; }
|
||||||
|
double get_clk_power() const { return m_clk_power; }
|
||||||
|
|
||||||
double get_dynamic_power(){return m_power_dyn;}
|
|
||||||
double get_static_power(){return m_power_sta;}
|
|
||||||
double get_clk_power(){return m_clk_power;}
|
|
||||||
bool get_fault_vector(int temperature, float fault_vector[]){
|
bool get_fault_vector(int temperature, float fault_vector[]){
|
||||||
return m_network_ptr->fault_model->fault_vector(m_id, temperature,
|
return m_network_ptr->fault_model->fault_vector(m_id, temperature,
|
||||||
fault_vector);
|
fault_vector);
|
||||||
|
@ -110,11 +110,6 @@ class Router_d : public BasicRouter
|
||||||
private:
|
private:
|
||||||
int m_virtual_networks, m_num_vcs, m_vc_per_vnet;
|
int m_virtual_networks, m_num_vcs, m_vc_per_vnet;
|
||||||
GarnetNetwork_d *m_network_ptr;
|
GarnetNetwork_d *m_network_ptr;
|
||||||
|
|
||||||
std::vector<double> buf_read_count;
|
|
||||||
std::vector<double> buf_write_count;
|
|
||||||
std::vector<double> vc_local_arbit_count;
|
|
||||||
std::vector<double> vc_global_arbit_count;
|
|
||||||
double sw_local_arbit_count, sw_global_arbit_count;
|
double sw_local_arbit_count, sw_global_arbit_count;
|
||||||
double crossbar_count;
|
double crossbar_count;
|
||||||
|
|
||||||
|
@ -125,9 +120,16 @@ class Router_d : public BasicRouter
|
||||||
SWallocator_d *m_sw_alloc;
|
SWallocator_d *m_sw_alloc;
|
||||||
Switch_d *m_switch;
|
Switch_d *m_switch;
|
||||||
|
|
||||||
|
// Statistical variables for power
|
||||||
double m_power_dyn;
|
double m_power_dyn;
|
||||||
double m_power_sta;
|
double m_power_sta;
|
||||||
double m_clk_power;
|
double m_clk_power;
|
||||||
|
|
||||||
|
// Statistical variables for performance
|
||||||
|
std::vector<double> buf_read_count;
|
||||||
|
std::vector<double> buf_write_count;
|
||||||
|
std::vector<double> vc_local_arbit_count;
|
||||||
|
std::vector<double> vc_global_arbit_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_ROUTER_D_HH__
|
#endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_ROUTER_D_HH__
|
||||||
|
|
|
@ -57,26 +57,17 @@ class VCallocator_d : public Consumer
|
||||||
bool is_invc_candidate(int inport_iter, int invc_iter);
|
bool is_invc_candidate(int inport_iter, int invc_iter);
|
||||||
void select_outvc(int inport_iter, int invc_iter);
|
void select_outvc(int inport_iter, int invc_iter);
|
||||||
|
|
||||||
inline double
|
double get_local_arbit_count(unsigned int vnet) const
|
||||||
get_local_arbit_count(int vnet)
|
{ return m_local_arbiter_activity[vnet]; }
|
||||||
{
|
|
||||||
return m_local_arbiter_activity[vnet];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double
|
double get_global_arbit_count(unsigned int vnet) const
|
||||||
get_global_arbit_count(int vnet)
|
{ return m_global_arbiter_activity[vnet]; }
|
||||||
{
|
|
||||||
return m_global_arbiter_activity[vnet];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_num_vcs, m_vc_per_vnet;
|
int m_num_vcs, m_vc_per_vnet;
|
||||||
int m_num_inports;
|
int m_num_inports;
|
||||||
int m_num_outports;
|
int m_num_outports;
|
||||||
|
|
||||||
std::vector<double > m_local_arbiter_activity;
|
|
||||||
std::vector<double > m_global_arbiter_activity;
|
|
||||||
|
|
||||||
Router_d *m_router;
|
Router_d *m_router;
|
||||||
|
|
||||||
// First stage of arbitration
|
// First stage of arbitration
|
||||||
|
@ -94,6 +85,10 @@ class VCallocator_d : public Consumer
|
||||||
|
|
||||||
std::vector<InputUnit_d *> m_input_unit;
|
std::vector<InputUnit_d *> m_input_unit;
|
||||||
std::vector<OutputUnit_d *> m_output_unit;
|
std::vector<OutputUnit_d *> m_output_unit;
|
||||||
|
|
||||||
|
// Statistical variables
|
||||||
|
std::vector<double> m_local_arbiter_activity;
|
||||||
|
std::vector<double> m_global_arbiter_activity;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_VC_ALLOCATOR_D_HH__
|
#endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_VC_ALLOCATOR_D_HH__
|
||||||
|
|
|
@ -210,54 +210,38 @@ GarnetNetwork::functionalWrite(Packet *pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GarnetNetwork::printLinkStats(ostream& out) const
|
GarnetNetwork::regStats()
|
||||||
{
|
{
|
||||||
double average_link_utilization = 0;
|
BaseGarnetNetwork::regStats();
|
||||||
vector<double> average_vc_load;
|
|
||||||
average_vc_load.resize(m_virtual_networks*m_vcs_per_vnet);
|
|
||||||
|
|
||||||
for (int i = 0; i < m_virtual_networks*m_vcs_per_vnet; i++) {
|
m_average_link_utilization.name(name() + ".avg_link_utilization");
|
||||||
average_vc_load[i] = 0;
|
|
||||||
|
m_average_vc_load
|
||||||
|
.init(m_virtual_networks * m_vcs_per_vnet)
|
||||||
|
.name(name() + ".avg_vc_load")
|
||||||
|
.flags(Stats::pdf | Stats::total | Stats::nozero)
|
||||||
|
;
|
||||||
|
for (int i = 0; i < m_virtual_networks * m_vcs_per_vnet; i++) {
|
||||||
|
m_average_vc_load
|
||||||
|
.subname(i, csprintf(".%i", i))
|
||||||
|
.flags(Stats::nozero)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
out << endl;
|
|
||||||
for (int i = 0; i < m_links.size(); i++) {
|
|
||||||
average_link_utilization +=
|
|
||||||
(double(m_links[i]->getLinkUtilization())) /
|
|
||||||
(double(curCycle() - g_ruby_start));
|
|
||||||
|
|
||||||
vector<int> vc_load = m_links[i]->getVcLoad();
|
|
||||||
for (int j = 0; j < vc_load.size(); j++) {
|
|
||||||
assert(vc_load.size() == m_vcs_per_vnet*m_virtual_networks);
|
|
||||||
average_vc_load[j] += vc_load[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
average_link_utilization =
|
|
||||||
average_link_utilization/m_links.size();
|
|
||||||
out << "Average Link Utilization :: " << average_link_utilization
|
|
||||||
<< " flits/cycle" << endl;
|
|
||||||
out << "-------------" << endl;
|
|
||||||
|
|
||||||
for (int i = 0; i < m_vcs_per_vnet*m_virtual_networks; i++) {
|
|
||||||
if (!m_in_use[i/m_vcs_per_vnet])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
average_vc_load[i] = double(average_vc_load[i]) /
|
|
||||||
(double(curCycle() - g_ruby_start));
|
|
||||||
out << "Average VC Load [" << i << "] = " << average_vc_load[i]
|
|
||||||
<< " flits/cycle " << endl;
|
|
||||||
}
|
|
||||||
out << "-------------" << endl;
|
|
||||||
out << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GarnetNetwork::printPowerStats(ostream& out) const
|
GarnetNetwork::collateStats()
|
||||||
{
|
{
|
||||||
out << "Network Power" << endl;
|
for (int i = 0; i < m_links.size(); i++) {
|
||||||
out << "-------------" << endl;
|
m_average_link_utilization +=
|
||||||
out << "Orion does not work with flexible pipeline" << endl;
|
(double(m_links[i]->getLinkUtilization())) /
|
||||||
out << endl;
|
(double(curCycle() - g_ruby_start));
|
||||||
|
|
||||||
|
vector<unsigned int> vc_load = m_links[i]->getVcLoad();
|
||||||
|
for (int j = 0; j < vc_load.size(); j++) {
|
||||||
|
m_average_vc_load[j] += vc_load[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -58,11 +58,10 @@ class GarnetNetwork : public BaseGarnetNetwork
|
||||||
|
|
||||||
int getBufferSize() { return m_buffer_size; }
|
int getBufferSize() { return m_buffer_size; }
|
||||||
int getNumPipeStages() {return m_number_of_pipe_stages; }
|
int getNumPipeStages() {return m_number_of_pipe_stages; }
|
||||||
|
|
||||||
int getNumNodes(){ return m_nodes; }
|
int getNumNodes(){ return m_nodes; }
|
||||||
|
|
||||||
void printLinkStats(std::ostream& out) const;
|
void collateStats();
|
||||||
void printPowerStats(std::ostream& out) const;
|
void regStats();
|
||||||
void print(std::ostream& out) const;
|
void print(std::ostream& out) const;
|
||||||
|
|
||||||
// Methods used by Topology to setup the network
|
// Methods used by Topology to setup the network
|
||||||
|
@ -97,6 +96,10 @@ class GarnetNetwork : public BaseGarnetNetwork
|
||||||
|
|
||||||
int m_buffer_size;
|
int m_buffer_size;
|
||||||
int m_number_of_pipe_stages;
|
int m_number_of_pipe_stages;
|
||||||
|
|
||||||
|
// Statistical variables
|
||||||
|
Stats::Scalar m_average_link_utilization;
|
||||||
|
Stats::Vector m_average_vc_load;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream&
|
inline std::ostream&
|
||||||
|
|
|
@ -40,6 +40,7 @@ NetworkLink::NetworkLink(const Params *p)
|
||||||
m_link_utilized = 0;
|
m_link_utilized = 0;
|
||||||
m_latency = p->link_latency;
|
m_latency = p->link_latency;
|
||||||
m_id = p->link_id;
|
m_id = p->link_id;
|
||||||
|
|
||||||
int num_net = p->virt_nets;
|
int num_net = p->virt_nets;
|
||||||
int num_vc = p->vcs_per_vnet;
|
int num_vc = p->vcs_per_vnet;
|
||||||
m_vc_load.resize(num_net * num_vc);
|
m_vc_load.resize(num_net * num_vc);
|
||||||
|
@ -53,12 +54,6 @@ NetworkLink::~NetworkLink()
|
||||||
delete linkBuffer;
|
delete linkBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
NetworkLink::get_id()
|
|
||||||
{
|
|
||||||
return m_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
NetworkLink::setLinkConsumer(FlexibleConsumer *consumer)
|
NetworkLink::setLinkConsumer(FlexibleConsumer *consumer)
|
||||||
{
|
{
|
||||||
|
@ -101,18 +96,6 @@ NetworkLink::release_vc_link(int vc, Cycles release_time)
|
||||||
link_source->release_vc(m_out_port, vc, release_time);
|
link_source->release_vc(m_out_port, vc, release_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int>
|
|
||||||
NetworkLink::getVcLoad()
|
|
||||||
{
|
|
||||||
return m_vc_load;
|
|
||||||
}
|
|
||||||
|
|
||||||
double
|
|
||||||
NetworkLink::getLinkUtilization()
|
|
||||||
{
|
|
||||||
return (double(m_link_utilized));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
NetworkLink::isReady()
|
NetworkLink::isReady()
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,7 +59,7 @@ class NetworkLink : public ClockedObject, public FlexibleConsumer
|
||||||
|
|
||||||
bool is_vc_ready(flit *t_flit);
|
bool is_vc_ready(flit *t_flit);
|
||||||
|
|
||||||
int get_id();
|
int get_id() const { return m_id; }
|
||||||
void setInPort(int port);
|
void setInPort(int port);
|
||||||
void setOutPort(int port);
|
void setOutPort(int port);
|
||||||
void wakeup();
|
void wakeup();
|
||||||
|
@ -69,29 +69,28 @@ class NetworkLink : public ClockedObject, public FlexibleConsumer
|
||||||
void request_vc_link(int vc, NetDest destination, Cycles request_time);
|
void request_vc_link(int vc, NetDest destination, Cycles request_time);
|
||||||
bool isBufferNotFull_link(int vc);
|
bool isBufferNotFull_link(int vc);
|
||||||
void setSource(FlexibleConsumer *source);
|
void setSource(FlexibleConsumer *source);
|
||||||
double getLinkUtilization();
|
void init_net_ptr(GarnetNetwork* net_ptr) { m_net_ptr = net_ptr; }
|
||||||
std::vector<int> getVcLoad();
|
|
||||||
|
|
||||||
void init_net_ptr(GarnetNetwork* net_ptr)
|
unsigned int getLinkUtilization() const { return m_link_utilized; }
|
||||||
{
|
const std::vector<unsigned int> & getVcLoad() const { return m_vc_load; }
|
||||||
m_net_ptr = net_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool functionalRead(Packet *);
|
bool functionalRead(Packet *);
|
||||||
uint32_t functionalWrite(Packet *);
|
uint32_t functionalWrite(Packet *);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
int m_id;
|
int m_id;
|
||||||
Cycles m_latency;
|
Cycles m_latency;
|
||||||
int m_in_port, m_out_port;
|
int m_in_port, m_out_port;
|
||||||
int m_link_utilized;
|
|
||||||
std::vector<int> m_vc_load;
|
|
||||||
GarnetNetwork *m_net_ptr;
|
GarnetNetwork *m_net_ptr;
|
||||||
|
|
||||||
flitBuffer *linkBuffer;
|
flitBuffer *linkBuffer;
|
||||||
FlexibleConsumer *link_consumer;
|
FlexibleConsumer *link_consumer;
|
||||||
FlexibleConsumer *link_source;
|
FlexibleConsumer *link_source;
|
||||||
flitBuffer *link_srcQueue;
|
flitBuffer *link_srcQueue;
|
||||||
|
|
||||||
|
// Statistical variables
|
||||||
|
unsigned int m_link_utilized;
|
||||||
|
std::vector<unsigned int> m_vc_load;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __MEM_RUBY_NETWORK_GARNET_FLEXIBLE_PIPELINE_NETWORK_LINK_HH__
|
#endif // __MEM_RUBY_NETWORK_GARNET_FLEXIBLE_PIPELINE_NETWORK_LINK_HH__
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include "mem/ruby/network/orion/OrionLink.hh"
|
#include "mem/ruby/network/orion/OrionLink.hh"
|
||||||
#include "mem/ruby/network/orion/OrionRouter.hh"
|
#include "mem/ruby/network/orion/OrionRouter.hh"
|
||||||
|
|
||||||
double
|
void
|
||||||
Router_d::calculate_power()
|
Router_d::calculate_power()
|
||||||
{
|
{
|
||||||
//Network Activities from garnet
|
//Network Activities from garnet
|
||||||
|
@ -97,7 +97,7 @@ Router_d::calculate_power()
|
||||||
uint32_t in_buf_per_data_vc = m_network_ptr->getBuffersPerDataVC();
|
uint32_t in_buf_per_data_vc = m_network_ptr->getBuffersPerDataVC();
|
||||||
uint32_t in_buf_per_ctrl_vc = m_network_ptr->getBuffersPerCtrlVC();
|
uint32_t in_buf_per_ctrl_vc = m_network_ptr->getBuffersPerCtrlVC();
|
||||||
//flit width in bits
|
//flit width in bits
|
||||||
uint32_t flit_width_bits = m_network_ptr->getNiFlitSize() * 8;
|
uint32_t flit_width_bits = m_network_ptr->getNiFlitSize() * 8;
|
||||||
|
|
||||||
orion_rtr_ptr = new OrionRouter(
|
orion_rtr_ptr = new OrionRouter(
|
||||||
num_in_port,
|
num_in_port,
|
||||||
|
@ -120,16 +120,11 @@ Router_d::calculate_power()
|
||||||
double Psw_arb_local_dyn = 0.0;
|
double Psw_arb_local_dyn = 0.0;
|
||||||
double Psw_arb_global_dyn = 0.0;
|
double Psw_arb_global_dyn = 0.0;
|
||||||
double Pxbar_dyn = 0.0;
|
double Pxbar_dyn = 0.0;
|
||||||
double Ptotal_dyn = 0.0;
|
|
||||||
|
|
||||||
double Pbuf_sta = 0.0;
|
double Pbuf_sta = 0.0;
|
||||||
double Pvc_arb_sta = 0.0;
|
double Pvc_arb_sta = 0.0;
|
||||||
double Psw_arb_sta = 0.0;
|
double Psw_arb_sta = 0.0;
|
||||||
double Pxbar_sta = 0.0;
|
double Pxbar_sta = 0.0;
|
||||||
double Ptotal_sta = 0.0;
|
|
||||||
|
|
||||||
double Ptotal = 0.0;
|
|
||||||
|
|
||||||
|
|
||||||
//Dynamic Power
|
//Dynamic Power
|
||||||
|
|
||||||
|
@ -198,13 +193,11 @@ Router_d::calculate_power()
|
||||||
(crossbar_count/sim_cycles)*freq_Hz;
|
(crossbar_count/sim_cycles)*freq_Hz;
|
||||||
|
|
||||||
// Total
|
// Total
|
||||||
Ptotal_dyn = Pbuf_wr_dyn + Pbuf_rd_dyn +
|
m_power_dyn = Pbuf_wr_dyn + Pbuf_rd_dyn +
|
||||||
Pvc_arb_local_dyn + Pvc_arb_global_dyn +
|
Pvc_arb_local_dyn + Pvc_arb_global_dyn +
|
||||||
Psw_arb_local_dyn + Psw_arb_global_dyn +
|
Psw_arb_local_dyn + Psw_arb_global_dyn +
|
||||||
Pxbar_dyn;
|
Pxbar_dyn;
|
||||||
|
|
||||||
m_power_dyn = Ptotal_dyn;
|
|
||||||
|
|
||||||
// Clock Power
|
// Clock Power
|
||||||
m_clk_power = orion_rtr_ptr->calc_dynamic_energy_clock()*freq_Hz;
|
m_clk_power = orion_rtr_ptr->calc_dynamic_energy_clock()*freq_Hz;
|
||||||
|
|
||||||
|
@ -214,16 +207,10 @@ Router_d::calculate_power()
|
||||||
Psw_arb_sta = orion_rtr_ptr->get_static_power_sa();
|
Psw_arb_sta = orion_rtr_ptr->get_static_power_sa();
|
||||||
Pxbar_sta = orion_rtr_ptr->get_static_power_xbar();
|
Pxbar_sta = orion_rtr_ptr->get_static_power_xbar();
|
||||||
|
|
||||||
Ptotal_sta += Pbuf_sta + Pvc_arb_sta + Psw_arb_sta + Pxbar_sta;
|
m_power_sta = Pbuf_sta + Pvc_arb_sta + Psw_arb_sta + Pxbar_sta;
|
||||||
|
|
||||||
m_power_sta = Ptotal_sta;
|
|
||||||
|
|
||||||
Ptotal = m_power_dyn + m_power_sta + m_clk_power;
|
|
||||||
|
|
||||||
return Ptotal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
void
|
||||||
NetworkLink_d::calculate_power()
|
NetworkLink_d::calculate_power()
|
||||||
{
|
{
|
||||||
OrionConfig* orion_cfg_ptr;
|
OrionConfig* orion_cfg_ptr;
|
||||||
|
@ -249,20 +236,17 @@ NetworkLink_d::calculate_power()
|
||||||
|
|
||||||
// Dynamic Power
|
// Dynamic Power
|
||||||
// Assume half the bits flipped on every link activity
|
// Assume half the bits flipped on every link activity
|
||||||
double Plink_dyn =
|
double link_dynamic_energy =
|
||||||
orion_link_ptr->calc_dynamic_energy(channel_width_bits/2)*
|
orion_link_ptr->calc_dynamic_energy(channel_width_bits/2);
|
||||||
(m_link_utilized/ sim_cycles)*freq_Hz;
|
m_power_dyn = link_dynamic_energy * (m_link_utilized / sim_cycles) *
|
||||||
|
freq_Hz;
|
||||||
|
|
||||||
m_power_dyn = Plink_dyn;
|
|
||||||
|
|
||||||
// Static Power
|
// Static Power
|
||||||
// Calculates number of repeaters needed in link, and their static power
|
// Calculates number of repeaters needed in link, and their static power
|
||||||
// For short links, like 1mm, no repeaters are needed so static power is 0
|
// For short links, like 1mm, no repeaters are needed so static power is 0
|
||||||
double Plink_sta = orion_link_ptr->get_static_power();
|
m_power_sta = orion_link_ptr->get_static_power();
|
||||||
|
|
||||||
m_power_sta = Plink_sta;
|
delete orion_link_ptr;
|
||||||
|
delete orion_cfg_ptr;
|
||||||
double Ptotal = m_power_dyn + m_power_sta;
|
|
||||||
|
|
||||||
return Ptotal;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,34 +102,6 @@ PerfectSwitch::addOutPort(const vector<MessageBuffer*>& out,
|
||||||
m_routing_table.push_back(routing_table_entry);
|
m_routing_table.push_back(routing_table_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
PerfectSwitch::clearRoutingTables()
|
|
||||||
{
|
|
||||||
m_routing_table.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PerfectSwitch::clearBuffers()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < m_in.size(); i++){
|
|
||||||
for(int vnet = 0; vnet < m_virtual_networks; vnet++) {
|
|
||||||
m_in[i][vnet]->clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < m_out.size(); i++){
|
|
||||||
for(int vnet = 0; vnet < m_virtual_networks; vnet++) {
|
|
||||||
m_out[i][vnet]->clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PerfectSwitch::reconfigureOutPort(const NetDest& routing_table_entry)
|
|
||||||
{
|
|
||||||
m_routing_table.push_back(routing_table_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
PerfectSwitch::~PerfectSwitch()
|
PerfectSwitch::~PerfectSwitch()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -328,16 +300,15 @@ PerfectSwitch::storeEventInfo(int info)
|
||||||
m_pending_message_count[info]++;
|
m_pending_message_count[info]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
PerfectSwitch::printStats(std::ostream& out) const
|
|
||||||
{
|
|
||||||
out << "PerfectSwitch printStats" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PerfectSwitch::clearStats()
|
PerfectSwitch::clearStats()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
void
|
||||||
|
PerfectSwitch::collateStats()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PerfectSwitch::print(std::ostream& out) const
|
PerfectSwitch::print(std::ostream& out) const
|
||||||
|
|
|
@ -67,18 +67,15 @@ class PerfectSwitch : public Consumer
|
||||||
void init(SimpleNetwork *);
|
void init(SimpleNetwork *);
|
||||||
void addInPort(const std::vector<MessageBuffer*>& in);
|
void addInPort(const std::vector<MessageBuffer*>& in);
|
||||||
void addOutPort(const std::vector<MessageBuffer*>& out,
|
void addOutPort(const std::vector<MessageBuffer*>& out,
|
||||||
const NetDest& routing_table_entry);
|
const NetDest& routing_table_entry);
|
||||||
void clearRoutingTables();
|
|
||||||
void clearBuffers();
|
|
||||||
void reconfigureOutPort(const NetDest& routing_table_entry);
|
|
||||||
int getInLinks() const { return m_in.size(); }
|
int getInLinks() const { return m_in.size(); }
|
||||||
int getOutLinks() const { return m_out.size(); }
|
int getOutLinks() const { return m_out.size(); }
|
||||||
|
|
||||||
void wakeup();
|
void wakeup();
|
||||||
void storeEventInfo(int info);
|
void storeEventInfo(int info);
|
||||||
|
|
||||||
void printStats(std::ostream& out) const;
|
|
||||||
void clearStats();
|
void clearStats();
|
||||||
|
void collateStats();
|
||||||
void print(std::ostream& out) const;
|
void print(std::ostream& out) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -206,76 +206,39 @@ SimpleNetwork::getThrottles(NodeID id) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SimpleNetwork::printStats(ostream& out) const
|
SimpleNetwork::regStats()
|
||||||
{
|
{
|
||||||
out << endl;
|
m_msg_counts.resize(MessageSizeType_NUM);
|
||||||
out << "Network Stats" << endl;
|
m_msg_bytes.resize(MessageSizeType_NUM);
|
||||||
out << "-------------" << endl;
|
|
||||||
out << endl;
|
|
||||||
|
|
||||||
//
|
for (MessageSizeType type = MessageSizeType_FIRST;
|
||||||
// Determine total counts before printing out each switch's stats
|
type < MessageSizeType_NUM; ++type) {
|
||||||
//
|
m_msg_counts[(unsigned int) type]
|
||||||
std::vector<uint64> total_msg_counts;
|
.name(name() + ".msg_count." + MessageSizeType_to_string(type))
|
||||||
total_msg_counts.resize(MessageSizeType_NUM);
|
.flags(Stats::nozero)
|
||||||
for (MessageSizeType type = MessageSizeType_FIRST;
|
;
|
||||||
type < MessageSizeType_NUM;
|
m_msg_bytes[(unsigned int) type]
|
||||||
++type) {
|
.name(name() + ".msg_byte." + MessageSizeType_to_string(type))
|
||||||
total_msg_counts[type] = 0;
|
.flags(Stats::nozero)
|
||||||
}
|
;
|
||||||
|
|
||||||
for (int i = 0; i < m_switches.size(); i++) {
|
|
||||||
const std::vector<Throttle*>* throttles =
|
|
||||||
m_switches[i]->getThrottles();
|
|
||||||
|
|
||||||
for (int p = 0; p < throttles->size(); p++) {
|
|
||||||
|
|
||||||
const std::vector<std::vector<int> >& message_counts =
|
|
||||||
((*throttles)[p])->getCounters();
|
|
||||||
|
|
||||||
for (MessageSizeType type = MessageSizeType_FIRST;
|
|
||||||
type < MessageSizeType_NUM;
|
|
||||||
++type) {
|
|
||||||
|
|
||||||
const std::vector<int> &mct = message_counts[type];
|
// Now state what the formula is.
|
||||||
int sum = accumulate(mct.begin(), mct.end(), 0);
|
for (int i = 0; i < m_switches.size(); i++) {
|
||||||
total_msg_counts[type] += uint64(sum);
|
m_msg_counts[(unsigned int) type] +=
|
||||||
}
|
sum(m_switches[i]->getMsgCount(type));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
uint64 total_msgs = 0;
|
m_msg_bytes[(unsigned int) type] =
|
||||||
uint64 total_bytes = 0;
|
m_msg_counts[(unsigned int) type] * Stats::constant(
|
||||||
for (MessageSizeType type = MessageSizeType_FIRST;
|
Network::MessageSizeType_to_int(type));
|
||||||
type < MessageSizeType_NUM;
|
|
||||||
++type) {
|
|
||||||
|
|
||||||
if (total_msg_counts[type] > 0) {
|
|
||||||
out << "total_msg_count_" << type << ": " << total_msg_counts[type]
|
|
||||||
<< " " << total_msg_counts[type] *
|
|
||||||
uint64(MessageSizeType_to_int(type))
|
|
||||||
<< endl;
|
|
||||||
|
|
||||||
total_msgs += total_msg_counts[type];
|
|
||||||
|
|
||||||
total_bytes += total_msg_counts[type] *
|
|
||||||
uint64(MessageSizeType_to_int(type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out << "total_msgs: " << total_msgs
|
|
||||||
<< " total_bytes: " << total_bytes << endl;
|
|
||||||
|
|
||||||
out << endl;
|
|
||||||
for (int i = 0; i < m_switches.size(); i++) {
|
|
||||||
m_switches[i]->printStats(out);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SimpleNetwork::clearStats()
|
SimpleNetwork::collateStats()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < m_switches.size(); i++) {
|
for (int i = 0; i < m_switches.size(); i++) {
|
||||||
m_switches[i]->clearStats();
|
m_switches[i]->collateStats();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,8 @@ class SimpleNetwork : public Network
|
||||||
int getEndpointBandwidth() { return m_endpoint_bandwidth; }
|
int getEndpointBandwidth() { return m_endpoint_bandwidth; }
|
||||||
bool getAdaptiveRouting() {return m_adaptive_routing; }
|
bool getAdaptiveRouting() {return m_adaptive_routing; }
|
||||||
|
|
||||||
void printStats(std::ostream& out) const;
|
void collateStats();
|
||||||
void clearStats();
|
void regStats();
|
||||||
|
|
||||||
// returns the queue requested for the given component
|
// returns the queue requested for the given component
|
||||||
MessageBuffer* getToNetQueue(NodeID id, bool ordered, int network_num, std::string vnet_type);
|
MessageBuffer* getToNetQueue(NodeID id, bool ordered, int network_num, std::string vnet_type);
|
||||||
|
@ -90,9 +90,7 @@ class SimpleNetwork : public Network
|
||||||
void addLink(SwitchID src, SwitchID dest, int link_latency);
|
void addLink(SwitchID src, SwitchID dest, int link_latency);
|
||||||
void makeLink(SwitchID src, SwitchID dest,
|
void makeLink(SwitchID src, SwitchID dest,
|
||||||
const NetDest& routing_table_entry, int link_latency);
|
const NetDest& routing_table_entry, int link_latency);
|
||||||
SwitchID createSwitch();
|
|
||||||
void makeTopology();
|
void makeTopology();
|
||||||
void linkTopology();
|
|
||||||
|
|
||||||
// Private copy constructor and assignment operator
|
// Private copy constructor and assignment operator
|
||||||
SimpleNetwork(const SimpleNetwork& obj);
|
SimpleNetwork(const SimpleNetwork& obj);
|
||||||
|
@ -111,6 +109,10 @@ class SimpleNetwork : public Network
|
||||||
int m_buffer_size;
|
int m_buffer_size;
|
||||||
int m_endpoint_bandwidth;
|
int m_endpoint_bandwidth;
|
||||||
bool m_adaptive_routing;
|
bool m_adaptive_routing;
|
||||||
|
|
||||||
|
//Statistical variables
|
||||||
|
std::vector<Stats::Formula> m_msg_counts;
|
||||||
|
std::vector<Stats::Formula> m_msg_bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream&
|
inline std::ostream&
|
||||||
|
|
|
@ -44,6 +44,8 @@ using m5::stl_helpers::operator<<;
|
||||||
Switch::Switch(const Params *p) : BasicRouter(p)
|
Switch::Switch(const Params *p) : BasicRouter(p)
|
||||||
{
|
{
|
||||||
m_perfect_switch = new PerfectSwitch(m_id, this, p->virt_nets);
|
m_perfect_switch = new PerfectSwitch(m_id, this, p->virt_nets);
|
||||||
|
m_msg_counts.resize(MessageSizeType_NUM);
|
||||||
|
m_msg_bytes.resize(MessageSizeType_NUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
Switch::~Switch()
|
Switch::~Switch()
|
||||||
|
@ -110,29 +112,6 @@ Switch::addOutPort(const vector<MessageBuffer*>& out,
|
||||||
throttle_ptr->addLinks(intermediateBuffers, out);
|
throttle_ptr->addLinks(intermediateBuffers, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Switch::clearRoutingTables()
|
|
||||||
{
|
|
||||||
m_perfect_switch->clearRoutingTables();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Switch::clearBuffers()
|
|
||||||
{
|
|
||||||
m_perfect_switch->clearBuffers();
|
|
||||||
for (int i = 0; i < m_throttles.size(); i++) {
|
|
||||||
if (m_throttles[i] != NULL) {
|
|
||||||
m_throttles[i]->clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Switch::reconfigureOutPort(const NetDest& routing_table_entry)
|
|
||||||
{
|
|
||||||
m_perfect_switch->reconfigureOutPort(routing_table_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Throttle*
|
const Throttle*
|
||||||
Switch::getThrottle(LinkID link_number) const
|
Switch::getThrottle(LinkID link_number) const
|
||||||
{
|
{
|
||||||
|
@ -147,77 +126,54 @@ Switch::getThrottles() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Switch::printStats(std::ostream& out) const
|
Switch::regStats()
|
||||||
{
|
{
|
||||||
ccprintf(out, "switch_%d_inlinks: %d\n", m_id,
|
|
||||||
m_perfect_switch->getInLinks());
|
|
||||||
ccprintf(out, "switch_%d_outlinks: %d\n", m_id,
|
|
||||||
m_perfect_switch->getOutLinks());
|
|
||||||
|
|
||||||
// Average link utilizations
|
|
||||||
double average_utilization = 0.0;
|
|
||||||
int throttle_count = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < m_throttles.size(); i++) {
|
|
||||||
Throttle* throttle_ptr = m_throttles[i];
|
|
||||||
if (throttle_ptr) {
|
|
||||||
average_utilization += throttle_ptr->getUtilization();
|
|
||||||
throttle_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
average_utilization =
|
|
||||||
throttle_count == 0 ? 0 : average_utilization / throttle_count;
|
|
||||||
|
|
||||||
// Individual link utilizations
|
|
||||||
out << "links_utilized_percent_switch_" << m_id << ": "
|
|
||||||
<< average_utilization << endl;
|
|
||||||
|
|
||||||
for (int link = 0; link < m_throttles.size(); link++) {
|
for (int link = 0; link < m_throttles.size(); link++) {
|
||||||
Throttle* throttle_ptr = m_throttles[link];
|
m_throttles[link]->regStats(name());
|
||||||
if (throttle_ptr != NULL) {
|
|
||||||
out << " links_utilized_percent_switch_" << m_id
|
|
||||||
<< "_link_" << link << ": "
|
|
||||||
<< throttle_ptr->getUtilization() << " bw: "
|
|
||||||
<< throttle_ptr->getLinkBandwidth()
|
|
||||||
<< " base_latency: " << throttle_ptr->getLatency() << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
out << endl;
|
|
||||||
|
|
||||||
// Traffic breakdown
|
m_avg_utilization.name(name() + ".percent_links_utilized");
|
||||||
for (int link = 0; link < m_throttles.size(); link++) {
|
for (unsigned int i = 0; i < m_throttles.size(); i++) {
|
||||||
Throttle* throttle_ptr = m_throttles[link];
|
m_avg_utilization += m_throttles[i]->getUtilization();
|
||||||
if (!throttle_ptr)
|
}
|
||||||
continue;
|
m_avg_utilization /= Stats::constant(m_throttles.size());
|
||||||
|
|
||||||
const vector<vector<int> >& message_counts =
|
for (unsigned int type = MessageSizeType_FIRST;
|
||||||
throttle_ptr->getCounters();
|
type < MessageSizeType_NUM; ++type) {
|
||||||
for (int int_type = 0; int_type < MessageSizeType_NUM; int_type++) {
|
m_msg_counts[type]
|
||||||
MessageSizeType type = MessageSizeType(int_type);
|
.name(name() + ".msg_count." +
|
||||||
const vector<int> &mct = message_counts[type];
|
MessageSizeType_to_string(MessageSizeType(type)))
|
||||||
int sum = accumulate(mct.begin(), mct.end(), 0);
|
.flags(Stats::nozero)
|
||||||
if (sum == 0)
|
;
|
||||||
continue;
|
m_msg_bytes[type]
|
||||||
|
.name(name() + ".msg_bytes." +
|
||||||
out << " outgoing_messages_switch_" << m_id
|
MessageSizeType_to_string(MessageSizeType(type)))
|
||||||
<< "_link_" << link << "_" << type << ": " << sum << " "
|
.flags(Stats::nozero)
|
||||||
<< sum * m_network_ptr->MessageSizeType_to_int(type)
|
;
|
||||||
<< " ";
|
|
||||||
out << mct;
|
for (unsigned int i = 0; i < m_throttles.size(); i++) {
|
||||||
out << " base_latency: "
|
m_msg_counts[type] += m_throttles[i]->getMsgCount(type);
|
||||||
<< throttle_ptr->getLatency() << endl;
|
}
|
||||||
}
|
m_msg_bytes[type] = m_msg_counts[type] * Stats::constant(
|
||||||
|
Network::MessageSizeType_to_int(MessageSizeType(type)));
|
||||||
}
|
}
|
||||||
out << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Switch::clearStats()
|
Switch::resetStats()
|
||||||
{
|
{
|
||||||
m_perfect_switch->clearStats();
|
m_perfect_switch->clearStats();
|
||||||
for (int i = 0; i < m_throttles.size(); i++) {
|
for (int i = 0; i < m_throttles.size(); i++) {
|
||||||
if (m_throttles[i] != NULL)
|
m_throttles[i]->clearStats();
|
||||||
m_throttles[i]->clearStats();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Switch::collateStats()
|
||||||
|
{
|
||||||
|
m_perfect_switch->collateStats();
|
||||||
|
for (int i = 0; i < m_throttles.size(); i++) {
|
||||||
|
m_throttles[i]->collateStats();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,12 +67,13 @@ class Switch : public BasicRouter
|
||||||
int bw_multiplier);
|
int bw_multiplier);
|
||||||
const Throttle* getThrottle(LinkID link_number) const;
|
const Throttle* getThrottle(LinkID link_number) const;
|
||||||
const std::vector<Throttle*>* getThrottles() const;
|
const std::vector<Throttle*>* getThrottles() const;
|
||||||
void clearRoutingTables();
|
|
||||||
void clearBuffers();
|
|
||||||
void reconfigureOutPort(const NetDest& routing_table_entry);
|
|
||||||
|
|
||||||
void printStats(std::ostream& out) const;
|
void resetStats();
|
||||||
void clearStats();
|
void collateStats();
|
||||||
|
void regStats();
|
||||||
|
const Stats::Formula & getMsgCount(unsigned int type) const
|
||||||
|
{ return m_msg_counts[type]; }
|
||||||
|
|
||||||
void print(std::ostream& out) const;
|
void print(std::ostream& out) const;
|
||||||
void init_net_ptr(SimpleNetwork* net_ptr) { m_network_ptr = net_ptr; }
|
void init_net_ptr(SimpleNetwork* net_ptr) { m_network_ptr = net_ptr; }
|
||||||
|
|
||||||
|
@ -88,6 +89,11 @@ class Switch : public BasicRouter
|
||||||
SimpleNetwork* m_network_ptr;
|
SimpleNetwork* m_network_ptr;
|
||||||
std::vector<Throttle*> m_throttles;
|
std::vector<Throttle*> m_throttles;
|
||||||
std::vector<MessageBuffer*> m_buffers_to_free;
|
std::vector<MessageBuffer*> m_buffers_to_free;
|
||||||
|
|
||||||
|
// Statistical variables
|
||||||
|
Stats::Formula m_avg_utilization;
|
||||||
|
std::vector<Stats::Formula> m_msg_counts;
|
||||||
|
std::vector<Stats::Formula> m_msg_bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream&
|
inline std::ostream&
|
||||||
|
|
|
@ -79,16 +79,11 @@ Throttle::init(NodeID node, Cycles link_latency,
|
||||||
m_endpoint_bandwidth = endpoint_bandwidth;
|
m_endpoint_bandwidth = endpoint_bandwidth;
|
||||||
|
|
||||||
m_wakeups_wo_switch = 0;
|
m_wakeups_wo_switch = 0;
|
||||||
clearStats();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
m_msg_counts.resize(MessageSizeType_NUM);
|
||||||
Throttle::clear()
|
m_msg_bytes.resize(MessageSizeType_NUM);
|
||||||
{
|
|
||||||
for (int counter = 0; counter < m_vnets; counter++) {
|
m_link_utilization_proxy = 0;
|
||||||
m_in[counter]->clear();
|
|
||||||
m_out[counter]->clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -99,14 +94,6 @@ Throttle::addLinks(const std::vector<MessageBuffer*>& in_vec,
|
||||||
for (int i=0; i<in_vec.size(); i++) {
|
for (int i=0; i<in_vec.size(); i++) {
|
||||||
addVirtualNetwork(in_vec[i], out_vec[i]);
|
addVirtualNetwork(in_vec[i], out_vec[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_message_counters.resize(MessageSizeType_NUM);
|
|
||||||
for (int i = 0; i < MessageSizeType_NUM; i++) {
|
|
||||||
m_message_counters[i].resize(in_vec.size());
|
|
||||||
for (int j = 0; j<m_message_counters[i].size(); j++) {
|
|
||||||
m_message_counters[i][j] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -179,7 +166,7 @@ Throttle::wakeup()
|
||||||
m_in[vnet]->pop();
|
m_in[vnet]->pop();
|
||||||
|
|
||||||
// Count the message
|
// Count the message
|
||||||
m_message_counters[net_msg_ptr->getMessageSize()][vnet]++;
|
m_msg_counts[net_msg_ptr->getMessageSize()][vnet]++;
|
||||||
|
|
||||||
DPRINTF(RubyNetwork, "%s\n", *m_out[vnet]);
|
DPRINTF(RubyNetwork, "%s\n", *m_out[vnet]);
|
||||||
}
|
}
|
||||||
|
@ -208,7 +195,7 @@ Throttle::wakeup()
|
||||||
double ratio = 1.0 - (double(bw_remaining) / double(getLinkBandwidth()));
|
double ratio = 1.0 - (double(bw_remaining) / double(getLinkBandwidth()));
|
||||||
|
|
||||||
// If ratio = 0, we used no bandwidth, if ratio = 1, we used all
|
// If ratio = 0, we used no bandwidth, if ratio = 1, we used all
|
||||||
linkUtilized(ratio);
|
m_link_utilization_proxy += ratio;
|
||||||
|
|
||||||
if (bw_remaining > 0 && !schedule_wakeup) {
|
if (bw_remaining > 0 && !schedule_wakeup) {
|
||||||
// We have extra bandwidth and our output buffer was
|
// We have extra bandwidth and our output buffer was
|
||||||
|
@ -225,29 +212,41 @@ Throttle::wakeup()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Throttle::printStats(ostream& out) const
|
Throttle::regStats(string parent)
|
||||||
{
|
{
|
||||||
out << "utilized_percent: " << getUtilization() << endl;
|
m_link_utilization
|
||||||
|
.name(parent + csprintf(".throttle%i", m_node) + ".link_utilization");
|
||||||
|
|
||||||
|
for (MessageSizeType type = MessageSizeType_FIRST;
|
||||||
|
type < MessageSizeType_NUM; ++type) {
|
||||||
|
m_msg_counts[(unsigned int)type]
|
||||||
|
.init(m_vnets)
|
||||||
|
.name(parent + csprintf(".throttle%i", m_node) + ".msg_count." +
|
||||||
|
MessageSizeType_to_string(type))
|
||||||
|
.flags(Stats::nozero)
|
||||||
|
;
|
||||||
|
m_msg_bytes[(unsigned int) type]
|
||||||
|
.name(parent + csprintf(".throttle%i", m_node) + ".msg_bytes." +
|
||||||
|
MessageSizeType_to_string(type))
|
||||||
|
.flags(Stats::nozero)
|
||||||
|
;
|
||||||
|
|
||||||
|
m_msg_bytes[(unsigned int) type] = m_msg_counts[type] * Stats::constant(
|
||||||
|
Network::MessageSizeType_to_int(type));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Throttle::clearStats()
|
Throttle::clearStats()
|
||||||
{
|
{
|
||||||
m_ruby_start = g_system_ptr->curCycle();
|
m_link_utilization_proxy = 0;
|
||||||
m_links_utilized = 0.0;
|
|
||||||
|
|
||||||
for (int i = 0; i < m_message_counters.size(); i++) {
|
|
||||||
for (int j = 0; j < m_message_counters[i].size(); j++) {
|
|
||||||
m_message_counters[i][j] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
void
|
||||||
Throttle::getUtilization() const
|
Throttle::collateStats()
|
||||||
{
|
{
|
||||||
return 100.0 * double(m_links_utilized) /
|
m_link_utilization = 100.0 * m_link_utilization_proxy
|
||||||
double(g_system_ptr->curCycle()-m_ruby_start);
|
/ (double(g_system_ptr->curCycle() - g_ruby_start));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -63,32 +63,29 @@ class Throttle : public Consumer
|
||||||
{ return csprintf("Throttle-%i", m_sID); }
|
{ return csprintf("Throttle-%i", m_sID); }
|
||||||
|
|
||||||
void addLinks(const std::vector<MessageBuffer*>& in_vec,
|
void addLinks(const std::vector<MessageBuffer*>& in_vec,
|
||||||
const std::vector<MessageBuffer*>& out_vec);
|
const std::vector<MessageBuffer*>& out_vec);
|
||||||
void wakeup();
|
void wakeup();
|
||||||
|
|
||||||
void printStats(std::ostream& out) const;
|
// The average utilization (a fraction) since last clearStats()
|
||||||
void clearStats();
|
const Stats::Scalar & getUtilization() const
|
||||||
// The average utilization (a percent) since last clearStats()
|
{ return m_link_utilization; }
|
||||||
double getUtilization() const;
|
const Stats::Vector & getMsgCount(unsigned int type) const
|
||||||
|
{ return m_msg_counts[type]; }
|
||||||
|
|
||||||
int getLinkBandwidth() const
|
int getLinkBandwidth() const
|
||||||
{ return m_endpoint_bandwidth * m_link_bandwidth_multiplier; }
|
{ return m_endpoint_bandwidth * m_link_bandwidth_multiplier; }
|
||||||
|
|
||||||
Cycles getLatency() const { return m_link_latency; }
|
Cycles getLatency() const { return m_link_latency; }
|
||||||
const std::vector<std::vector<int> >&
|
|
||||||
getCounters() const
|
|
||||||
{
|
|
||||||
return m_message_counters;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
|
void clearStats();
|
||||||
|
void collateStats();
|
||||||
|
void regStats(std::string name);
|
||||||
void print(std::ostream& out) const;
|
void print(std::ostream& out) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init(NodeID node, Cycles link_latency, int link_bandwidth_multiplier,
|
void init(NodeID node, Cycles link_latency, int link_bandwidth_multiplier,
|
||||||
int endpoint_bandwidth);
|
int endpoint_bandwidth);
|
||||||
void addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr);
|
void addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr);
|
||||||
void linkUtilized(double ratio) { m_links_utilized += ratio; }
|
|
||||||
|
|
||||||
// Private copy constructor and assignment operator
|
// Private copy constructor and assignment operator
|
||||||
Throttle(const Throttle& obj);
|
Throttle(const Throttle& obj);
|
||||||
|
@ -96,8 +93,7 @@ class Throttle : public Consumer
|
||||||
|
|
||||||
std::vector<MessageBuffer*> m_in;
|
std::vector<MessageBuffer*> m_in;
|
||||||
std::vector<MessageBuffer*> m_out;
|
std::vector<MessageBuffer*> m_out;
|
||||||
std::vector<std::vector<int> > m_message_counters;
|
unsigned int m_vnets;
|
||||||
int m_vnets;
|
|
||||||
std::vector<int> m_units_remaining;
|
std::vector<int> m_units_remaining;
|
||||||
int m_sID;
|
int m_sID;
|
||||||
NodeID m_node;
|
NodeID m_node;
|
||||||
|
@ -106,9 +102,12 @@ class Throttle : public Consumer
|
||||||
int m_wakeups_wo_switch;
|
int m_wakeups_wo_switch;
|
||||||
int m_endpoint_bandwidth;
|
int m_endpoint_bandwidth;
|
||||||
|
|
||||||
// For tracking utilization
|
// Statistical variables
|
||||||
Cycles m_ruby_start;
|
Stats::Scalar m_link_utilization;
|
||||||
double m_links_utilized;
|
std::vector<Stats::Vector> m_msg_counts;
|
||||||
|
std::vector<Stats::Formula> m_msg_bytes;
|
||||||
|
|
||||||
|
double m_link_utilization_proxy;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream&
|
inline std::ostream&
|
||||||
|
|
|
@ -140,11 +140,9 @@ RubySystem::printStats(ostream& out)
|
||||||
tm *localTime = localtime(&T);
|
tm *localTime = localtime(&T);
|
||||||
char buf[100];
|
char buf[100];
|
||||||
strftime(buf, 100, "%b/%d/%Y %H:%M:%S", localTime);
|
strftime(buf, 100, "%b/%d/%Y %H:%M:%S", localTime);
|
||||||
|
|
||||||
out << "Real time: " << buf << endl;
|
out << "Real time: " << buf << endl;
|
||||||
|
|
||||||
m_profiler_ptr->printStats(out);
|
m_profiler_ptr->printStats(out);
|
||||||
m_network_ptr->printStats(out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -410,7 +408,6 @@ void
|
||||||
RubySystem::resetStats()
|
RubySystem::resetStats()
|
||||||
{
|
{
|
||||||
m_profiler_ptr->clearStats();
|
m_profiler_ptr->clearStats();
|
||||||
m_network_ptr->clearStats();
|
|
||||||
for (uint32_t cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) {
|
for (uint32_t cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) {
|
||||||
m_abs_cntrl_vec[cntrl]->clearStats();
|
m_abs_cntrl_vec[cntrl]->clearStats();
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,9 +104,6 @@ class RubySystem : public ClockedObject
|
||||||
|
|
||||||
void printStats(std::ostream& out);
|
void printStats(std::ostream& out);
|
||||||
void resetStats();
|
void resetStats();
|
||||||
|
|
||||||
uint64 getInstructionCount(int thread) { return 1; }
|
|
||||||
|
|
||||||
void print(std::ostream& out) const;
|
void print(std::ostream& out) const;
|
||||||
|
|
||||||
void serialize(std::ostream &os);
|
void serialize(std::ostream &os);
|
||||||
|
|
Loading…
Reference in a new issue