Tiago Mück has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/41865 )
Change subject: mem-ruby: additional SimpleNetwork stats
......................................................................
mem-ruby: additional SimpleNetwork stats
Additional stats allow more detailed monitoring of switch bandwidth
and stalls.
JIRA: https://gem5.atlassian.net/browse/GEM5-920
Change-Id: I56604f315024f19df5f89c6f6ea1e3aa0ea185ea
Signed-off-by: Tiago Mück <[email protected]>
---
M src/mem/ruby/network/simple/Throttle.cc
M src/mem/ruby/network/simple/Throttle.hh
2 files changed, 66 insertions(+), 14 deletions(-)
diff --git a/src/mem/ruby/network/simple/Throttle.cc
b/src/mem/ruby/network/simple/Throttle.cc
index f3dd82c..ed9b26f 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"
const int MESSAGE_SIZE_MULTIPLIER = 1000;
//const int BROADCAST_SCALING = 4; // Have a 16p system act like a 64p
systems
@@ -130,7 +131,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) {
@@ -158,6 +159,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 "
@@ -173,6 +175,15 @@
// Count the message
(*(throttleStats.
m_msg_counts[net_msg_ptr->getMessageSize()]))[vnet]++;
+ throttleStats.m_total_msg_count += 1;
+ uint32_t total_size =
+
Network::MessageSizeType_to_int(net_msg_ptr->getMessageSize());
+ throttleStats.m_total_msg_bytes += total_size;
+ total_size -=
+ Network::MessageSizeType_to_int(MessageSizeType_Control);
+ throttleStats.m_total_data_msg_bytes += total_size;
+ throttleStats.m_total_msg_wait_time +=
+ current_time - msg_enqueue_time;
DPRINTF(RubyNetwork, "%s\n", *out);
}
@@ -189,15 +200,14 @@
assert(bw_remaining >= 0);
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 (((bw_remaining == 0) &&
- (in->isReady(current_time) || (units_remaining > 0))) ||
- (ready && !out->areNSlotsAvailable(1, current_time))) {
- DPRINTF(RubyNetwork, "vnet: %d set schedule_wakeup\n", vnet);
- schedule_wakeup = true;
- }
+ bw_saturated = bw_saturated ||
+ ((bw_remaining == 0) &&
+ (in->isReady(current_time) || (units_remaining > 0)));
+ output_blocked = output_blocked ||
+ (ready && !out->areNSlotsAvailable(1, current_time));
}
void
@@ -208,7 +218,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;
@@ -223,13 +234,15 @@
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]);
}
}
@@ -245,7 +258,10 @@
// If ratio = 0, we used no bandwidth, if ratio = 1, we used all
m_link_utilization_proxy += ratio;
- if (!schedule_wakeup) {
+ if (bw_saturated) throttleStats.m_total_bw_sat_cy += 1;
+ if (output_blocked) throttleStats.m_total_stall_cy += 1;
+
+ if (!bw_saturated && !output_blocked) {
// We have extra bandwidth and our output buffer was
// available, so we must not have anything else to do until
// another message arrives.
@@ -332,7 +348,33 @@
Throttle::
ThrottleStats::ThrottleStats(Stats::Group *parent, const NodeID &nodeID)
: Stats::Group(parent, csprintf("throttle%02i", nodeID).c_str()),
- m_link_utilization(this, "link_utilization")
+ m_link_utilization(this, "link_utilization"),
+ m_total_msg_count(this, "total_msg_count",
+ "Total number of messages forwarded by this switch"),
+ m_total_msg_bytes(this, "total_msg_bytes",
+ "Total number of bytes forwarded by this switch"),
+ m_total_data_msg_bytes(this, "total_data_msg_bytes",
+ "Total number of data bytes forwarded by this switch"),
+ m_total_msg_wait_time(this, "total_msg_wait_time",
+ "Total time spend forwarding messages"),
+ m_total_stall_cy(this, "total_stall_cy",
+ "Total time spent blocked on any output link"),
+ m_total_bw_sat_cy(this, "total_bw_sat_cy",
+ "Total time bandwidth was saturated on any output link"),
+ m_avg_msg_wait_time(this, "avg_msg_wait_time",
+ "Average time a message took to be forwarded"),
+ m_avg_bandwidth(this, "avg_bandwidth",
+ "Average bandwidth (GB/s)"),
+ m_avg_useful_bandwidth(this, "avg_useful_bandwidth",
+ "Average usefull (only data) bandwidth (GB/s)")
{
+ m_avg_msg_wait_time = m_total_msg_wait_time / m_total_msg_count;
+ m_avg_bandwidth.precision(2);
+ m_avg_bandwidth = (m_total_msg_bytes / simSeconds) /
+ Stats::constant(1024*1024*1024);
+
+ m_avg_useful_bandwidth.precision(2);
+ m_avg_useful_bandwidth = (m_total_data_msg_bytes / simSeconds) /
+ Stats::constant(1024*1024*1024);
}
diff --git a/src/mem/ruby/network/simple/Throttle.hh
b/src/mem/ruby/network/simple/Throttle.hh
index 9b5cfe6..44da830 100644
--- a/src/mem/ruby/network/simple/Throttle.hh
+++ b/src/mem/ruby/network/simple/Throttle.hh
@@ -121,7 +121,7 @@
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
@@ -156,6 +156,16 @@
Stats::Scalar m_link_utilization;
Stats::Vector* m_msg_counts[MessageSizeType_NUM];
Stats::Formula* m_msg_bytes[MessageSizeType_NUM];
+
+ Stats::Scalar m_total_msg_count;
+ Stats::Scalar m_total_msg_bytes;
+ Stats::Scalar m_total_data_msg_bytes;
+ Stats::Scalar m_total_msg_wait_time;
+ Stats::Scalar m_total_stall_cy;
+ Stats::Scalar m_total_bw_sat_cy;
+ Stats::Formula m_avg_msg_wait_time;
+ Stats::Formula m_avg_bandwidth;
+ Stats::Formula m_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: 1
Gerrit-Owner: Tiago Mück <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s