1/* 2 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 12 unchanged lines hidden (view full) --- 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 |
29#include <algorithm> 30 |
31#include "mem/protocol/Protocol.hh" 32#include "mem/ruby/buffers/MessageBuffer.hh" 33#include "mem/ruby/network/simple/PerfectSwitch.hh" 34#include "mem/ruby/network/simple/SimpleNetwork.hh" 35#include "mem/ruby/profiler/Profiler.hh" 36#include "mem/ruby/slicc_interface/NetworkMessage.hh" 37#include "mem/ruby/system/System.hh" 38 --- 13 unchanged lines hidden (view full) --- 52 m_virtual_networks = network_ptr->getNumberOfVirtualNetworks(); 53 m_switch_id = sid; 54 m_round_robin_start = 0; 55 m_network_ptr = network_ptr; 56 m_wakeups_wo_switch = 0; 57} 58 59void |
60PerfectSwitch::addInPort(const vector<MessageBuffer*>& in) |
61{ 62 assert(in.size() == m_virtual_networks); 63 NodeID port = m_in.size(); |
64 m_in.push_back(in); |
65 for (int j = 0; j < m_virtual_networks; j++) { 66 m_in[port][j]->setConsumer(this); 67 string desc = csprintf("[Queue from port %s %s %s to PerfectSwitch]", 68 NodeIDToString(m_switch_id), NodeIDToString(port), 69 NodeIDToString(j)); 70 m_in[port][j]->setDescription(desc); 71 } 72} 73 74void |
75PerfectSwitch::addOutPort(const vector<MessageBuffer*>& out, |
76 const NetDest& routing_table_entry) 77{ 78 assert(out.size() == m_virtual_networks); 79 80 // Setup link order 81 LinkOrder l; 82 l.m_value = 0; 83 l.m_link = m_out.size(); |
84 m_link_order.push_back(l); |
85 86 // Add to routing table |
87 m_out.push_back(out); 88 m_routing_table.push_back(routing_table_entry); |
89} 90 91void 92PerfectSwitch::clearRoutingTables() 93{ 94 m_routing_table.clear(); 95} 96 --- 11 unchanged lines hidden (view full) --- 108 m_out[i][vnet]->clear(); 109 } 110 } 111} 112 113void 114PerfectSwitch::reconfigureOutPort(const NetDest& routing_table_entry) 115{ |
116 m_routing_table.push_back(routing_table_entry); |
117} 118 119PerfectSwitch::~PerfectSwitch() 120{ 121} 122 123void 124PerfectSwitch::wakeup() --- 33 unchanged lines hidden (view full) --- 158 for (int counter = 0; counter < m_in.size(); counter++) { 159 // Round robin scheduling 160 incoming++; 161 if (incoming >= m_in.size()) { 162 incoming = 0; 163 } 164 165 // temporary vectors to store the routing results |
166 vector<LinkID> output_links; 167 vector<NetDest> output_link_destinations; |
168 169 // Is there a message waiting? 170 while (m_in[incoming][vnet]->isReady()) { 171 DEBUG_EXPR(NETWORK_COMP, MedPrio, incoming); 172 173 // Peek at message 174 msg_ptr = m_in[incoming][vnet]->peekMsgPtr(); 175 net_msg_ptr = safe_cast<NetworkMessage*>(msg_ptr.get()); --- 27 unchanged lines hidden (view full) --- 203 } 204 int value = 205 (out_queue_length << 8) | (random() & 0xff); 206 m_link_order[out].m_link = out; 207 m_link_order[out].m_value = value; 208 } 209 210 // Look at the most empty link first |
211 sort(m_link_order.begin(), m_link_order.end()); |
212 } 213 } 214 215 for (int i = 0; i < m_routing_table.size(); i++) { 216 // pick the next link to look at 217 int link = m_link_order[i].m_link; 218 NetDest dst = m_routing_table[link]; 219 DEBUG_EXPR(NETWORK_COMP, MedPrio, dst); 220 221 if (!msg_dsts.intersectionIsNotEmpty(dst)) 222 continue; 223 224 // Remember what link we're using |
225 output_links.push_back(link); |
226 227 // Need to remember which destinations need this 228 // message in another vector. This Set is the 229 // intersection of the routing_table entry and the 230 // current destination set. The intersection must 231 // not be empty, since we are inside "if" |
232 output_link_destinations.push_back(msg_dsts.AND(dst)); |
233 234 // Next, we update the msg_destination not to 235 // include those nodes that were already handled 236 // by this link 237 msg_dsts.removeNetDest(dst); 238 } 239 240 assert(msg_dsts.count() == 0); --- 97 unchanged lines hidden --- |