Tiago Mück has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/31255 )

Change subject: mem-ruby: Allow same-cycle enqueue
......................................................................

mem-ruby: Allow same-cycle enqueue

Messages may be enqueued and be ready in the same cycle.

Using this feature may introduce nondeterminism in the protocol and
should be used in specific cases. A case study is to avoid needing an
additional cycle for internal protocol triggers (e.g. the All_Acks
event in src/mem/ruby/protocol/MOESI_CMP_directory-L2cache.sm).
To mitigate modeling mistakes, the 'allow_zero_latency' parameter must
be set for a MessageBuffer where this behavior is acceptable.

This changes also updates the Consumer to schedule events according to
this new behavior. The original implementation would not schedule a new
wakeup event if the wakeup for the Consumer had already been executed
in that cycle.

Additional authors:
- Tuan Ta <tuan....@arm.com>

Change-Id: Ib194e7b4b4ee4b06da1baea17c0eb743f650dfdd
Signed-off-by: Tiago Mück <tiago.m...@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/31255
Reviewed-by: Jason Lowe-Power <power...@gmail.com>
Maintainer: Jason Lowe-Power <power...@gmail.com>
Tested-by: kokoro <noreply+kok...@google.com>
---
M src/mem/ruby/common/Consumer.cc
M src/mem/ruby/common/Consumer.hh
M src/mem/ruby/network/MessageBuffer.cc
M src/mem/ruby/network/MessageBuffer.hh
M src/mem/ruby/network/MessageBuffer.py
5 files changed, 92 insertions(+), 29 deletions(-)

Approvals:
  Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/mem/ruby/common/Consumer.cc b/src/mem/ruby/common/Consumer.cc
index f68ee14..d5db717 100644
--- a/src/mem/ruby/common/Consumer.cc
+++ b/src/mem/ruby/common/Consumer.cc
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2020 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2012 Mark D. Hill and David A. Wood
  * All rights reserved.
  *
@@ -30,26 +42,51 @@

 using namespace std;

+Consumer::Consumer(ClockedObject *_em)
+    : m_wakeup_event([this]{ processCurrentEvent(); },
+                    "Consumer Event", false),
+      em(_em)
+{ }
+
 void
 Consumer::scheduleEvent(Cycles timeDelta)
 {
-    scheduleEventAbsolute(em->clockEdge(timeDelta));
+    m_wakeup_ticks.insert(em->clockEdge(timeDelta));
+    scheduleNextWakeup();
 }

 void
 Consumer::scheduleEventAbsolute(Tick evt_time)
 {
-    if (!alreadyScheduled(evt_time)) {
-        // This wakeup is not redundant
-        auto *evt = new EventFunctionWrapper(
-            [this]{ wakeup(); }, "Consumer Event", true);
+    m_wakeup_ticks.insert(
+        divCeil(evt_time, em->clockPeriod()) * em->clockPeriod());
+    scheduleNextWakeup();
+}

-        em->schedule(evt, evt_time);
-        insertScheduledWakeupTime(evt_time);
+void
+Consumer::scheduleNextWakeup()
+{
+    // look for the next tick in the future to schedule
+    auto it = m_wakeup_ticks.lower_bound(em->clockEdge());
+    if (it != m_wakeup_ticks.end()) {
+        Tick when = *it;
+        assert(when >= em->clockEdge());
+        if (m_wakeup_event.scheduled() && (when < m_wakeup_event.when()))
+            em->reschedule(m_wakeup_event, when, true);
+        else if (!m_wakeup_event.scheduled())
+            em->schedule(m_wakeup_event, when);
     }
+}

-    Tick t = em->clockEdge();
-    set<Tick>::iterator bit = m_scheduled_wakeups.begin();
-    set<Tick>::iterator eit = m_scheduled_wakeups.lower_bound(t);
-    m_scheduled_wakeups.erase(bit,eit);
+void
+Consumer::processCurrentEvent()
+{
+    auto curr = m_wakeup_ticks.begin();
+    assert(em->clockEdge() == *curr);
+
+ // remove the current tick from the wakeup list, wake up, and then schedule
+    // the next wakeup
+    m_wakeup_ticks.erase(curr);
+    wakeup();
+    scheduleNextWakeup();
 }
diff --git a/src/mem/ruby/common/Consumer.hh b/src/mem/ruby/common/Consumer.hh
index 2e18684..2c7065b 100644
--- a/src/mem/ruby/common/Consumer.hh
+++ b/src/mem/ruby/common/Consumer.hh
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2020 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
  * All rights reserved.
  *
@@ -43,10 +55,7 @@
 class Consumer
 {
   public:
-    Consumer(ClockedObject *_em)
-        : em(_em)
-    {
-    }
+    Consumer(ClockedObject *_em);

     virtual
     ~Consumer()
@@ -59,13 +68,7 @@
     bool
     alreadyScheduled(Tick time)
     {
-        return m_scheduled_wakeups.find(time) != m_scheduled_wakeups.end();
-    }
-
-    void
-    insertScheduledWakeupTime(Tick time)
-    {
-        m_scheduled_wakeups.insert(time);
+        return m_wakeup_ticks.find(time) != m_wakeup_ticks.end();
     }

     ClockedObject *
@@ -74,15 +77,19 @@
         return em;
     }

-
     void scheduleEventAbsolute(Tick timeAbs);
     void scheduleEvent(Cycles timeDelta);

   private:
-    std::set<Tick> m_scheduled_wakeups;
+    std::set<Tick> m_wakeup_ticks;
+    EventFunctionWrapper m_wakeup_event;
     ClockedObject *em;
+
+    void scheduleNextWakeup();
+    void processCurrentEvent();
 };

