47#include "debug/RubyNetwork.hh"
71 m_switch_id(sID), m_switch(
em), m_node(node),
72 m_physical_vnets(false), m_ruby_system(
rs),
73 throttleStats(
em, node)
84 int link_bandwidth_multiplier,
int endpoint_bandwidth,
86 :
Throttle(sID,
rs, node, link_latency, endpoint_bandwidth,
em)
96 :
Throttle(sID,
rs, node, link_latency, endpoint_bandwidth,
em)
99 for (
auto link_bandwidth_multiplier : vnet_bandwidth_multiplier){
103 for (
auto channels : vnet_channels){
114 assert(in_vec.size() == out_vec.size());
116 for (
int vnet = 0; vnet < in_vec.size(); ++vnet) {
121 m_in.push_back(in_ptr);
122 m_out.push_back(out_ptr);
126 std::string desc =
"[Queue to Throttle " +
166 bool &bw_saturated,
bool &output_blocked,
169 if (out ==
nullptr || in ==
nullptr) {
181 auto hasPendingWork = [&]{
return in->
isReady(current_time) ||
182 units_remaining > 0; };
183 while ((bw_remaining > 0) && hasPendingWork() &&
187 if (units_remaining == 0 && in->
isReady(current_time)) {
190 Message *net_msg_ptr = msg_ptr.get();
194 DPRINTF(RubyNetwork,
"throttle: %d my bw %d bw spent "
195 "enqueueing net msg %d time: %lld.\n",
201 out->
enqueue(msg_ptr, current_time,
208 uint32_t total_size =
215 current_time - msg_enqueue_time;
216 DPRINTF(RubyNetwork,
"%s\n", *out);
220 int spent = std::min(units_remaining, bw_remaining);
221 units_remaining -= spent;
222 bw_remaining -= spent;
223 total_bw_remaining -= spent;
233 if (hasPendingWork()) {
236 bw_saturated = bw_saturated || (bw_remaining == 0);
237 output_blocked = output_blocked ||
250 bool bw_saturated =
false;
251 bool output_blocked =
false;
254 bool iteration_direction =
false;
260 iteration_direction =
true;
263 if (iteration_direction) {
264 for (
int vnet = 0; vnet <
m_vnets; ++vnet) {
265 for (
int channel = 0; channel <
getChannelCnt(vnet); ++channel) {
267 bw_saturated, output_blocked,
272 for (
int vnet =
m_vnets-1; vnet >= 0; --vnet) {
273 for (
int channel = 0; channel <
getChannelCnt(vnet); ++channel) {
275 bw_saturated, output_blocked,
286 double ratio = 1.0 - (double(bw_remaining) /
295 if (bw_saturated || output_blocked) {
298 DPRINTF(RubyNetwork,
"%s scheduled again\n", *
this);
319 assert(net_msg_ptr != NULL);
333 : statistics::
Group(parent,
csprintf(
"throttle%02i", nodeID).c_str()),
334 ADD_STAT(acc_link_utilization, statistics::units::Count::get(),
335 "Accumulated link utilization"),
336 ADD_STAT(link_utilization, statistics::units::Ratio::get(),
337 "Average link utilization"),
338 ADD_STAT(total_msg_count, statistics::units::Count::get(),
339 "Total number of messages forwarded by this switch"),
340 ADD_STAT(total_msg_bytes, statistics::units::Byte::get(),
341 "Total number of bytes forwarded by this switch"),
342 ADD_STAT(total_data_msg_bytes, statistics::units::Byte::get(),
343 "Total number of data bytes forwarded by this switch"),
344 ADD_STAT(total_msg_wait_time, statistics::units::
Tick::get(),
345 "Total time spend forwarding messages"),
346 ADD_STAT(total_stall_cy, statistics::units::Cycle::get(),
347 "Total time spent blocked on any output link"),
348 ADD_STAT(total_bw_sat_cy, statistics::units::Cycle::get(),
349 "Total time bandwidth was saturated on any output link"),
350 ADD_STAT(avg_msg_wait_time, statistics::units::Ratio::get(),
351 "Average time a message took to be forwarded"),
352 ADD_STAT(avg_bandwidth, statistics::units::Ratio::get(),
353 "Average bandwidth (GB/s)"),
354 ADD_STAT(avg_useful_bandwidth, statistics::units::Ratio::get(),
355 "Average usefull (only data) bandwidth (GB/s)")
370 for (MessageSizeType
type = MessageSizeType_FIRST;
371 type < MessageSizeType_NUM; ++
type) {
374 csprintf(
"msg_count.%s", MessageSizeType_to_string(
type)).c_str());
382 csprintf(
"msg_bytes.%s", MessageSizeType_to_string(
type)).c_str());
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Tick cyclesToTicks(Cycles c) const
Cycles is a wrapper class for representing cycle counts, i.e.
void scheduleEvent(Cycles timeDelta)
void setConsumer(Consumer *consumer)
bool areNSlotsAvailable(unsigned int n, Tick curTime)
bool isReady(Tick current_time) const
void enqueue(MsgPtr message, Tick curTime, Tick delta, bool bypassStrictFIFO=false)
Tick dequeue(Tick current_time, bool decrement_messages=true)
Updates the delay cycles of the message at the head of the queue, removes it from the queue and retur...
const MsgPtr & peekMsgPtr() const
virtual const NetDest & getDestination() const
Tick getLastEnqueueTime() const
virtual const MessageSizeType & getMessageSize() const
static uint32_t getNumberOfVirtualNetworks()
static uint32_t MessageSizeType_to_int(MessageSizeType size_type)
std::vector< int > m_vnet_channels
std::vector< MessageBuffer * > m_in
void operateVnet(int vnet, int channel, int &total_bw_remaining, bool &bw_saturated, bool &output_blocked, MessageBuffer *in, MessageBuffer *out)
std::vector< std::vector< int > > m_units_remaining
void print(std::ostream &out) const
int getTotalLinkBandwidth() const
RubySystem * m_ruby_system
gem5::ruby::Throttle::ThrottleStats throttleStats
Throttle(int sID, RubySystem *rs, NodeID node, Cycles link_latency, int endpoint_bandwidth, Switch *em)
std::vector< MessageBuffer * > m_out
int getLinkBandwidth(int vnet) const
void addLinks(const std::vector< MessageBuffer * > &in_vec, const std::vector< MessageBuffer * > &out_vec)
std::vector< int > m_link_bandwidth_multiplier
int getChannelCnt(int vnet) const
Derived & precision(int _precision)
Set the precision and marks this stat to print at the end of simulation.
A vector of scalar stats.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
#define gem5_assert(cond,...)
The assert macro will function like a normal assert, but will use panic instead of straight abort().
std::shared_ptr< Message > MsgPtr
const int PRIORITY_SWITCH_LIMIT
const int MESSAGE_SIZE_MULTIPLIER
const int BROADCAST_SCALING
static int network_message_to_size(Message *net_msg_ptr)
const FlagsType init
This Stat is Initialized.
const FlagsType nozero
Don't print if this is zero.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
uint64_t Tick
Tick count type.
std::string csprintf(const char *format, const Args &...args)
statistics::Value & simTicks
statistics::Formula & simSeconds
void ccprintf(cp::Print &print)
statistics::Scalar total_msg_bytes
statistics::Formula avg_msg_wait_time
statistics::Formula link_utilization
statistics::Formula * msg_bytes[MessageSizeType_NUM]
statistics::Scalar total_msg_wait_time
statistics::Scalar total_data_msg_bytes
statistics::Scalar acc_link_utilization
ThrottleStats(Switch *parent, const NodeID &nodeID)
statistics::Formula avg_useful_bandwidth
statistics::Scalar total_msg_count
statistics::Formula avg_bandwidth
statistics::Vector * msg_counts[MessageSizeType_NUM]
statistics::Scalar total_stall_cy
statistics::Scalar total_bw_sat_cy