public:
typedef InfoProxyType<Derived> Info;
+ DataWrapVec()
+ {}
+
+ DataWrapVec(const DataWrapVec &ref)
+ {}
+
// The following functions are specific to vectors. If you use them
// in a non vector context, you will get a nice compiler error!
AbstractController *abs_cntrl = ext_link->params()->ext_node;
abs_cntrl->initNetworkPtr(this);
}
+
+ // Register a callback function for combining the statistics
+ Stats::registerDumpCallback(new StatsCallback(this));
}
void
LinkDirection direction,
const NetDest& routing_table_entry) = 0;
- virtual void printStats(std::ostream& out) const = 0;
- virtual void clearStats() = 0;
+ virtual void collateStats() = 0;
virtual void print(std::ostream& out) const = 0;
/*
Network(const Network& obj);
Network& operator=(const Network& obj);
- protected:
- const std::string m_name;
- int m_nodes;
+ uint32_t m_nodes;
static uint32_t m_virtual_networks;
Topology* m_topology_ptr;
static uint32_t m_control_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&
m_in_use.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++) {
m_in_use[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++) {
}
void
-BaseGarnetNetwork::clearStats()
+BaseGarnetNetwork::regStats()
{
-}
-
-void
-BaseGarnetNetwork::printStats(ostream& out) const
-{
- out << endl;
- out << "Network Stats" << endl;
- out << "-------------" << endl;
- out << endl;
- printPerformanceStats(out);
- printLinkStats(out);
- printPowerStats(out);
-}
-
-void
-BaseGarnetNetwork::printPerformanceStats(ostream& out) const
-{
- int total_flits_injected = 0;
- int total_flits_received = 0;
- int total_network_latency = 0.0;
- int total_queueing_latency = 0.0;
+ m_flits_received
+ .init(m_virtual_networks)
+ .name(name() + ".flits_received")
+ .flags(Stats::pdf | Stats::total | Stats::nozero | Stats::oneline)
+ ;
+
+ m_flits_injected
+ .init(m_virtual_networks)
+ .name(name() + ".flits_injected")
+ .flags(Stats::pdf | Stats::total | Stats::nozero | Stats::oneline)
+ ;
+
+ m_network_latency
+ .init(m_virtual_networks)
+ .name(name() + ".network_latency")
+ .flags(Stats::oneline)
+ ;
+
+ m_queueing_latency
+ .init(m_virtual_networks)
+ .name(name() + ".queueing_latency")
+ .flags(Stats::oneline)
+ ;
for (int i = 0; i < m_virtual_networks; i++) {
- if (!m_in_use[i])
- continue;
-
- out << "[Vnet " << i << "]: flits injected = "
- << 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];
+ m_flits_received.subname(i, csprintf("vnet-%i", i));
+ m_flits_injected.subname(i, csprintf("vnet-%i", i));
+ m_network_latency.subname(i, csprintf("vnet-%i", i));
+ m_queueing_latency.subname(i, csprintf("vnet-%i", i));
}
- out << "Total flits injected = " << total_flits_injected << endl;
- out << "Total flits received = " << total_flits_received << endl;
- out << "Average network latency = "
- << ((double) total_network_latency/ (double) total_flits_received) << endl;
- out << "Average queueing (at source NI) latency = "
- << ((double) total_queueing_latency/ (double) total_flits_received) << endl;
- out << "Average latency = "
- << ((double) (total_queueing_latency + total_network_latency) /
- (double) total_flits_received)<< endl;
- out << "-------------" << endl;
- out << endl;
+
+ m_avg_vnet_latency
+ .name(name() + ".average_vnet_latency")
+ .flags(Stats::oneline);
+ m_avg_vnet_latency = m_network_latency / m_flits_received;
+
+ m_avg_vqueue_latency
+ .name(name() + ".average_vqueue_latency")
+ .flags(Stats::oneline);
+ m_avg_vqueue_latency = m_queueing_latency / m_flits_received;
+
+ 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;
}
virtual void checkNetworkAllocation(NodeID id, bool ordered,
int network_num, std::string vnet_type) = 0;
- void clearStats();
- void printStats(std::ostream& out) const;
- void printPerformanceStats(std::ostream& out) const;
- virtual void printLinkStats(std::ostream& out) const = 0;
- virtual void printPowerStats(std::ostream& out) const = 0;
+ virtual void regStats();
+ virtual void collateStats() {}
protected:
int m_ni_flit_size;
int m_vcs_per_vnet;
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_ordered;
std::vector<std::vector<MessageBuffer*> > m_toNetQueues;
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__
}
void
-GarnetNetwork_d::printLinkStats(ostream& out) const
+GarnetNetwork_d::regStats()
{
- double average_link_utilization = 0;
- vector<double> average_vc_load;
- average_vc_load.resize(m_virtual_networks*m_vcs_per_vnet);
+ BaseGarnetNetwork::regStats();
+ regLinkStats();
+ regPowerStats();
+}
- for (int i = 0; i < m_virtual_networks*m_vcs_per_vnet; i++) {
- average_vc_load[i] = 0;
- }
+void
+GarnetNetwork_d::regLinkStats()
+{
+ m_average_link_utilization.name(name() + ".avg_link_utilization");
+
+ 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();
+}
- out << endl;
+void
+GarnetNetwork_d::collateLinkStats()
+{
for (int i = 0; i < m_links.size(); i++) {
- average_link_utilization +=
+ m_average_link_utilization +=
(double(m_links[i]->getLinkUtilization())) /
(double(curCycle() - g_ruby_start));
- vector<int> vc_load = m_links[i]->getVcLoad();
+ vector<unsigned 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];
+ m_average_vc_load[j] +=
+ ((double)vc_load[j] / (double)(curCycle() - g_ruby_start));
}
}
- 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
-GarnetNetwork_d::printPowerStats(ostream& out) const
+GarnetNetwork_d::collatePowerStats()
{
- out << "Network Power" << endl;
- 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;
-
for (int i = 0; i < m_links.size(); i++) {
- m_total_link_power += m_links[i]->calculate_power();
+ m_links[i]->calculate_power();
m_dynamic_link_power += m_links[i]->get_dynamic_power();
m_static_link_power += m_links[i]->get_static_power();
}
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_static_router_power += m_routers[i]->get_static_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
int getBuffersPerDataVC() {return m_buffers_per_data_vc; }
int getBuffersPerCtrlVC() {return m_buffers_per_ctrl_vc; }
- void printLinkStats(std::ostream& out) const;
- void printPowerStats(std::ostream& out) const;
+ void collateStats();
+ void regStats();
void print(std::ostream& out) const;
VNET_type
GarnetNetwork_d(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<Router_d *> m_routers; // All Routers in Network
int m_buffers_per_data_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&
m_credit_link = credit_link;
}
- inline double
- get_buf_read_count(int vnet)
- {
- return m_num_buffer_reads[vnet];
- }
-
- inline double
- get_buf_write_count(int vnet)
- {
- return m_num_buffer_writes[vnet];
- }
+ double get_buf_read_count(unsigned int vnet) const
+ { return m_num_buffer_reads[vnet]; }
+ double get_buf_write_count(unsigned int vnet) const
+ { return m_num_buffer_writes[vnet]; }
uint32_t functionalWrite(Packet *pkt);
int m_id;
int m_num_vcs;
int m_vc_per_vnet;
- std::vector<double> m_num_buffer_writes;
- std::vector<double> m_num_buffer_reads;
Router_d *m_router;
NetworkLink_d *m_in_link;
// Virtual channels
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__
}
}
-std::vector<int>
-NetworkLink_d::getVcLoad()
-{
- return m_vc_load;
-}
-
-int
-NetworkLink_d::getLinkUtilization()
-{
- return m_link_utilized;
-}
-
NetworkLink_d *
NetworkLink_dParams::create()
{
void setLinkConsumer(Consumer *consumer);
void setSourceQueue(flitBuffer_d *srcQueue);
void print(std::ostream& out) const{}
- int getLinkUtilization();
- std::vector<int> getVcLoad();
int get_id(){return m_id;}
- double get_dynamic_power(){return m_power_dyn;}
- double get_static_power(){return m_power_sta;}
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)
{ return linkBuffer->isReady(curTime); }
void init_net_ptr(GarnetNetwork_d* net_ptr) { m_net_ptr = net_ptr; }
uint32_t functionalWrite(Packet *);
- protected:
+ private:
int m_id;
Cycles m_latency;
int channel_width;
flitBuffer_d *linkBuffer;
Consumer *link_consumer;
flitBuffer_d *link_srcQueue;
- int m_link_utilized;
- std::vector<int> m_vc_load;
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_sta;
};
for (int fault_type_index = 0; fault_type_index < num_fault_types;
fault_type_index++){
out << " - probability of (";
- out <<
+ out <<
m_network_ptr->fault_model->fault_type_to_string(fault_type_index);
out << ") = ";
out << fault_vector[fault_type_index] << endl;
{
int temperature_celcius = BASELINE_TEMPERATURE_CELCIUS;
float aggregate_fault_prob;
- get_aggregate_fault_probability(temperature_celcius,
+ get_aggregate_fault_probability(temperature_celcius,
&aggregate_fault_prob);
out << "Router-" << m_id << " fault probability: ";
out << aggregate_fault_prob << endl;
void printFaultVector(std::ostream& out);
void printAggregateFaultProbability(std::ostream& out);
- double calculate_power();
+ void calculate_power();
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[]){
return m_network_ptr->fault_model->fault_vector(m_id, temperature,
fault_vector);
private:
int m_virtual_networks, m_num_vcs, m_vc_per_vnet;
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 crossbar_count;
SWallocator_d *m_sw_alloc;
Switch_d *m_switch;
+ // Statistical variables for power
double m_power_dyn;
double m_power_sta;
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__
bool is_invc_candidate(int inport_iter, int invc_iter);
void select_outvc(int inport_iter, int invc_iter);
- inline double
- get_local_arbit_count(int vnet)
- {
- return m_local_arbiter_activity[vnet];
- }
-
- inline double
- get_global_arbit_count(int vnet)
- {
- return m_global_arbiter_activity[vnet];
- }
+ double get_local_arbit_count(unsigned int vnet) const
+ { return m_local_arbiter_activity[vnet]; }
+
+ double get_global_arbit_count(unsigned int vnet) const
+ { return m_global_arbiter_activity[vnet]; }
private:
int m_num_vcs, m_vc_per_vnet;
int m_num_inports;
int m_num_outports;
- std::vector<double > m_local_arbiter_activity;
- std::vector<double > m_global_arbiter_activity;
-
Router_d *m_router;
// First stage of arbitration
std::vector<InputUnit_d *> m_input_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__
}
void
-GarnetNetwork::printLinkStats(ostream& out) const
+GarnetNetwork::regStats()
{
- double average_link_utilization = 0;
- 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++) {
- average_vc_load[i] = 0;
+ BaseGarnetNetwork::regStats();
+
+ m_average_link_utilization.name(name() + ".avg_link_utilization");
+
+ 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;
+void
+GarnetNetwork::collateStats()
+{
for (int i = 0; i < m_links.size(); i++) {
- average_link_utilization +=
+ m_average_link_utilization +=
(double(m_links[i]->getLinkUtilization())) /
(double(curCycle() - g_ruby_start));
- vector<int> vc_load = m_links[i]->getVcLoad();
+ vector<unsigned 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];
+ m_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
-GarnetNetwork::printPowerStats(ostream& out) const
-{
- out << "Network Power" << endl;
- out << "-------------" << endl;
- out << "Orion does not work with flexible pipeline" << endl;
- out << endl;
}
void
int getBufferSize() { return m_buffer_size; }
int getNumPipeStages() {return m_number_of_pipe_stages; }
-
int getNumNodes(){ return m_nodes; }
- void printLinkStats(std::ostream& out) const;
- void printPowerStats(std::ostream& out) const;
+ void collateStats();
+ void regStats();
void print(std::ostream& out) const;
// Methods used by Topology to setup the network
int m_buffer_size;
int m_number_of_pipe_stages;
+
+ // Statistical variables
+ Stats::Scalar m_average_link_utilization;
+ Stats::Vector m_average_vc_load;
};
inline std::ostream&
m_link_utilized = 0;
m_latency = p->link_latency;
m_id = p->link_id;
+
int num_net = p->virt_nets;
int num_vc = p->vcs_per_vnet;
m_vc_load.resize(num_net * num_vc);
delete linkBuffer;
}
-int
-NetworkLink::get_id()
-{
- return m_id;
-}
-
void
NetworkLink::setLinkConsumer(FlexibleConsumer *consumer)
{
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
NetworkLink::isReady()
{
bool is_vc_ready(flit *t_flit);
- int get_id();
+ int get_id() const { return m_id; }
void setInPort(int port);
void setOutPort(int port);
void wakeup();
void request_vc_link(int vc, NetDest destination, Cycles request_time);
bool isBufferNotFull_link(int vc);
void setSource(FlexibleConsumer *source);
- double getLinkUtilization();
- std::vector<int> getVcLoad();
+ void init_net_ptr(GarnetNetwork* net_ptr) { m_net_ptr = net_ptr; }
- void init_net_ptr(GarnetNetwork* net_ptr)
- {
- m_net_ptr = net_ptr;
- }
+ unsigned int getLinkUtilization() const { return m_link_utilized; }
+ const std::vector<unsigned int> & getVcLoad() const { return m_vc_load; }
bool functionalRead(Packet *);
uint32_t functionalWrite(Packet *);
- protected:
+ private:
int m_id;
Cycles m_latency;
int m_in_port, m_out_port;
- int m_link_utilized;
- std::vector<int> m_vc_load;
GarnetNetwork *m_net_ptr;
flitBuffer *linkBuffer;
FlexibleConsumer *link_consumer;
FlexibleConsumer *link_source;
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__
#include "mem/ruby/network/orion/OrionLink.hh"
#include "mem/ruby/network/orion/OrionRouter.hh"
-double
+void
Router_d::calculate_power()
{
//Network Activities from garnet
uint32_t in_buf_per_data_vc = m_network_ptr->getBuffersPerDataVC();
uint32_t in_buf_per_ctrl_vc = m_network_ptr->getBuffersPerCtrlVC();
//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(
num_in_port,
double Psw_arb_local_dyn = 0.0;
double Psw_arb_global_dyn = 0.0;
double Pxbar_dyn = 0.0;
- double Ptotal_dyn = 0.0;
double Pbuf_sta = 0.0;
double Pvc_arb_sta = 0.0;
double Psw_arb_sta = 0.0;
double Pxbar_sta = 0.0;
- double Ptotal_sta = 0.0;
-
- double Ptotal = 0.0;
-
//Dynamic Power
(crossbar_count/sim_cycles)*freq_Hz;
// Total
- Ptotal_dyn = Pbuf_wr_dyn + Pbuf_rd_dyn +
- Pvc_arb_local_dyn + Pvc_arb_global_dyn +
- Psw_arb_local_dyn + Psw_arb_global_dyn +
- Pxbar_dyn;
+ m_power_dyn = Pbuf_wr_dyn + Pbuf_rd_dyn +
+ Pvc_arb_local_dyn + Pvc_arb_global_dyn +
+ Psw_arb_local_dyn + Psw_arb_global_dyn +
+ Pxbar_dyn;
- m_power_dyn = Ptotal_dyn;
-
// Clock Power
m_clk_power = orion_rtr_ptr->calc_dynamic_energy_clock()*freq_Hz;
Psw_arb_sta = orion_rtr_ptr->get_static_power_sa();
Pxbar_sta = orion_rtr_ptr->get_static_power_xbar();
- Ptotal_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;
+ m_power_sta = Pbuf_sta + Pvc_arb_sta + Psw_arb_sta + Pxbar_sta;
}
-double
+void
NetworkLink_d::calculate_power()
{
OrionConfig* orion_cfg_ptr;
// Dynamic Power
// Assume half the bits flipped on every link activity
- double Plink_dyn =
- orion_link_ptr->calc_dynamic_energy(channel_width_bits/2)*
- (m_link_utilized/ sim_cycles)*freq_Hz;
+ double link_dynamic_energy =
+ orion_link_ptr->calc_dynamic_energy(channel_width_bits/2);
+ m_power_dyn = link_dynamic_energy * (m_link_utilized / sim_cycles) *
+ freq_Hz;
- m_power_dyn = Plink_dyn;
// 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
- double Plink_sta = orion_link_ptr->get_static_power();
-
- m_power_sta = Plink_sta;
-
- double Ptotal = m_power_dyn + m_power_sta;
+ m_power_sta = orion_link_ptr->get_static_power();
- return Ptotal;
+ delete orion_link_ptr;
+ delete orion_cfg_ptr;
}
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()
{
}
}
void
-PerfectSwitch::printStats(std::ostream& out) const
+PerfectSwitch::clearStats()
{
- out << "PerfectSwitch printStats" << endl;
}
-
void
-PerfectSwitch::clearStats()
+PerfectSwitch::collateStats()
{
}
+
void
PerfectSwitch::print(std::ostream& out) const
{
void init(SimpleNetwork *);
void addInPort(const std::vector<MessageBuffer*>& in);
void addOutPort(const std::vector<MessageBuffer*>& out,
- const NetDest& routing_table_entry);
- void clearRoutingTables();
- void clearBuffers();
- void reconfigureOutPort(const NetDest& routing_table_entry);
+ const NetDest& routing_table_entry);
int getInLinks() const { return m_in.size(); }
int getOutLinks() const { return m_out.size(); }
void wakeup();
void storeEventInfo(int info);
- void printStats(std::ostream& out) const;
void clearStats();
+ void collateStats();
void print(std::ostream& out) const;
private:
}
void
-SimpleNetwork::printStats(ostream& out) const
+SimpleNetwork::regStats()
{
- out << endl;
- out << "Network Stats" << endl;
- out << "-------------" << endl;
- out << endl;
-
- //
- // Determine total counts before printing out each switch's stats
- //
- std::vector<uint64> total_msg_counts;
- total_msg_counts.resize(MessageSizeType_NUM);
- for (MessageSizeType type = MessageSizeType_FIRST;
- type < MessageSizeType_NUM;
- ++type) {
- total_msg_counts[type] = 0;
- }
-
- 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];
- int sum = accumulate(mct.begin(), mct.end(), 0);
- total_msg_counts[type] += uint64(sum);
- }
- }
- }
- uint64 total_msgs = 0;
- uint64 total_bytes = 0;
- for (MessageSizeType type = MessageSizeType_FIRST;
- 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));
+ m_msg_counts.resize(MessageSizeType_NUM);
+ m_msg_bytes.resize(MessageSizeType_NUM);
+
+ for (MessageSizeType type = MessageSizeType_FIRST;
+ type < MessageSizeType_NUM; ++type) {
+ m_msg_counts[(unsigned int) type]
+ .name(name() + ".msg_count." + MessageSizeType_to_string(type))
+ .flags(Stats::nozero)
+ ;
+ m_msg_bytes[(unsigned int) type]
+ .name(name() + ".msg_byte." + MessageSizeType_to_string(type))
+ .flags(Stats::nozero)
+ ;
+
+ // Now state what the formula is.
+ for (int i = 0; i < m_switches.size(); i++) {
+ m_msg_counts[(unsigned int) type] +=
+ sum(m_switches[i]->getMsgCount(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);
+
+ m_msg_bytes[(unsigned int) type] =
+ m_msg_counts[(unsigned int) type] * Stats::constant(
+ Network::MessageSizeType_to_int(type));
}
}
void
-SimpleNetwork::clearStats()
+SimpleNetwork::collateStats()
{
for (int i = 0; i < m_switches.size(); i++) {
- m_switches[i]->clearStats();
+ m_switches[i]->collateStats();
}
}
int getEndpointBandwidth() { return m_endpoint_bandwidth; }
bool getAdaptiveRouting() {return m_adaptive_routing; }
- void printStats(std::ostream& out) const;
- void clearStats();
+ void collateStats();
+ void regStats();
// returns the queue requested for the given component
MessageBuffer* getToNetQueue(NodeID id, bool ordered, int network_num, std::string vnet_type);
void addLink(SwitchID src, SwitchID dest, int link_latency);
void makeLink(SwitchID src, SwitchID dest,
const NetDest& routing_table_entry, int link_latency);
- SwitchID createSwitch();
void makeTopology();
- void linkTopology();
// Private copy constructor and assignment operator
SimpleNetwork(const SimpleNetwork& obj);
int m_buffer_size;
int m_endpoint_bandwidth;
bool m_adaptive_routing;
+
+ //Statistical variables
+ std::vector<Stats::Formula> m_msg_counts;
+ std::vector<Stats::Formula> m_msg_bytes;
};
inline std::ostream&
Switch::Switch(const Params *p) : BasicRouter(p)
{
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()
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*
Switch::getThrottle(LinkID link_number) const
{
}
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++) {
- Throttle* throttle_ptr = m_throttles[link];
- 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;
- }
+ m_throttles[link]->regStats(name());
}
- out << endl;
-
- // Traffic breakdown
- for (int link = 0; link < m_throttles.size(); link++) {
- Throttle* throttle_ptr = m_throttles[link];
- if (!throttle_ptr)
- continue;
- const vector<vector<int> >& message_counts =
- throttle_ptr->getCounters();
- for (int int_type = 0; int_type < MessageSizeType_NUM; int_type++) {
- MessageSizeType type = MessageSizeType(int_type);
- const vector<int> &mct = message_counts[type];
- int sum = accumulate(mct.begin(), mct.end(), 0);
- if (sum == 0)
- continue;
-
- out << " outgoing_messages_switch_" << m_id
- << "_link_" << link << "_" << type << ": " << sum << " "
- << sum * m_network_ptr->MessageSizeType_to_int(type)
- << " ";
- out << mct;
- out << " base_latency: "
- << throttle_ptr->getLatency() << endl;
+ m_avg_utilization.name(name() + ".percent_links_utilized");
+ for (unsigned int i = 0; i < m_throttles.size(); i++) {
+ m_avg_utilization += m_throttles[i]->getUtilization();
+ }
+ m_avg_utilization /= Stats::constant(m_throttles.size());
+
+ for (unsigned int type = MessageSizeType_FIRST;
+ type < MessageSizeType_NUM; ++type) {
+ m_msg_counts[type]
+ .name(name() + ".msg_count." +
+ MessageSizeType_to_string(MessageSizeType(type)))
+ .flags(Stats::nozero)
+ ;
+ m_msg_bytes[type]
+ .name(name() + ".msg_bytes." +
+ MessageSizeType_to_string(MessageSizeType(type)))
+ .flags(Stats::nozero)
+ ;
+
+ for (unsigned int i = 0; i < m_throttles.size(); i++) {
+ m_msg_counts[type] += m_throttles[i]->getMsgCount(type);
}
+ m_msg_bytes[type] = m_msg_counts[type] * Stats::constant(
+ Network::MessageSizeType_to_int(MessageSizeType(type)));
}
- out << endl;
}
void
-Switch::clearStats()
+Switch::resetStats()
{
m_perfect_switch->clearStats();
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();
}
}
int bw_multiplier);
const Throttle* getThrottle(LinkID link_number) 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 clearStats();
+ void resetStats();
+ void collateStats();
+ void regStats();
+ const Stats::Formula & getMsgCount(unsigned int type) const
+ { return m_msg_counts[type]; }
+
void print(std::ostream& out) const;
void init_net_ptr(SimpleNetwork* net_ptr) { m_network_ptr = net_ptr; }
SimpleNetwork* m_network_ptr;
std::vector<Throttle*> m_throttles;
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&
m_endpoint_bandwidth = endpoint_bandwidth;
m_wakeups_wo_switch = 0;
- clearStats();
-}
-void
-Throttle::clear()
-{
- for (int counter = 0; counter < m_vnets; counter++) {
- m_in[counter]->clear();
- m_out[counter]->clear();
- }
+ m_msg_counts.resize(MessageSizeType_NUM);
+ m_msg_bytes.resize(MessageSizeType_NUM);
+
+ m_link_utilization_proxy = 0;
}
void
for (int i=0; i<in_vec.size(); 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
m_in[vnet]->pop();
// 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]);
}
double ratio = 1.0 - (double(bw_remaining) / double(getLinkBandwidth()));
// 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) {
// We have extra bandwidth and our output buffer was
}
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
Throttle::clearStats()
{
- m_ruby_start = g_system_ptr->curCycle();
- 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;
- }
- }
+ m_link_utilization_proxy = 0;
}
-double
-Throttle::getUtilization() const
+void
+Throttle::collateStats()
{
- return 100.0 * double(m_links_utilized) /
- double(g_system_ptr->curCycle()-m_ruby_start);
+ m_link_utilization = 100.0 * m_link_utilization_proxy
+ / (double(g_system_ptr->curCycle() - g_ruby_start));
}
void
{ return csprintf("Throttle-%i", m_sID); }
void addLinks(const std::vector<MessageBuffer*>& in_vec,
- const std::vector<MessageBuffer*>& out_vec);
+ const std::vector<MessageBuffer*>& out_vec);
void wakeup();
- void printStats(std::ostream& out) const;
- void clearStats();
- // The average utilization (a percent) since last clearStats()
- double getUtilization() const;
+ // The average utilization (a fraction) since last clearStats()
+ const Stats::Scalar & getUtilization() const
+ { return m_link_utilization; }
+ const Stats::Vector & getMsgCount(unsigned int type) const
+ { return m_msg_counts[type]; }
+
int getLinkBandwidth() const
{ return m_endpoint_bandwidth * m_link_bandwidth_multiplier; }
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;
private:
void init(NodeID node, Cycles link_latency, int link_bandwidth_multiplier,
int endpoint_bandwidth);
void addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr);
- void linkUtilized(double ratio) { m_links_utilized += ratio; }
// Private copy constructor and assignment operator
Throttle(const Throttle& obj);
std::vector<MessageBuffer*> m_in;
std::vector<MessageBuffer*> m_out;
- std::vector<std::vector<int> > m_message_counters;
- int m_vnets;
+ unsigned int m_vnets;
std::vector<int> m_units_remaining;
int m_sID;
NodeID m_node;
int m_wakeups_wo_switch;
int m_endpoint_bandwidth;
- // For tracking utilization
- Cycles m_ruby_start;
- double m_links_utilized;
+ // Statistical variables
+ Stats::Scalar m_link_utilization;
+ std::vector<Stats::Vector> m_msg_counts;
+ std::vector<Stats::Formula> m_msg_bytes;
+
+ double m_link_utilization_proxy;
};
inline std::ostream&
tm *localTime = localtime(&T);
char buf[100];
strftime(buf, 100, "%b/%d/%Y %H:%M:%S", localTime);
-
out << "Real time: " << buf << endl;
m_profiler_ptr->printStats(out);
- m_network_ptr->printStats(out);
}
void
RubySystem::resetStats()
{
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();
}
void printStats(std::ostream& out);
void resetStats();
-
- uint64 getInstructionCount(int thread) { return 1; }
-
void print(std::ostream& out) const;
void serialize(std::ostream &os);