47#include "debug/RubyNetwork.hh"
85 int link_bandwidth_multiplier,
int endpoint_bandwidth,
89 gem5_assert(link_bandwidth_multiplier > 0,
"Throttle::Throttle");
100 for (
auto link_bandwidth_multiplier : vnet_bandwidth_multiplier){
101 gem5_assert(link_bandwidth_multiplier > 0,
"Throttle::Throttle");
104 for (
auto channels : vnet_channels){
109 "Throttle::Throttle");
116 assert(in_vec.size() == out_vec.size());
118 for (
int vnet = 0; vnet < in_vec.size(); ++vnet) {
123 m_in.push_back(in_ptr);
124 m_out.push_back(out_ptr);
128 std::string desc =
"[Queue to Throttle " +
137 "Throttle::addLinks");
169 bool &bw_saturated,
bool &output_blocked,
172 if (out ==
nullptr || in ==
nullptr) {
178 gem5_assert(units_remaining >= 0,
"Throttle::operateVnet");
184 auto hasPendingWork = [&]{
return in->
isReady(current_time) ||
185 units_remaining > 0; };
186 while ((bw_remaining > 0) && hasPendingWork() &&
190 if (units_remaining == 0 && in->
isReady(current_time)) {
193 Message *net_msg_ptr = msg_ptr.get();
194 Tick msg_enqueue_time = msg_ptr->getLastEnqueueTime();
197 DPRINTF(RubyNetwork,
"throttle: %d my bw %d bw spent "
198 "enqueueing net msg %d time: %lld.\n",
204 out->
enqueue(msg_ptr, current_time,
213 uint32_t total_size =
220 current_time - msg_enqueue_time;
221 DPRINTF(RubyNetwork,
"%s\n", *out);
225 int spent = std::min(units_remaining, bw_remaining);
226 units_remaining -= spent;
227 bw_remaining -= spent;
228 total_bw_remaining -= spent;
231 gem5_assert(units_remaining >= 0,
"Throttle::operateVnet");
232 gem5_assert(bw_remaining >= 0,
"Throttle::operateVnet");
233 gem5_assert(total_bw_remaining >= 0,
"Throttle::operateVnet");
238 if (hasPendingWork()) {
241 "Throttle::operateVnet");
242 bw_saturated = bw_saturated || (bw_remaining == 0);
243 output_blocked = output_blocked ||
256 bool bw_saturated =
false;
257 bool output_blocked =
false;
260 bool iteration_direction =
false;
266 iteration_direction =
true;
269 if (iteration_direction) {
270 for (
int vnet = 0; vnet <
m_vnets; ++vnet) {
271 for (
int channel = 0; channel <
getChannelCnt(vnet); ++channel) {
273 bw_saturated, output_blocked,
278 for (
int vnet =
m_vnets-1; vnet >= 0; --vnet) {
279 for (
int channel = 0; channel <
getChannelCnt(vnet); ++channel) {
281 bw_saturated, output_blocked,
292 double ratio = 1.0 - (double(bw_remaining) /
301 if (bw_saturated || output_blocked) {
304 DPRINTF(RubyNetwork,
"%s scheduled again\n", *
this);
325 assert(net_msg_ptr != NULL);
344 "Average link utilization"),
346 "Total number of messages forwarded by this switch"),
348 "Total number of bytes forwarded by this switch"),
350 "Total number of data bytes forwarded by this switch"),
352 "Total time spend forwarding messages"),
354 "Total time spent blocked on any output link"),
356 "Total time bandwidth was saturated on any output link"),
358 "Average time a message took to be forwarded"),
360 "Average bandwidth (GB/s)"),
362 "Average useful (only data) bandwidth (GB/s)")
377 for (MessageSizeType type = MessageSizeType_FIRST;
378 type < MessageSizeType_NUM; ++type) {
381 csprintf(
"msg_count.%s", MessageSizeType_to_string(type)).c_str());
389 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