Srikant Bharadwaj has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/32304 )

Change subject: mem-garnet: Fix scheduling of links in case of multiple physical links
......................................................................

mem-garnet: Fix scheduling of links in case of multiple physical links

Network Interface must be able to schedule flits in all physical
links in every cycle. Earlier implementation did not allow it.
This patch fixes to let NI schedule a flit for every link.
Each output port maintains its own round robin arbiter.

Change-Id: Ie41a2d03b0115f081d2cc5a5f9f1865eda88576e
---
M src/mem/ruby/network/garnet2.0/NetworkInterface.cc
M src/mem/ruby/network/garnet2.0/NetworkInterface.hh
2 files changed, 59 insertions(+), 38 deletions(-)



diff --git a/src/mem/ruby/network/garnet2.0/NetworkInterface.cc b/src/mem/ruby/network/garnet2.0/NetworkInterface.cc
index 85a161c..5cb61d3 100644
--- a/src/mem/ruby/network/garnet2.0/NetworkInterface.cc
+++ b/src/mem/ruby/network/garnet2.0/NetworkInterface.cc
@@ -48,7 +48,6 @@
   : ClockedObject(p), Consumer(this), m_id(p->id),
     m_virtual_networks(p->virt_nets), m_vc_per_vnet(0),
     m_vc_allocator(m_virtual_networks, 0),
-    m_vc_round_robin(0),
     m_deadlock_threshold(p->garnet_deadlock_threshold),
     vc_busy_counter(m_virtual_networks, 0)
 {
@@ -485,51 +484,59 @@
 void
 NetworkInterface::scheduleOutputLink()
 {
-    int vc = m_vc_round_robin;
+    // Schedule each output link
+    for (auto &oPort: outPorts) {
+        int vc = oPort->vcRoundRobin();

-    for (int i = 0; i < niOutVcs.size(); i++) {
-        vc++;
-        if (vc == niOutVcs.size())
-            vc = 0;
+        for (int i = 0; i < m_num_vcs; i++) {
+            vc++;
+            if (vc == m_num_vcs)
+                vc = 0;

-        // model buffer backpressure
-        if (niOutVcs[vc].isReady(curTick()) &&
-            outVcState[vc].has_credit()) {
-
-            bool is_candidate_vc = true;
             int t_vnet = get_vnet(vc);
-            int vc_base = t_vnet * m_vc_per_vnet;
+            if (oPort->isVnetSupported(t_vnet)) {
+                // model buffer backpressure
+                if (m_ni_out_vcs[vc]->isReady(curTick()) &&
+                    m_out_vc_state[vc]->has_credit()) {

-            if (m_net_ptr->isVNetOrdered(t_vnet)) {
-                for (int vc_offset = 0; vc_offset < m_vc_per_vnet;
-                     vc_offset++) {
-                    int t_vc = vc_base + vc_offset;
-                    if (niOutVcs[t_vc].isReady(curTick())) {
-                        if (m_ni_out_vcs_enqueue_time[t_vc] <
-                            m_ni_out_vcs_enqueue_time[vc]) {
-                            is_candidate_vc = false;
-                            break;
+                    bool is_candidate_vc = true;
+                    int vc_base = t_vnet * m_vc_per_vnet;
+
+                    if (m_net_ptr->isVNetOrdered(t_vnet)) {
+                        for (int vc_offset = 0; vc_offset < m_vc_per_vnet;
+                             vc_offset++) {
+                            int t_vc = vc_base + vc_offset;
+                            if (niOutVcs[t_vc].isReady(curTick())) {
+                                if (m_ni_out_vcs_enqueue_time[t_vc] <
+                                    m_ni_out_vcs_enqueue_time[vc]) {
+                                    is_candidate_vc = false;
+                                    break;
+                                }
+                            }
                         }
                     }
+                    if (!is_candidate_vc)
+                        continue;
+
+                    // Update the round robin arbiter
+                    oPort->vcRoundRobin(vc);
+
+                    outVcState[vc].decrement_credit();
+                    // Just removing the flit
+                    flit *t_flit = m_ni_out_vcs[vc]->getTopFlit();
+                    t_flit->set_time(clockEdge(Cycles(1)));
+                    scheduleFlit(t_flit);
+
+                    if (t_flit->get_type() == TAIL_ ||
+                       t_flit->get_type() == HEAD_TAIL_) {
+                        m_ni_out_vcs_enqueue_time[vc] = Tick(INFINITE_);
+                    }
+                    goto donePort;
                 }
             }
-            if (!is_candidate_vc)
-                continue;
-
-            m_vc_round_robin = vc;
-
-            outVcState[vc].decrement_credit();
-            // Just removing the flit
-            flit *t_flit = niOutVcs[vc].getTopFlit();
-            t_flit->set_time(clockEdge(Cycles(1)));
-            scheduleFlit(t_flit);
-
-            if (t_flit->get_type() == TAIL_ ||
-               t_flit->get_type() == HEAD_TAIL_) {
-                m_ni_out_vcs_enqueue_time[vc] = Tick(INFINITE_);
-            }
-            return;
         }
+donePort:
+        continue;
     }
 }

diff --git a/src/mem/ruby/network/garnet2.0/NetworkInterface.hh b/src/mem/ruby/network/garnet2.0/NetworkInterface.hh
index 1d3855a..167c112 100644
--- a/src/mem/ruby/network/garnet2.0/NetworkInterface.hh
+++ b/src/mem/ruby/network/garnet2.0/NetworkInterface.hh
@@ -96,6 +96,8 @@

                 _routerID = routerID;
                 _bitWidth = outLink->bitWidth;
+                _vcRoundRobin = 0;
+
             }

             flitBuffer *
@@ -149,6 +151,17 @@
                 return ss.str();
             }

+            int vcRoundRobin()
+            {
+                return _vcRoundRobin;
+            }
+
+            void vcRoundRobin(int vc)
+            {
+                _vcRoundRobin = vc;
+            }
+
+
         private:
             std::vector<int> _vnets;
             flitBuffer *_outFlitQueue;
@@ -156,6 +169,8 @@
             NetworkLink *_outNetLink;
             CreditLink *_inCreditLink;

+            int _vcRoundRobin; // For round robin scheduling
+
             int _routerID;
             uint32_t _bitWidth;
     };
@@ -239,7 +254,6 @@
     const int m_virtual_networks;
     int m_vc_per_vnet, m_num_vcs;
     std::vector<int> m_vc_allocator;
-    int m_vc_round_robin; // For round robin scheduling
     std::vector<OutputPort *> outPorts;
     std::vector<InputPort *> inPorts;
     int m_deadlock_threshold;

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/32304
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: feature-heterogarnet
Gerrit-Change-Id: Ie41a2d03b0115f081d2cc5a5f9f1865eda88576e
Gerrit-Change-Number: 32304
Gerrit-PatchSet: 1
Gerrit-Owner: Srikant Bharadwaj <srikant.bharad...@amd.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to