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

Change subject: mem-garnet: Allow simulataneous enqueue in case of multiple links
......................................................................

mem-garnet: Allow simulataneous enqueue in case of multiple links

HeteroGarnet allows multiple links connected to controllers.
But we did not support multiple enqueue leading to bottlenecks
after the flit reaches Network Interface. We should allow multiple
enqueue for disjoint links.

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



diff --git a/src/mem/ruby/network/garnet2.0/NetworkInterface.cc b/src/mem/ruby/network/garnet2.0/NetworkInterface.cc
index 5cb61d3..190aabe 100644
--- a/src/mem/ruby/network/garnet2.0/NetworkInterface.cc
+++ b/src/mem/ruby/network/garnet2.0/NetworkInterface.cc
@@ -219,7 +219,7 @@

     // Check if there are flits stalling a virtual channel. Track if a
     // message is enqueued to restrict ejection to one message per cycle.
-    bool messageEnqueuedThisCycle = checkStallQueue();
+    checkStallQueue();

     /*********** Check the incoming flit link **********/
     DPRINTF(RubyNetwork, "Number of input ports: %d\n", inPorts.size());
@@ -238,7 +238,7 @@
             // credits.
             if (t_flit->get_type() == TAIL_ ||
                 t_flit->get_type() == HEAD_TAIL_) {
-                if (!messageEnqueuedThisCycle &&
+                if (!iPort->messageEnqueuedThisCycle &&
                     outNode_ptr[vnet]->areNSlotsAvailable(1, curTime)) {
                     // Space is available. Enqueue to protocol buffer.
outNode_ptr[vnet]->enqueue(t_flit->get_msg_ptr(), curTime,
@@ -257,7 +257,7 @@
// set up a callback for when protocol buffer is dequeued. // Stat update and flit pointer deletion will occur upon
                     // unstall.
-                    m_stall_queue.push_back(t_flit);
+                    iPort->m_stall_queue.push_back(t_flit);
                     m_stall_count[vnet]++;

                     auto cb = std::bind(&NetworkInterface::dequeueCallback,
@@ -311,55 +311,56 @@
     checkReschedule();
 }

-bool
+void
 NetworkInterface::checkStallQueue()
 {
-    bool messageEnqueuedThisCycle = false;
-    Tick curTime = clockEdge();
+    // Check all stall queues.
+    // There is one stall queue for each input link
+    for (auto &iPort: inPorts) {
+        iPort->messageEnqueuedThisCycle = false;
+        Tick curTime = clockEdge();

-    if (!m_stall_queue.empty()) {
-        for (auto stallIter = m_stall_queue.begin();
-             stallIter != m_stall_queue.end(); ) {
-            flit *stallFlit = *stallIter;
-            int vnet = stallFlit->get_vnet();
+        if (!iPort->m_stall_queue.empty()) {
+            for (auto stallIter = iPort->m_stall_queue.begin();
+                 stallIter != iPort->m_stall_queue.end(); ) {
+                flit *stallFlit = *stallIter;
+                int vnet = stallFlit->get_vnet();

- // If we can now eject to the protocol buffer, send back credits
-            if (outNode_ptr[vnet]->areNSlotsAvailable(1, curTime)) {
- outNode_ptr[vnet]->enqueue(stallFlit->get_msg_ptr(), curTime,
-                                           cyclesToTicks(Cycles(1)));
+                // If we can now eject to the protocol buffer,
+                // send back credits
+                if (outNode_ptr[vnet]->areNSlotsAvailable(1,
+                    curTime)) {
+                    outNode_ptr[vnet]->enqueue(stallFlit->get_msg_ptr(),
+                        curTime, cyclesToTicks(Cycles(1)));

- // Send back a credit with free signal now that the VC is no
-                // longer stalled.
-                Credit *cFlit = new Credit(stallFlit->get_vc(), true,
-                                               curTick());
-                InputPort *iPort = getInportForVnet(vnet);
-                assert(iPort);
+                    // Send back a credit with free signal now that the
+                    // VC is no longer stalled.
+                    Credit *cFlit = new Credit(stallFlit->get_vc(), true,
+                                                   curTick());
+                    iPort->sendCredit(cFlit);

-                iPort->sendCredit(cFlit);
+                    // Update Stats
+                    incrementStats(stallFlit);

-                // Update Stats
-                incrementStats(stallFlit);
+ // Flit can now safely be deleted and removed from stall
+                    // queue
+                    delete stallFlit;
+                    iPort->m_stall_queue.erase(stallIter);
+                    m_stall_count[vnet]--;

-                // Flit can now safely be deleted and removed from stall
-                // queue
-                delete stallFlit;
-                m_stall_queue.erase(stallIter);
-                m_stall_count[vnet]--;
+ // If there are no more stalled messages for this vnet, the
+                    // callback on it's MessageBuffer is not needed.
+                    if (m_stall_count[vnet] == 0)
+                        outNode_ptr[vnet]->unregisterDequeueCallback();

-                // If there are no more stalled messages for this vnet, the
-                // callback on it's MessageBuffer is not needed.
-                if (m_stall_count[vnet] == 0)
-                    outNode_ptr[vnet]->unregisterDequeueCallback();
-
-                messageEnqueuedThisCycle = true;
-                break;
-            } else {
-                ++stallIter;
+                    iPort->messageEnqueuedThisCycle = true;
+                    break;
+                } else {
+                    ++stallIter;
+                }
             }
         }
     }
-
-    return messageEnqueuedThisCycle;
 }

 // Embed the protocol message into flits
diff --git a/src/mem/ruby/network/garnet2.0/NetworkInterface.hh b/src/mem/ruby/network/garnet2.0/NetworkInterface.hh
index 167c112..04fb2d8 100644
--- a/src/mem/ruby/network/garnet2.0/NetworkInterface.hh
+++ b/src/mem/ruby/network/garnet2.0/NetworkInterface.hh
@@ -238,6 +238,9 @@
                 return ss.str();
             }

+            // Queue for stalled flits
+            std::deque<flit *> m_stall_queue;
+            bool messageEnqueuedThisCycle;
         private:
             std::vector<int> _vnets;
             flitBuffer *_outCreditQueue;
@@ -259,8 +262,6 @@
     int m_deadlock_threshold;
     std::vector<OutVcState> outVcState;

-    // Queue for stalled flits
-    std::deque<flit *> m_stall_queue;
     std::vector<int> m_stall_count;

     // Input Flit Buffers
@@ -275,7 +276,7 @@
     // When a vc stays busy for a long time, it indicates a deadlock
     std::vector<int> vc_busy_counter;

-    bool checkStallQueue();
+    void checkStallQueue();
     bool flitisizeMessage(MsgPtr msg_ptr, int vnet);
     int calculateVC(int vnet);


--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/32305
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: Id2bc56eada85c620d3eed9b3cc05af5ab5c33903
Gerrit-Change-Number: 32305
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