1d0
<
30,37c29,30
< /*
< * $Id$
< *
< * Description: see Throttle.hh
< *
< */
<
< #include "mem/ruby/network/simple/Throttle.hh"
---
> #include "base/cprintf.hh"
> #include "mem/protocol/Protocol.hh"
40c33
< #include "mem/ruby/system/System.hh"
---
> #include "mem/ruby/network/simple/Throttle.hh"
42c35
< #include "mem/protocol/Protocol.hh"
---
> #include "mem/ruby/system/System.hh"
53c46
< extern std::ostream * debug_cout_ptr;
---
> extern std::ostream *debug_cout_ptr;
55c48,49
< Throttle::Throttle(int sID, NodeID node, int link_latency, int link_bandwidth_multiplier)
---
> Throttle::Throttle(int sID, NodeID node, int link_latency,
> int link_bandwidth_multiplier)
57,58c51,52
< init(node, link_latency, link_bandwidth_multiplier);
< m_sID = sID;
---
> init(node, link_latency, link_bandwidth_multiplier);
> m_sID = sID;
61c55,56
< Throttle::Throttle(NodeID node, int link_latency, int link_bandwidth_multiplier)
---
> Throttle::Throttle(NodeID node, int link_latency,
> int link_bandwidth_multiplier)
63,64c58,59
< init(node, link_latency, link_bandwidth_multiplier);
< m_sID = 0;
---
> init(node, link_latency, link_bandwidth_multiplier);
> m_sID = 0;
67c62,63
< void Throttle::init(NodeID node, int link_latency, int link_bandwidth_multiplier)
---
> void
> Throttle::init(NodeID node, int link_latency, int link_bandwidth_multiplier)
69,70c65,66
< m_node = node;
< m_vnets = 0;
---
> m_node = node;
> m_vnets = 0;
72,74c68,70
< ASSERT(link_bandwidth_multiplier > 0);
< m_link_bandwidth_multiplier = link_bandwidth_multiplier;
< m_link_latency = link_latency;
---
> ASSERT(link_bandwidth_multiplier > 0);
> m_link_bandwidth_multiplier = link_bandwidth_multiplier;
> m_link_latency = link_latency;
76,77c72,73
< m_wakeups_wo_switch = 0;
< clearStats();
---
> m_wakeups_wo_switch = 0;
> clearStats();
80c76,77
< void Throttle::clear()
---
> void
> Throttle::clear()
82,85c79,82
< for (int counter = 0; counter < m_vnets; counter++) {
< m_in[counter]->clear();
< m_out[counter]->clear();
< }
---
> for (int counter = 0; counter < m_vnets; counter++) {
> m_in[counter]->clear();
> m_out[counter]->clear();
> }
88c85,87
< void Throttle::addLinks(const Vector<MessageBuffer*>& in_vec, const Vector<MessageBuffer*>& out_vec)
---
> void
> Throttle::addLinks(const Vector<MessageBuffer*>& in_vec,
> const Vector<MessageBuffer*>& out_vec)
90,93c89,92
< assert(in_vec.size() == out_vec.size());
< for (int i=0; i<in_vec.size(); i++) {
< addVirtualNetwork(in_vec[i], out_vec[i]);
< }
---
> assert(in_vec.size() == out_vec.size());
> for (int i=0; i<in_vec.size(); i++) {
> addVirtualNetwork(in_vec[i], out_vec[i]);
> }
95,99c94,99
< m_message_counters.setSize(MessageSizeType_NUM);
< for (int i=0; i<MessageSizeType_NUM; i++) {
< m_message_counters[i].setSize(in_vec.size());
< for (int j=0; j<m_message_counters[i].size(); j++) {
< m_message_counters[i][j] = 0;
---
> m_message_counters.setSize(MessageSizeType_NUM);
> for (int i = 0; i < MessageSizeType_NUM; i++) {
> m_message_counters[i].setSize(in_vec.size());
> for (int j = 0; j<m_message_counters[i].size(); j++) {
> m_message_counters[i][j] = 0;
> }
101d100
< }
104c103,104
< void Throttle::addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr)
---
> void
> Throttle::addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr)
106,108c106,108
< m_units_remaining.insertAtBottom(0);
< m_in.insertAtBottom(in_ptr);
< m_out.insertAtBottom(out_ptr);
---
> m_units_remaining.insertAtBottom(0);
> m_in.insertAtBottom(in_ptr);
> m_out.insertAtBottom(out_ptr);
110,114c110,115
< // Set consumer and description
< m_in[m_vnets]->setConsumer(this);
< string desc = "[Queue to Throttle " + NodeIDToString(m_sID) + " " + NodeIDToString(m_node) + "]";
< m_in[m_vnets]->setDescription(desc);
< m_vnets++;
---
> // Set consumer and description
> m_in[m_vnets]->setConsumer(this);
> string desc = "[Queue to Throttle " + NodeIDToString(m_sID) + " " +
> NodeIDToString(m_node) + "]";
> m_in[m_vnets]->setDescription(desc);
> m_vnets++;
117c118,119
< void Throttle::wakeup()
---
> void
> Throttle::wakeup()
119,121c121,123
< // Limits the number of message sent to a limited number of bytes/cycle.
< assert(getLinkBandwidth() > 0);
< int bw_remaining = getLinkBandwidth();
---
> // Limits the number of message sent to a limited number of bytes/cycle.
> assert(getLinkBandwidth() > 0);
> int bw_remaining = getLinkBandwidth();
123,128c125,130
< // Give the highest numbered link priority most of the time
< m_wakeups_wo_switch++;
< int highest_prio_vnet = m_vnets-1;
< int lowest_prio_vnet = 0;
< int counter = 1;
< bool schedule_wakeup = false;
---
> // Give the highest numbered link priority most of the time
> m_wakeups_wo_switch++;
> int highest_prio_vnet = m_vnets-1;
> int lowest_prio_vnet = 0;
> int counter = 1;
> bool schedule_wakeup = false;
130,136c132,138
< // invert priorities to avoid starvation seen in the component network
< if (m_wakeups_wo_switch > PRIORITY_SWITCH_LIMIT) {
< m_wakeups_wo_switch = 0;
< highest_prio_vnet = 0;
< lowest_prio_vnet = m_vnets-1;
< counter = -1;
< }
---
> // invert priorities to avoid starvation seen in the component network
> if (m_wakeups_wo_switch > PRIORITY_SWITCH_LIMIT) {
> m_wakeups_wo_switch = 0;
> highest_prio_vnet = 0;
> lowest_prio_vnet = m_vnets-1;
> counter = -1;
> }
138c140,142
< for (int vnet = highest_prio_vnet; (vnet*counter) >= (counter*lowest_prio_vnet); vnet -= counter) {
---
> for (int vnet = highest_prio_vnet;
> (vnet * counter) >= (counter * lowest_prio_vnet);
> vnet -= counter) {
140,142c144,146
< assert(m_out[vnet] != NULL);
< assert(m_in[vnet] != NULL);
< assert(m_units_remaining[vnet] >= 0);
---
> assert(m_out[vnet] != NULL);
> assert(m_in[vnet] != NULL);
> assert(m_units_remaining[vnet] >= 0);
144c148,150
< while ((bw_remaining > 0) && ((m_in[vnet]->isReady()) || (m_units_remaining[vnet] > 0)) && m_out[vnet]->areNSlotsAvailable(1)) {
---
> while (bw_remaining > 0 &&
> (m_in[vnet]->isReady() || m_units_remaining[vnet] > 0) &&
> m_out[vnet]->areNSlotsAvailable(1)) {
146,147c152,160
< // See if we are done transferring the previous message on this virtual network
< if (m_units_remaining[vnet] == 0 && m_in[vnet]->isReady()) {
---
> // See if we are done transferring the previous message on
> // this virtual network
> if (m_units_remaining[vnet] == 0 && m_in[vnet]->isReady()) {
> // Find the size of the message we are moving
> MsgPtr msg_ptr = m_in[vnet]->peekMsgPtr();
> NetworkMessage* net_msg_ptr =
> safe_cast<NetworkMessage*>(msg_ptr.ref());
> m_units_remaining[vnet] +=
> network_message_to_size(net_msg_ptr);
149,152c162,167
< // Find the size of the message we are moving
< MsgPtr msg_ptr = m_in[vnet]->peekMsgPtr();
< NetworkMessage* net_msg_ptr = dynamic_cast<NetworkMessage*>(msg_ptr.ref());
< m_units_remaining[vnet] += network_message_to_size(net_msg_ptr);
---
> DEBUG_NEWLINE(NETWORK_COMP,HighPrio);
> DEBUG_MSG(NETWORK_COMP, HighPrio,
> csprintf("throttle: %d my bw %d bw spent enqueueing "
> "net msg %d time: %d.",
> m_node, getLinkBandwidth(), m_units_remaining[vnet],
> g_eventQueue_ptr->getTime()));
154,158c169,171
< DEBUG_NEWLINE(NETWORK_COMP,HighPrio);
< DEBUG_MSG(NETWORK_COMP,HighPrio,"throttle: " + int_to_string(m_node)
< + " my bw " + int_to_string(getLinkBandwidth())
< + " bw spent enqueueing net msg " + int_to_string(m_units_remaining[vnet])
< + " time: " + int_to_string(g_eventQueue_ptr->getTime()) + ".");
---
> // Move the message
> m_out[vnet]->enqueue(m_in[vnet]->peekMsgPtr(), m_link_latency);
> m_in[vnet]->pop();
160,162c173,174
< // Move the message
< m_out[vnet]->enqueue(m_in[vnet]->peekMsgPtr(), m_link_latency);
< m_in[vnet]->pop();
---
> // Count the message
> m_message_counters[net_msg_ptr->getMessageSize()][vnet]++;
164,165c176,178
< // Count the message
< m_message_counters[net_msg_ptr->getMessageSize()][vnet]++;
---
> DEBUG_MSG(NETWORK_COMP,LowPrio,*m_out[vnet]);
> DEBUG_NEWLINE(NETWORK_COMP,HighPrio);
> }
167,169c180,184
< DEBUG_MSG(NETWORK_COMP,LowPrio,*m_out[vnet]);
< DEBUG_NEWLINE(NETWORK_COMP,HighPrio);
< }
---
> // Calculate the amount of bandwidth we spent on this message
> int diff = m_units_remaining[vnet] - bw_remaining;
> m_units_remaining[vnet] = max(0, diff);
> bw_remaining = max(0, -diff);
> }
171,174c186,193
< // Calculate the amount of bandwidth we spent on this message
< int diff = m_units_remaining[vnet] - bw_remaining;
< m_units_remaining[vnet] = max(0, diff);
< bw_remaining = max(0, -diff);
---
> if (bw_remaining > 0 &&
> (m_in[vnet]->isReady() || m_units_remaining[vnet] > 0) &&
> !m_out[vnet]->areNSlotsAvailable(1)) {
> DEBUG_MSG(NETWORK_COMP,LowPrio,vnet);
> // schedule me to wakeup again because I'm waiting for my
> // output queue to become available
> schedule_wakeup = true;
> }
177,181c196,198
< if ((bw_remaining > 0) && ((m_in[vnet]->isReady()) || (m_units_remaining[vnet] > 0)) && !m_out[vnet]->areNSlotsAvailable(1)) {
< DEBUG_MSG(NETWORK_COMP,LowPrio,vnet);
< schedule_wakeup = true; // schedule me to wakeup again because I'm waiting for my output queue to become available
< }
< }
---
> // We should only wake up when we use the bandwidth
> // This is only mostly true
> // assert(bw_remaining != getLinkBandwidth());
183,184c200,201
< // We should only wake up when we use the bandwidth
< // assert(bw_remaining != getLinkBandwidth()); // This is only mostly true
---
> // Record that we used some or all of the link bandwidth this cycle
> double ratio = 1.0 - (double(bw_remaining) / double(getLinkBandwidth()));
186,189c203,204
< // Record that we used some or all of the link bandwidth this cycle
< double ratio = 1.0-(double(bw_remaining)/double(getLinkBandwidth()));
< // If ratio = 0, we used no bandwidth, if ratio = 1, we used all
< linkUtilized(ratio);
---
> // If ratio = 0, we used no bandwidth, if ratio = 1, we used all
> linkUtilized(ratio);
191,200c206,219
< if ((bw_remaining > 0) && !schedule_wakeup) {
< // We have extra bandwidth and our output buffer was available, so we must not have anything else to do until another message arrives.
< DEBUG_MSG(NETWORK_COMP,LowPrio,*this);
< DEBUG_MSG(NETWORK_COMP,LowPrio,"not scheduled again");
< } else {
< DEBUG_MSG(NETWORK_COMP,LowPrio,*this);
< DEBUG_MSG(NETWORK_COMP,LowPrio,"scheduled again");
< // We are out of bandwidth for this cycle, so wakeup next cycle and continue
< g_eventQueue_ptr->scheduleEvent(this, 1);
< }
---
> if (bw_remaining > 0 && !schedule_wakeup) {
> // We have extra bandwidth and our output buffer was
> // available, so we must not have anything else to do until
> // another message arrives.
> DEBUG_MSG(NETWORK_COMP, LowPrio, *this);
> DEBUG_MSG(NETWORK_COMP, LowPrio, "not scheduled again");
> } else {
> DEBUG_MSG(NETWORK_COMP, LowPrio, *this);
> DEBUG_MSG(NETWORK_COMP, LowPrio, "scheduled again");
>
> // We are out of bandwidth for this cycle, so wakeup next
> // cycle and continue
> g_eventQueue_ptr->scheduleEvent(this, 1);
> }
203c222,223
< void Throttle::printStats(ostream& out) const
---
> void
> Throttle::printStats(ostream& out) const
205c225
< out << "utilized_percent: " << getUtilization() << endl;
---
> out << "utilized_percent: " << getUtilization() << endl;
208c228,229
< void Throttle::clearStats()
---
> void
> Throttle::clearStats()
210,211c231,232
< m_ruby_start = g_eventQueue_ptr->getTime();
< m_links_utilized = 0.0;
---
> m_ruby_start = g_eventQueue_ptr->getTime();
> m_links_utilized = 0.0;
213,215c234,237
< for (int i=0; i<m_message_counters.size(); i++) {
< for (int j=0; j<m_message_counters[i].size(); j++) {
< m_message_counters[i][j] = 0;
---
> for (int i = 0; i < m_message_counters.size(); i++) {
> for (int j = 0; j < m_message_counters[i].size(); j++) {
> m_message_counters[i][j] = 0;
> }
217d238
< }
220c241,242
< void Throttle::printConfig(ostream& out) const
---
> void
> Throttle::printConfig(ostream& out) const
222d243
<
225c246,247
< double Throttle::getUtilization() const
---
> double
> Throttle::getUtilization() const
227c249,250
< return (100.0 * double(m_links_utilized)) / (double(g_eventQueue_ptr->getTime()-m_ruby_start));
---
> return 100.0 * double(m_links_utilized) /
> double(g_eventQueue_ptr->getTime()-m_ruby_start);
230c253,254
< void Throttle::print(ostream& out) const
---
> void
> Throttle::print(ostream& out) const
232c256,257
< out << "[Throttle: " << m_sID << " " << m_node << " bw: " << getLinkBandwidth() << "]";
---
> out << "[Throttle: " << m_sID << " " << m_node
> << " bw: " << getLinkBandwidth() << "]";
235,238c260,261
< // Helper function
<
< static
< int network_message_to_size(NetworkMessage* net_msg_ptr)
---
> int
> network_message_to_size(NetworkMessage* net_msg_ptr)
240c263
< assert(net_msg_ptr != NULL);
---
> assert(net_msg_ptr != NULL);
242,248c265,273
< // Artificially increase the size of broadcast messages
< if (BROADCAST_SCALING > 1) {
< if (net_msg_ptr->getDestination().isBroadcast()) {
< return (RubySystem::getNetwork()->MessageSizeType_to_int(net_msg_ptr->getMessageSize()) * MESSAGE_SIZE_MULTIPLIER * BROADCAST_SCALING);
< }
< }
< return (RubySystem::getNetwork()->MessageSizeType_to_int(net_msg_ptr->getMessageSize()) * MESSAGE_SIZE_MULTIPLIER);
---
> int size = RubySystem::getNetwork()->
> MessageSizeType_to_int(net_msg_ptr->getMessageSize());
> size *= MESSAGE_SIZE_MULTIPLIER;
>
> // Artificially increase the size of broadcast messages
> if (BROADCAST_SCALING > 1 && net_msg_ptr->getDestination().isBroadcast())
> size *= BROADCAST_SCALING;
>
> return size;