From 46cce440be4999cfdedebbf190c83570ba9f1b49 Mon Sep 17 00:00:00 2001 From: Tushar Krishna Date: Mon, 21 Mar 2011 22:51:59 -0400 Subject: This patch makes garnet use the info about active and inactive vnets during allocation and power estimations etc --- .../garnet/fixed-pipeline/GarnetNetwork_d.cc | 3 + .../ruby/network/garnet/fixed-pipeline/Router_d.hh | 1 + .../network/garnet/fixed-pipeline/SWallocator_d.cc | 66 +++++++++++++--------- .../network/garnet/fixed-pipeline/VCallocator_d.cc | 15 ++--- .../garnet/flexible-pipeline/GarnetNetwork.cc | 3 + .../network/garnet/flexible-pipeline/Router.cc | 41 ++++++++++++-- .../network/garnet/flexible-pipeline/Router.hh | 1 + src/mem/ruby/network/orion/NetworkPower.cc | 7 ++- 8 files changed, 93 insertions(+), 44 deletions(-) diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc index f0b8ccce7..5cbff7db6 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc @@ -300,6 +300,9 @@ GarnetNetwork_d::printStats(ostream& out) const out << "-------------" << endl; for (int i = 0; i < m_vcs_per_class*m_virtual_networks; i++) { + if (!m_in_use[i/m_vcs_per_class]) + continue; + average_vc_load[i] = (double(average_vc_load[i]) / (double(g_eventQueue_ptr->getTime()) - m_ruby_start)); out << "Average VC Load [" << i << "] = " << average_vc_load[i] diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh index b6899ea6b..f7af30ce9 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh +++ b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh @@ -62,6 +62,7 @@ class Router_d int link_weight, CreditLink_d *credit_link); int get_num_vcs() { return m_num_vcs; } + int get_num_vnets() { return m_virtual_networks; } int get_vc_per_vnet() { return m_vc_per_vnet; } int get_num_inports() { return m_input_unit.size(); } int get_num_outports() { return m_output_unit.size(); } diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/SWallocator_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/SWallocator_d.cc index 72ea7524f..704157589 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/SWallocator_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/SWallocator_d.cc @@ -90,14 +90,28 @@ SWallocator_d::arbitrate_inports() // First do round robin arbitration on a set of input vc requests for (int inport = 0; inport < m_num_inports; inport++) { int invc = m_round_robin_inport[inport]; - m_round_robin_inport[inport]++; - if (m_round_robin_inport[inport] >= m_num_vcs) - m_round_robin_inport[inport] = 0; - for (int j = 0; j < m_num_vcs; j++) { + // Select next round robin vc candidate within valid vnet + int next_round_robin_invc = invc; + do { + next_round_robin_invc++; + + if (next_round_robin_invc >= m_num_vcs) + next_round_robin_invc = 0; + } while (!((m_router->get_net_ptr())->validVirtualNetwork( + get_vnet(next_round_robin_invc)))); + + m_round_robin_inport[inport] = next_round_robin_invc; + + for (int invc_iter = 0; invc_iter < m_num_vcs; invc_iter++) { invc++; if (invc >= m_num_vcs) invc = 0; + + if (!((m_router->get_net_ptr())->validVirtualNetwork( + get_vnet(invc)))) + continue; + if (m_input_unit[inport]->need_stage(invc, ACTIVE_, SA_) && m_input_unit[inport]->has_credits(invc)) { if (is_candidate_inport(inport, invc)) { @@ -141,47 +155,47 @@ SWallocator_d::arbitrate_outports() // Now there are a set of input vc requests for output vcs. // Again do round robin arbitration on these requests for (int outport = 0; outport < m_num_outports; outport++) { - int in_port = m_round_robin_outport[outport]; + int inport = m_round_robin_outport[outport]; m_round_robin_outport[outport]++; if (m_round_robin_outport[outport] >= m_num_outports) m_round_robin_outport[outport] = 0; - for (int inport = 0; inport < m_num_inports; inport++) { - in_port++; - if (in_port >= m_num_inports) - in_port = 0; + for (int inport_iter = 0; inport_iter < m_num_inports; inport_iter++) { + inport++; + if (inport >= m_num_inports) + inport = 0; - // in_port has a request this cycle for outport: - if (m_port_req[outport][in_port]) { - m_port_req[outport][in_port] = false; - int invc = m_vc_winners[outport][in_port]; - int outvc = m_input_unit[in_port]->get_outvc(invc); + // inport has a request this cycle for outport: + if (m_port_req[outport][inport]) { + m_port_req[outport][inport] = false; + int invc = m_vc_winners[outport][inport]; + int outvc = m_input_unit[inport]->get_outvc(invc); // remove flit from Input Unit - flit_d *t_flit = m_input_unit[in_port]->getTopFlit(invc); + flit_d *t_flit = m_input_unit[inport]->getTopFlit(invc); t_flit->advance_stage(ST_); t_flit->set_vc(outvc); t_flit->set_outport(outport); t_flit->set_time(g_eventQueue_ptr->getTime() + 1); m_output_unit[outport]->decrement_credit(outvc); - m_router->update_sw_winner(in_port, t_flit); + m_router->update_sw_winner(inport, t_flit); m_global_arbiter_activity++; if ((t_flit->get_type() == TAIL_) || t_flit->get_type() == HEAD_TAIL_) { // Send a credit back // along with the information that this VC is now idle - m_input_unit[in_port]->increment_credit(invc, true); + m_input_unit[inport]->increment_credit(invc, true); // This Input VC should now be empty - assert(m_input_unit[in_port]->isReady(invc) == false); + assert(m_input_unit[inport]->isReady(invc) == false); - m_input_unit[in_port]->set_vc_state(IDLE_, invc); - m_input_unit[in_port]->set_enqueue_time(invc, INFINITE_); + m_input_unit[inport]->set_vc_state(IDLE_, invc); + m_input_unit[inport]->set_enqueue_time(invc, INFINITE_); } else { // Send a credit back // but do not indicate that the VC is idle - m_input_unit[in_port]->increment_credit(invc, false); + m_input_unit[inport]->increment_credit(invc, false); } break; // got a in request for this outport } @@ -205,13 +219,9 @@ SWallocator_d::check_for_wakeup() int SWallocator_d::get_vnet(int invc) { - for (int i = 0; i < RubySystem::getNetwork()->getNumberOfVirtualNetworks(); - i++) { - if (invc >= (i*m_vc_per_vnet) && invc < ((i+1)*m_vc_per_vnet)) { - return i; - } - } - fatal("Could not determine vc"); + int vnet = invc/m_vc_per_vnet; + assert(vnet < m_router->get_num_vnets()); + return vnet; } void diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/VCallocator_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/VCallocator_d.cc index 3cffda84c..326c7fa92 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/VCallocator_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/VCallocator_d.cc @@ -177,6 +177,10 @@ VCallocator_d::arbitrate_invcs() { for (int inport_iter = 0; inport_iter < m_num_inports; inport_iter++) { for (int invc_iter = 0; invc_iter < m_num_vcs; invc_iter++) { + if (!((m_router->get_net_ptr())->validVirtualNetwork( + get_vnet(invc_iter)))) + continue; + if (m_input_unit[inport_iter]->need_stage( invc_iter, VC_AB_, VA_)) { if (!is_invc_candidate(inport_iter, invc_iter)) @@ -240,13 +244,10 @@ VCallocator_d::arbitrate_outvcs() int VCallocator_d::get_vnet(int invc) { - for (int i = 0; i < RubySystem::getNetwork()->getNumberOfVirtualNetworks(); - i++) { - if (invc >= (i*m_vc_per_vnet) && invc < ((i+1)*m_vc_per_vnet)) { - return i; - } - } - fatal("Could not determine vc"); + int vnet = invc/m_vc_per_vnet; + assert(vnet < m_router->get_num_vnets()); + + return vnet; } void diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc index 8280360c4..205eb1472 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc +++ b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc @@ -260,6 +260,9 @@ GarnetNetwork::printStats(ostream& out) const out << "-------------" << endl; for (int i = 0; i < m_vcs_per_class*m_virtual_networks; i++) { + if (!m_in_use[i/m_vcs_per_class]) + continue; + average_vc_load[i] = (double(average_vc_load[i]) / (double(g_eventQueue_ptr->getTime()) - m_ruby_start)); out << "Average VC Load [" << i << "] = " << average_vc_load[i] << diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/Router.cc b/src/mem/ruby/network/garnet/flexible-pipeline/Router.cc index fef6b00a1..4a0d59973 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/Router.cc +++ b/src/mem/ruby/network/garnet/flexible-pipeline/Router.cc @@ -156,14 +156,27 @@ Router::vc_arbitrate() if (inport >= m_in_link.size()) inport = 0; int invc = m_round_robin_invc[inport]; - m_round_robin_invc[inport]++; - if (m_round_robin_invc[inport] >= m_num_vcs) - m_round_robin_invc[inport] = 0; + int next_round_robin_invc = invc; + do { + next_round_robin_invc++; + + if (next_round_robin_invc >= m_num_vcs) + next_round_robin_invc = 0; + + } while (!(m_net_ptr->validVirtualNetwork( + get_vnet(next_round_robin_invc)))); + + m_round_robin_invc[inport] = next_round_robin_invc; + for (int vc_iter = 0; vc_iter < m_num_vcs; vc_iter++) { invc++; if (invc >= m_num_vcs) invc = 0; + + if (!(m_net_ptr->validVirtualNetwork(get_vnet(invc)))) + continue; + InVcState *in_vc_state = m_in_vc_state[inport][invc]; if (in_vc_state->isInState(VC_AB_, g_eventQueue_ptr->getTime())) { @@ -330,9 +343,17 @@ Router::scheduleOutputLinks() { for (int port = 0; port < m_out_link.size(); port++) { int vc_tolookat = m_vc_round_robin[port]; - m_vc_round_robin[port]++; - if (m_vc_round_robin[port] == m_num_vcs) - m_vc_round_robin[port] = 0; + + int next_round_robin_vc_tolookat = vc_tolookat; + do { + next_round_robin_vc_tolookat++; + + if (next_round_robin_vc_tolookat == m_num_vcs) + next_round_robin_vc_tolookat = 0; + } while (!(m_net_ptr->validVirtualNetwork( + get_vnet(next_round_robin_vc_tolookat)))); + + m_vc_round_robin[port] = next_round_robin_vc_tolookat; for (int i = 0; i < m_num_vcs; i++) { vc_tolookat++; @@ -358,6 +379,14 @@ Router::scheduleOutputLinks() } } +int +Router::get_vnet(int vc) +{ + int vnet = vc/m_vc_per_vnet; + assert(vnet < m_virtual_networks); + return vnet; +} + void Router::checkReschedule() { diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/Router.hh b/src/mem/ruby/network/garnet/flexible-pipeline/Router.hh index 20a4abd54..8f240551c 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/Router.hh +++ b/src/mem/ruby/network/garnet/flexible-pipeline/Router.hh @@ -62,6 +62,7 @@ class Router : public FlexibleConsumer void grant_vc(int out_port, int vc, Time grant_time); void release_vc(int out_port, int vc, Time release_time); void vc_arbitrate(); + int get_vnet(int vc); void printConfig(std::ostream& out) const; void print(std::ostream& out) const; diff --git a/src/mem/ruby/network/orion/NetworkPower.cc b/src/mem/ruby/network/orion/NetworkPower.cc index b71e09dce..a28b8fd07 100644 --- a/src/mem/ruby/network/orion/NetworkPower.cc +++ b/src/mem/ruby/network/orion/NetworkPower.cc @@ -55,9 +55,10 @@ Router_d::calculate_power() std::vector buf_write_count_active; for (int i =0; i < m_virtual_networks; i++) { - if (vc_local_arbit_count[i] > 0) { + + active_vclass_ary[i] = (get_net_ptr())->validVirtualNetwork(i); + if (active_vclass_ary[i]) { num_active_vclass++; - active_vclass_ary[i] = true; vc_local_arbit_count_active.push_back(vc_local_arbit_count[i]); vc_global_arbit_count_active.push_back(vc_global_arbit_count[i]); buf_read_count_active.push_back(buf_read_count[i]); @@ -66,7 +67,7 @@ Router_d::calculate_power() else { // Inactive vclass assert(vc_global_arbit_count[i] == 0); - active_vclass_ary[i] = false; + assert(vc_local_arbit_count[i] == 0); } } -- cgit v1.2.3