This patch makes garnet use the info about active and inactive vnets during allocatio...
authorTushar Krishna <tushar@csail.mit.edu>
Tue, 22 Mar 2011 02:51:59 +0000 (22:51 -0400)
committerTushar Krishna <tushar@csail.mit.edu>
Tue, 22 Mar 2011 02:51:59 +0000 (22:51 -0400)
src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc
src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh
src/mem/ruby/network/garnet/fixed-pipeline/SWallocator_d.cc
src/mem/ruby/network/garnet/fixed-pipeline/VCallocator_d.cc
src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc
src/mem/ruby/network/garnet/flexible-pipeline/Router.cc
src/mem/ruby/network/garnet/flexible-pipeline/Router.hh
src/mem/ruby/network/orion/NetworkPower.cc

index f0b8ccce7cb8ed124992fef036f7da530488b8a8..5cbff7db6872143b87909fbb06d9f898286443e4 100644 (file)
@@ -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]
index b6899ea6b8fcc3b51c04878479db2dd20b7985b4..f7af30ce98b58bac162832ab75e89336c070945f 100644 (file)
@@ -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(); }
index 72ea7524fb9591f25beebe39ce489de7a2f1f252..7041575891210289adf60b17b89a60774d87a9f5 100644 (file)
@@ -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
index 3cffda84cc7fb0f12665730636ebaec37ee4463f..326c7fa927d8656f68ef8dde411e6cd6e97727a6 100644 (file)
@@ -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
index 8280360c47a40cea397dc8160292ceedb4864672..205eb14725cf3820e7d42b136b741f9442da14c3 100644 (file)
@@ -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] <<
index fef6b00a180ebad9cb2d44b49002aac515e556d5..4a0d599732d2a4c46c48c1691e4d07e841e22c38 100644 (file)
@@ -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()
 {
index 20a4abd54da3089ecedf9e1dd5c10b99292cd857..8f240551ca1a27fb6b7bc44f0d2c8c9d61c795c6 100644 (file)
@@ -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;
index b71e09dcebe55ce5b733a315ba6b9fdcaea94fab..a28b8fd075957fb4ee3974e336cfd5d20c2388a8 100644 (file)
@@ -55,9 +55,10 @@ Router_d::calculate_power()
     std::vector<double > 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);
         }
     }