Tiago Muck has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/41865 )

 (

4 is the latest approved patch-set.
No files were changed between the latest approved patch-set and the submitted one.
 )Change subject: mem-ruby: additional SimpleNetwork stats
......................................................................

mem-ruby: additional SimpleNetwork stats

Additional stats allow more detailed monitoring of switch bandwidth
and stalls.

Also cleaned up previous Throttle stats to match new stat API.

JIRA: https://gem5.atlassian.net/browse/GEM5-920

Change-Id: I56604f315024f19df5f89c6f6ea1e3aa0ea185ea
Signed-off-by: Tiago Mück <tiago.m...@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/41865
Reviewed-by: Meatboy 106 <garbage2collec...@gmail.com>
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/network/simple/Switch.cc
M src/mem/ruby/network/simple/Throttle.cc
M src/mem/ruby/network/simple/Throttle.hh
3 files changed, 126 insertions(+), 79 deletions(-)

Approvals:
Jason Lowe-Power: Looks good to me, but someone else must approve; Looks good to me, approved
  Meatboy 106: Looks good to me, approved
  kokoro: Regressions pass




diff --git a/src/mem/ruby/network/simple/Switch.cc b/src/mem/ruby/network/simple/Switch.cc
index a5fc6ed..c74246e 100644
--- a/src/mem/ruby/network/simple/Switch.cc
+++ b/src/mem/ruby/network/simple/Switch.cc
@@ -139,10 +139,6 @@
 {
     BasicRouter::regStats();

-    for (auto& throttle : throttles) {
-        throttle.regStats();
-    }
-
     for (const auto& throttle : throttles) {
         switchStats.m_avg_utilization += throttle.getUtilization();
     }
@@ -177,18 +173,12 @@
 Switch::resetStats()
 {
     perfectSwitch.clearStats();
-    for (auto& throttle : throttles) {
-        throttle.clearStats();
-    }
 }

 void
 Switch::collateStats()
 {
     perfectSwitch.collateStats();
-    for (auto& throttle : throttles) {
-        throttle.collateStats();
-    }
 }

 void
diff --git a/src/mem/ruby/network/simple/Throttle.cc b/src/mem/ruby/network/simple/Throttle.cc
index 1e530df..20cebcc 100644
--- a/src/mem/ruby/network/simple/Throttle.cc
+++ b/src/mem/ruby/network/simple/Throttle.cc
@@ -50,6 +50,7 @@
 #include "mem/ruby/network/simple/Switch.hh"
 #include "mem/ruby/slicc_interface/Message.hh"
 #include "mem/ruby/system/RubySystem.hh"
+#include "sim/stats.hh"

 namespace gem5
 {
@@ -77,7 +78,6 @@
     m_endpoint_bandwidth = endpoint_bandwidth;

     m_wakeups_wo_switch = 0;
-    m_link_utilization_proxy = 0;
 }

Throttle::Throttle(int sID, RubySystem *rs, NodeID node, Cycles link_latency,
@@ -163,7 +163,7 @@

 void
 Throttle::operateVnet(int vnet, int channel, int &total_bw_remaining,
-                      bool &schedule_wakeup,
+                      bool &bw_saturated, bool &output_blocked,
                       MessageBuffer *in, MessageBuffer *out)
 {
     if (out == nullptr || in == nullptr) {
@@ -188,6 +188,7 @@
             // Find the size of the message we are moving
             MsgPtr msg_ptr = in->peekMsgPtr();
             Message *net_msg_ptr = msg_ptr.get();
+            Tick msg_enqueue_time = msg_ptr->getLastEnqueueTime();
             units_remaining = network_message_to_size(net_msg_ptr);

             DPRINTF(RubyNetwork, "throttle: %d my bw %d bw spent "
@@ -202,7 +203,16 @@

             // Count the message
             (*(throttleStats.
-                m_msg_counts[net_msg_ptr->getMessageSize()]))[vnet]++;
+                msg_counts[net_msg_ptr->getMessageSize()]))[vnet]++;
+            throttleStats.total_msg_count += 1;
+            uint32_t total_size =
+ Network::MessageSizeType_to_int(net_msg_ptr->getMessageSize());
+            throttleStats.total_msg_bytes += total_size;
+            total_size -=
+                Network::MessageSizeType_to_int(MessageSizeType_Control);
+            throttleStats.total_data_msg_bytes += total_size;
+            throttleStats.total_msg_wait_time +=
+                current_time - msg_enqueue_time;
             DPRINTF(RubyNetwork, "%s\n", *out);
         }

@@ -217,14 +227,15 @@
     gem5_assert(bw_remaining >= 0);
     gem5_assert(total_bw_remaining >= 0);

-    // Make sure to continue work next cycle if
+    // Notify caller if
     //  - we ran out of bandwith and still have stuff to do
     //  - we had something to do but output queue was unavailable
     if (hasPendingWork()) {
         gem5_assert((bw_remaining == 0) ||
                     !out->areNSlotsAvailable(1, current_time));
-        DPRINTF(RubyNetwork, "vnet: %d set schedule_wakeup\n", vnet);
-        schedule_wakeup = true;
+        bw_saturated = bw_saturated || (bw_remaining == 0);
+        output_blocked = output_blocked ||
+            !out->areNSlotsAvailable(1, current_time);
     }
 }

@@ -236,7 +247,8 @@
     int bw_remaining = getTotalLinkBandwidth();

     m_wakeups_wo_switch++;
-    bool schedule_wakeup = false;
+    bool bw_saturated = false;
+    bool output_blocked = false;

     // variable for deciding the direction in which to iterate
     bool iteration_direction = false;
@@ -251,14 +263,16 @@
     if (iteration_direction) {
         for (int vnet = 0; vnet < m_vnets; ++vnet) {
for (int channel = 0; channel < getChannelCnt(vnet); ++channel) {
-                operateVnet(vnet, channel, bw_remaining, schedule_wakeup,
+                operateVnet(vnet, channel, bw_remaining,
+                            bw_saturated, output_blocked,
                             m_in[vnet], m_out[vnet]);
             }
         }
     } else {
         for (int vnet = m_vnets-1; vnet >= 0; --vnet) {
for (int channel = 0; channel < getChannelCnt(vnet); ++channel) {
-                operateVnet(vnet, channel, bw_remaining, schedule_wakeup,
+                operateVnet(vnet, channel, bw_remaining,
+                            bw_saturated, output_blocked,
                             m_in[vnet], m_out[vnet]);
             }
         }
@@ -273,58 +287,20 @@
                          double(getTotalLinkBandwidth()));

     // If ratio = 0, we used no bandwidth, if ratio = 1, we used all
-    m_link_utilization_proxy += ratio;
+    throttleStats.acc_link_utilization += ratio;

-    if (schedule_wakeup) {
+    if (bw_saturated) throttleStats.total_bw_sat_cy += 1;
+    if (output_blocked) throttleStats.total_stall_cy += 1;
+
+    if (bw_saturated || output_blocked) {
         // We are out of bandwidth for this cycle, so wakeup next
         // cycle and continue
+        DPRINTF(RubyNetwork, "%s scheduled again\n", *this);
         scheduleEvent(Cycles(1));
     }
 }

 void
-Throttle::regStats()
-{
-    for (MessageSizeType type = MessageSizeType_FIRST;
-         type < MessageSizeType_NUM; ++type) {
-        throttleStats.m_msg_counts[(unsigned int)type] =
-            new statistics::Vector(&throttleStats,
- csprintf("msg_count.%s", MessageSizeType_to_string(type)).c_str());
-        throttleStats.m_msg_counts[(unsigned int)type]
-            ->init(Network::getNumberOfVirtualNetworks())
-            .flags(statistics::nozero)
-            ;
-
-        throttleStats.m_msg_bytes[(unsigned int) type] =
-            new statistics::Formula(&throttleStats,
- csprintf("msg_bytes.%s", MessageSizeType_to_string(type)).c_str());
-        throttleStats.m_msg_bytes[(unsigned int) type]
-            ->flags(statistics::nozero)
-            ;
-
-        *(throttleStats.m_msg_bytes[(unsigned int) type]) =
-            *(throttleStats.m_msg_counts[type]) * statistics::constant(
-                Network::MessageSizeType_to_int(type));
-    }
-}
-
-void
-Throttle::clearStats()
-{
-    m_link_utilization_proxy = 0;
-}
-
-void
-Throttle::collateStats()
-{
-    double time_delta = double(m_ruby_system->curCycle() -
-                               m_ruby_system->getStartCycle());
-
-    throttleStats.m_link_utilization =
-        100.0 * m_link_utilization_proxy / time_delta;
-}
-
-void
 Throttle::print(std::ostream& out) const
 {
     ccprintf(out,  "[%i bw:", m_node);
@@ -353,11 +329,65 @@
 }

 Throttle::
-ThrottleStats::ThrottleStats(statistics::Group *parent, const NodeID &nodeID)
+ThrottleStats::ThrottleStats(Switch *parent, const NodeID &nodeID)
     : statistics::Group(parent, csprintf("throttle%02i", nodeID).c_str()),
-      m_link_utilization(this, "link_utilization")
+      ADD_STAT(acc_link_utilization, statistics::units::Count::get(),
+        "Accumulated link utilization"),
+      ADD_STAT(link_utilization, statistics::units::Ratio::get(),
+        "Average link utilization"),
+      ADD_STAT(total_msg_count, statistics::units::Count::get(),
+        "Total number of messages forwarded by this switch"),
+      ADD_STAT(total_msg_bytes, statistics::units::Byte::get(),
+        "Total number of bytes forwarded by this switch"),
+      ADD_STAT(total_data_msg_bytes, statistics::units::Byte::get(),
+        "Total number of data bytes forwarded by this switch"),
+      ADD_STAT(total_msg_wait_time, statistics::units::Tick::get(),
+        "Total time spend forwarding messages"),
+      ADD_STAT(total_stall_cy, statistics::units::Cycle::get(),
+        "Total time spent blocked on any output link"),
+      ADD_STAT(total_bw_sat_cy, statistics::units::Cycle::get(),
+        "Total time bandwidth was saturated on any output link"),
+      ADD_STAT(avg_msg_wait_time, statistics::units::Ratio::get(),
+        "Average time a message took to be forwarded"),
+      ADD_STAT(avg_bandwidth, statistics::units::Ratio::get(),
+        "Average bandwidth (GB/s)"),
+      ADD_STAT(avg_useful_bandwidth, statistics::units::Ratio::get(),
+        "Average usefull (only data) bandwidth (GB/s)")
 {
+    link_utilization = 100 * acc_link_utilization /
+                        (simTicks / parent->clockPeriod());

+    avg_msg_wait_time = total_msg_wait_time / total_msg_count;
+
+    avg_bandwidth.precision(2);
+    avg_bandwidth = (total_msg_bytes / simSeconds) /
+                      statistics::constant(1024*1024*1024);
+
+    avg_useful_bandwidth.precision(2);
+    avg_useful_bandwidth = (total_data_msg_bytes / simSeconds) /
+                             statistics::constant(1024*1024*1024);
+
+    for (MessageSizeType type = MessageSizeType_FIRST;
+         type < MessageSizeType_NUM; ++type) {
+        msg_counts[(unsigned int)type] =
+            new statistics::Vector(this,
+ csprintf("msg_count.%s", MessageSizeType_to_string(type)).c_str());
+        msg_counts[(unsigned int)type]
+            ->init(Network::getNumberOfVirtualNetworks())
+            .flags(statistics::nozero)
+            ;
+
+        msg_bytes[(unsigned int) type] =
+            new statistics::Formula(this,
+ csprintf("msg_bytes.%s", MessageSizeType_to_string(type)).c_str());
+        msg_bytes[(unsigned int) type]
+            ->flags(statistics::nozero)
+            ;
+
+        *(msg_bytes[(unsigned int) type]) =
+            *(msg_counts[type]) * statistics::constant(
+                Network::MessageSizeType_to_int(type));
+    }
 }

 } // namespace ruby
diff --git a/src/mem/ruby/network/simple/Throttle.hh b/src/mem/ruby/network/simple/Throttle.hh
index 1ec6d65..83454b7 100644
--- a/src/mem/ruby/network/simple/Throttle.hh
+++ b/src/mem/ruby/network/simple/Throttle.hh
@@ -90,10 +90,10 @@
     void wakeup();

     // The average utilization (a fraction) since last clearStats()
-    const statistics::Scalar & getUtilization() const
-    { return throttleStats.m_link_utilization; }
+    const statistics::Formula & getUtilization() const
+    { return throttleStats.link_utilization; }
     const statistics::Vector & getMsgCount(unsigned int type) const
-    { return *(throttleStats.m_msg_counts[type]); }
+    { return *(throttleStats.msg_counts[type]); }

     int getLinkBandwidth(int vnet) const;

@@ -103,16 +103,13 @@

     Cycles getLatency() const { return m_link_latency; }

-    void clearStats();
-    void collateStats();
-    void regStats();
     void print(std::ostream& out) const;

   private:
void init(NodeID node, Cycles link_latency, int link_bandwidth_multiplier,
               int endpoint_bandwidth);
     void operateVnet(int vnet, int channel, int &total_bw_remaining,
-                     bool &schedule_wakeup,
+                     bool &bw_saturated, bool &output_blocked,
                      MessageBuffer *in, MessageBuffer *out);

     // Private copy constructor and assignment operator
@@ -136,17 +133,25 @@
     int m_endpoint_bandwidth;
     RubySystem *m_ruby_system;

-    double m_link_utilization_proxy;
-
-
     struct ThrottleStats : public statistics::Group
     {
-        ThrottleStats(statistics::Group *parent, const NodeID &nodeID);
+        ThrottleStats(Switch *parent, const NodeID &nodeID);

         // Statistical variables
-        statistics::Scalar m_link_utilization;
-        statistics::Vector* m_msg_counts[MessageSizeType_NUM];
-        statistics::Formula* m_msg_bytes[MessageSizeType_NUM];
+        statistics::Scalar acc_link_utilization;
+        statistics::Formula link_utilization;
+        statistics::Vector* msg_counts[MessageSizeType_NUM];
+        statistics::Formula* msg_bytes[MessageSizeType_NUM];
+
+        statistics::Scalar total_msg_count;
+        statistics::Scalar total_msg_bytes;
+        statistics::Scalar total_data_msg_bytes;
+        statistics::Scalar total_msg_wait_time;
+        statistics::Scalar total_stall_cy;
+        statistics::Scalar total_bw_sat_cy;
+        statistics::Formula avg_msg_wait_time;
+        statistics::Formula avg_bandwidth;
+        statistics::Formula avg_useful_bandwidth;
     } throttleStats;
 };


--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/41865
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: I56604f315024f19df5f89c6f6ea1e3aa0ea185ea
Gerrit-Change-Number: 41865
Gerrit-PatchSet: 7
Gerrit-Owner: Tiago Muck <tiago.m...@arm.com>
Gerrit-Reviewer: Jason Lowe-Power <ja...@lowepower.com>
Gerrit-Reviewer: Jason Lowe-Power <power...@gmail.com>
Gerrit-Reviewer: Meatboy 106 <garbage2collec...@gmail.com>
Gerrit-Reviewer: Tiago Muck <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