+
 inline std::ostream&
 operator<<(std::ostream& out, const Consumer& obj)
 {
diff --git a/src/mem/ruby/network/MessageBuffer.cc b/src/mem/ruby/network/MessageBuffer.cc
index fb1d734..8843694 100644
--- a/src/mem/ruby/network/MessageBuffer.cc
+++ b/src/mem/ruby/network/MessageBuffer.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 ARM Limited
+ * Copyright (c) 2019,2020 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -57,7 +57,8 @@
     m_max_size(p->buffer_size), m_time_last_time_size_checked(0),
     m_time_last_time_enqueue(0), m_time_last_time_pop(0),
     m_last_arrival_time(0), m_strict_fifo(p->ordered),
-    m_randomization(p->randomization)
+    m_randomization(p->randomization),
+    m_allow_zero_latency(p->allow_zero_latency)
 {
     m_msg_counter = 0;
     m_consumer = NULL;
@@ -172,7 +173,7 @@

     // Calculate the arrival time of the message, that is, the first
     // cycle the message can be dequeued.
-    assert(delta > 0);
+    assert((delta > 0) || m_allow_zero_latency);
     Tick arrival_time = 0;

// random delays are inserted if either RubySystem level randomization flag
@@ -193,7 +194,7 @@
     }

     // Check the arrival time
-    assert(arrival_time > current_time);
+    assert(arrival_time >= current_time);
     if (m_strict_fifo) {
         if (arrival_time < m_last_arrival_time) {
             panic("FIFO ordering violated: %s name: %s current time: %d "
diff --git a/src/mem/ruby/network/MessageBuffer.hh b/src/mem/ruby/network/MessageBuffer.hh
index 8abf3bd..3887340 100644
--- a/src/mem/ruby/network/MessageBuffer.hh
+++ b/src/mem/ruby/network/MessageBuffer.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 ARM Limited
+ * Copyright (c) 2019,2020 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -249,6 +249,7 @@
     int m_priority_rank;
     const bool m_strict_fifo;
     const bool m_randomization;
+    const bool m_allow_zero_latency;

     int m_input_link_id;
     int m_vnet_id;
diff --git a/src/mem/ruby/network/MessageBuffer.py b/src/mem/ruby/network/MessageBuffer.py
index a0a208f..297835f 100644
--- a/src/mem/ruby/network/MessageBuffer.py
+++ b/src/mem/ruby/network/MessageBuffer.py
@@ -1,3 +1,15 @@
+# Copyright (c) 2020 ARM Limited
+# All rights reserved.
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder.  You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
 # Copyright (c) 2015 Mark D. Hill and David A. Wood.
 # All rights reserved.
 #
@@ -39,6 +51,11 @@
                                        enqueue times (enforced to have \
                                        random delays if RubySystem \
                                        randomization flag is True)")
+ allow_zero_latency = Param.Bool(False, "Allows messages to be enqueued \ + with zero latency. This is useful \ + for internall trigger queues and \ + should not be used if this msg. \ + buffer connects different objects")

     out_port = RequestPort("Request port to MessageBuffer receiver")
     master = DeprecatedParam(out_port, '`master` is now called `out_port`')

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

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ib194e7b4b4ee4b06da1baea17c0eb743f650dfdd
Gerrit-Change-Number: 31255
Gerrit-PatchSet: 4
Gerrit-Owner: Tiago Mück <tiago.m...@arm.com>
Gerrit-Reviewer: Jason Lowe-Power <power...@gmail.com>
Gerrit-Reviewer: John Alsop <johnathan.al...@amd.com>
Gerrit-Reviewer: Tiago Mück <tiago.m...@arm.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
Gerrit-MessageType: merged
_______________________________________________
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