47#include "debug/RubyNetwork.hh"
85 int link_bandwidth_multiplier,
int endpoint_bandwidth,
100 for (
auto link_bandwidth_multiplier : vnet_bandwidth_multiplier){
104 for (
auto channels : vnet_channels){
115 assert(in_vec.size() == out_vec.size());
117 for (
int vnet = 0; vnet < in_vec.size(); ++vnet) {
122 m_in.push_back(in_ptr);
123 m_out.push_back(out_ptr);
127 std::string desc =
"[Queue to Throttle " +
167 bool &bw_saturated,
bool &output_blocked,
170 if (out ==
nullptr || in ==
nullptr) {
182 auto hasPendingWork = [&]{
return in->
isReady(current_time) ||
183 units_remaining > 0; };
184 while ((bw_remaining > 0) && hasPendingWork() &&
188 if (units_remaining == 0 && in->
isReady(current_time)) {
191 Message *net_msg_ptr = msg_ptr.get();
192 Tick msg_enqueue_time = msg_ptr->getLastEnqueueTime();
195 DPRINTF(RubyNetwork,
"throttle: %d my bw %d bw spent "
196 "enqueueing net msg %d time: %lld.\n",
202 out->
enqueue(msg_ptr, current_time,
211 uint32_t total_size =
218 current_time - msg_enqueue_time;
219 DPRINTF(RubyNetwork,
"%s\n", *out);
223 int spent = std::min(units_remaining, bw_remaining);
224 units_remaining -= spent;
225 bw_remaining -= spent;
226 total_bw_remaining -= spent;
236 if (hasPendingWork()) {
239 bw_saturated = bw_saturated || (bw_remaining == 0);
240 output_blocked = output_blocked ||
253 bool bw_saturated =
false;
254 bool output_blocked =
false;
257 bool iteration_direction =
false;
263 iteration_direction =
true;
266 if (iteration_direction) {
267 for (
int vnet = 0; vnet <
m_vnets; ++vnet) {
268 for (
int channel = 0; channel <
getChannelCnt(vnet); ++channel) {
270 bw_saturated, output_blocked,
275 for (
int vnet =
m_vnets-1; vnet >= 0; --vnet) {
276 for (
int channel = 0; channel <
getChannelCnt(vnet); ++channel) {
278 bw_saturated, output_blocked,
289 double ratio = 1.0 - (double(bw_remaining) /
298 if (bw_saturated || output_blocked) {
301 DPRINTF(RubyNetwork,
"%s scheduled again\n", *
this);
322 assert(net_msg_ptr != NULL);
341 "Average link utilization"),
343 "Total number of messages forwarded by this switch"),
345 "Total number of bytes forwarded by this switch"),
347 "Total number of data bytes forwarded by this switch"),
349 "Total time spend forwarding messages"),
351 "Total time spent blocked on any output link"),
353 "Total time bandwidth was saturated on any output link"),
355 "Average time a message took to be forwarded"),
357 "Average bandwidth (GB/s)"),
359 "Average useful (only data) bandwidth (GB/s)")
374 for (MessageSizeType type = MessageSizeType_FIRST;
375 type < MessageSizeType_NUM; ++type) {
378 csprintf(
"msg_count.%s", MessageSizeType_to_string(type)).c_str());
386 csprintf(
"msg_bytes.%s", MessageSizeType_to_string(type)).c_str());
Cycles is a wrapper class for representing cycle counts, i.e.
Consumer(ClockedObject *em, Event::Priority ev_prio=Event::Default_Pri)
void scheduleEvent(Cycles timeDelta)
void setConsumer(Consumer *consumer)
bool areNSlotsAvailable(unsigned int n, Tick curTime)
bool isReady(Tick current_time) const
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
void enqueue(MsgPtr message, Tick curTime, Tick delta, bool ruby_is_random, bool ruby_warmup, bool bypassStrictFIFO=false)
virtual const NetDest & getDestination() 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
Throttle(int sID, RubySystem *rs, NodeID node, Cycles link_latency, int endpoint_bandwidth, Switch *em, std::string link_name)
RubySystem * m_ruby_system
gem5::ruby::Throttle::ThrottleStats throttleStats
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
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 Arm Limited 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, std::string link_name)
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