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; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 <cassert> 30#include <numeric> 31 32#include "base/cast.hh" 33#include "base/stl_helpers.hh" 34#include "mem/ruby/buffers/MessageBuffer.hh" 35#include "mem/ruby/common/NetDest.hh" 36#include "mem/ruby/network/BasicLink.hh" 37#include "mem/ruby/network/simple/SimpleLink.hh" 38#include "mem/ruby/network/simple/SimpleNetwork.hh" 39#include "mem/ruby/network/simple/Switch.hh" 40#include "mem/ruby/network/simple/Throttle.hh" 41#include "mem/ruby/network/Topology.hh" 42#include "mem/ruby/profiler/Profiler.hh" 43#include "mem/ruby/system/System.hh" 44 45using namespace std; 46using m5::stl_helpers::deletePointers; 47 48SimpleNetwork::SimpleNetwork(const Params *p) 49 : Network(p) 50{ 51 m_buffer_size = p->buffer_size; 52 m_endpoint_bandwidth = p->endpoint_bandwidth; 53 m_adaptive_routing = p->adaptive_routing; 54 55 // Note: the parent Network Object constructor is called before the 56 // SimpleNetwork child constructor. Therefore, the member variables 57 // used below should already be initialized. 58 59 m_endpoint_switches.resize(m_nodes); 60 61 m_in_use.resize(m_virtual_networks); 62 m_ordered.resize(m_virtual_networks); 63 for (int i = 0; i < m_virtual_networks; i++) { 64 m_in_use[i] = false; 65 m_ordered[i] = false; 66 } 67 68 // Allocate to and from queues 69 m_toNetQueues.resize(m_nodes); 70 m_fromNetQueues.resize(m_nodes); 71 for (int node = 0; node < m_nodes; node++) { 72 m_toNetQueues[node].resize(m_virtual_networks); 73 m_fromNetQueues[node].resize(m_virtual_networks); 74 for (int j = 0; j < m_virtual_networks; j++) { 75 m_toNetQueues[node][j] = 76 new MessageBuffer(csprintf("toNet node %d j %d", node, j)); 77 m_fromNetQueues[node][j] = 78 new MessageBuffer(csprintf("fromNet node %d j %d", node, j)); 79 } 80 }
|
81 82 // record the routers 83 for (vector<BasicRouter*>::const_iterator i = 84 m_topology_ptr->params()->routers.begin(); 85 i != m_topology_ptr->params()->routers.end(); ++i) { 86 Switch* s = safe_cast<Switch*>(*i); 87 m_switch_ptr_vector.push_back(s); 88 s->init_net_ptr(this); 89 } |
90} 91 92void 93SimpleNetwork::init() 94{ 95 Network::init(); 96 97 // The topology pointer should have already been initialized in 98 // the parent class network constructor. 99 assert(m_topology_ptr != NULL);
|
91 int number_of_switches = m_topology_ptr->numSwitches();
92 for (int i = 0; i < number_of_switches; i++) {
93 m_switch_ptr_vector.push_back(new Switch(i, this));
94 }
95
|
100 // false because this isn't a reconfiguration 101 m_topology_ptr->createLinks(this, false); 102} 103 104void 105SimpleNetwork::reset() 106{ 107 for (int node = 0; node < m_nodes; node++) { 108 for (int j = 0; j < m_virtual_networks; j++) { 109 m_toNetQueues[node][j]->clear(); 110 m_fromNetQueues[node][j]->clear(); 111 } 112 } 113 114 for(int i = 0; i < m_switch_ptr_vector.size(); i++){ 115 m_switch_ptr_vector[i]->clearBuffers(); 116 } 117} 118 119SimpleNetwork::~SimpleNetwork() 120{ 121 for (int i = 0; i < m_nodes; i++) { 122 deletePointers(m_toNetQueues[i]); 123 deletePointers(m_fromNetQueues[i]); 124 } 125 deletePointers(m_switch_ptr_vector); 126 deletePointers(m_buffers_to_free); 127 // delete m_topology_ptr; 128} 129 130// From a switch to an endpoint node 131void 132SimpleNetwork::makeOutLink(SwitchID src, NodeID dest, BasicLink* link, 133 LinkDirection direction, 134 const NetDest& routing_table_entry, 135 bool isReconfiguration) 136{ 137 assert(dest < m_nodes); 138 assert(src < m_switch_ptr_vector.size()); 139 assert(m_switch_ptr_vector[src] != NULL); 140 141 if (isReconfiguration) { 142 m_switch_ptr_vector[src]->reconfigureOutPort(routing_table_entry); 143 return; 144 } 145 146 SimpleExtLink *simple_link = safe_cast<SimpleExtLink*>(link); 147 148 m_switch_ptr_vector[src]->addOutPort(m_fromNetQueues[dest], 149 routing_table_entry, 150 simple_link->m_latency, 151 simple_link->m_bw_multiplier); 152 153 m_endpoint_switches[dest] = m_switch_ptr_vector[src]; 154} 155 156// From an endpoint node to a switch 157void 158SimpleNetwork::makeInLink(NodeID src, SwitchID dest, BasicLink* link, 159 LinkDirection direction, 160 const NetDest& routing_table_entry, 161 bool isReconfiguration) 162{ 163 assert(src < m_nodes); 164 if (isReconfiguration) { 165 // do nothing 166 return; 167 } 168 169 m_switch_ptr_vector[dest]->addInPort(m_toNetQueues[src]); 170} 171 172// From a switch to a switch 173void 174SimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link, 175 LinkDirection direction, 176 const NetDest& routing_table_entry, 177 bool isReconfiguration) 178{ 179 if (isReconfiguration) { 180 m_switch_ptr_vector[src]->reconfigureOutPort(routing_table_entry); 181 return; 182 } 183 184 // Create a set of new MessageBuffers 185 std::vector<MessageBuffer*> queues; 186 for (int i = 0; i < m_virtual_networks; i++) { 187 // allocate a buffer 188 MessageBuffer* buffer_ptr = new MessageBuffer; 189 buffer_ptr->setOrdering(true); 190 if (m_buffer_size > 0) { 191 buffer_ptr->resize(m_buffer_size); 192 } 193 queues.push_back(buffer_ptr); 194 // remember to deallocate it 195 m_buffers_to_free.push_back(buffer_ptr); 196 } 197 // Connect it to the two switches 198 SimpleIntLink *simple_link = safe_cast<SimpleIntLink*>(link); 199 200 m_switch_ptr_vector[dest]->addInPort(queues); 201 m_switch_ptr_vector[src]->addOutPort(queues, routing_table_entry, 202 simple_link->m_latency, 203 simple_link->m_bw_multiplier); 204} 205 206void 207SimpleNetwork::checkNetworkAllocation(NodeID id, bool ordered, int network_num) 208{ 209 assert(id < m_nodes); 210 assert(network_num < m_virtual_networks); 211 212 if (ordered) { 213 m_ordered[network_num] = true; 214 } 215 m_in_use[network_num] = true; 216} 217 218MessageBuffer* 219SimpleNetwork::getToNetQueue(NodeID id, bool ordered, int network_num, 220 std::string vnet_type) 221{ 222 checkNetworkAllocation(id, ordered, network_num); 223 return m_toNetQueues[id][network_num]; 224} 225 226MessageBuffer* 227SimpleNetwork::getFromNetQueue(NodeID id, bool ordered, int network_num, 228 std::string vnet_type) 229{ 230 checkNetworkAllocation(id, ordered, network_num); 231 return m_fromNetQueues[id][network_num]; 232} 233 234const std::vector<Throttle*>* 235SimpleNetwork::getThrottles(NodeID id) const 236{ 237 assert(id >= 0); 238 assert(id < m_nodes); 239 assert(m_endpoint_switches[id] != NULL); 240 return m_endpoint_switches[id]->getThrottles(); 241} 242 243void 244SimpleNetwork::printStats(ostream& out) const 245{ 246 out << endl; 247 out << "Network Stats" << endl; 248 out << "-------------" << endl; 249 out << endl; 250 251 // 252 // Determine total counts before printing out each switch's stats 253 // 254 std::vector<uint64> total_msg_counts; 255 total_msg_counts.resize(MessageSizeType_NUM); 256 for (MessageSizeType type = MessageSizeType_FIRST; 257 type < MessageSizeType_NUM; 258 ++type) { 259 total_msg_counts[type] = 0; 260 } 261 262 for (int i = 0; i < m_switch_ptr_vector.size(); i++) { 263 const std::vector<Throttle*>* throttles = 264 m_switch_ptr_vector[i]->getThrottles(); 265 266 for (int p = 0; p < throttles->size(); p++) { 267 268 const std::vector<std::vector<int> >& message_counts = 269 ((*throttles)[p])->getCounters(); 270 271 for (MessageSizeType type = MessageSizeType_FIRST; 272 type < MessageSizeType_NUM; 273 ++type) { 274 275 const std::vector<int> &mct = message_counts[type]; 276 int sum = accumulate(mct.begin(), mct.end(), 0); 277 total_msg_counts[type] += uint64(sum); 278 } 279 } 280 } 281 uint64 total_msgs = 0; 282 uint64 total_bytes = 0; 283 for (MessageSizeType type = MessageSizeType_FIRST; 284 type < MessageSizeType_NUM; 285 ++type) { 286 287 if (total_msg_counts[type] > 0) { 288 out << "total_msg_count_" << type << ": " << total_msg_counts[type]
|
285 << " " << total_msg_counts[type] *
286 uint64(RubySystem::getNetwork()->MessageSizeType_to_int(type))
|
289 << " " << total_msg_counts[type] * 290 uint64(MessageSizeType_to_int(type)) |
291 << endl; 292 293 total_msgs += total_msg_counts[type]; 294 295 total_bytes += total_msg_counts[type] *
|
292 uint64(RubySystem::getNetwork()->MessageSizeType_to_int(type));
293
|
296 uint64(MessageSizeType_to_int(type)); |
297 } 298 } 299 300 out << "total_msgs: " << total_msgs 301 << " total_bytes: " << total_bytes << endl; 302 303 out << endl; 304 for (int i = 0; i < m_switch_ptr_vector.size(); i++) { 305 m_switch_ptr_vector[i]->printStats(out); 306 } 307 m_topology_ptr->printStats(out); 308} 309 310void 311SimpleNetwork::clearStats() 312{ 313 for (int i = 0; i < m_switch_ptr_vector.size(); i++) { 314 m_switch_ptr_vector[i]->clearStats(); 315 } 316 m_topology_ptr->clearStats(); 317} 318 319void 320SimpleNetwork::print(ostream& out) const 321{ 322 out << "[SimpleNetwork]"; 323} 324 325SimpleNetwork * 326SimpleNetworkParams::create() 327{ 328 return new SimpleNetwork(this); 329}
|