SimpleNetwork.cc revision 8255:73089f793a0a
16899SN/A/* 26899SN/A * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 36899SN/A * All rights reserved. 46899SN/A * 56899SN/A * Redistribution and use in source and binary forms, with or without 66899SN/A * modification, are permitted provided that the following conditions are 76899SN/A * met: redistributions of source code must retain the above copyright 86899SN/A * notice, this list of conditions and the following disclaimer; 96899SN/A * redistributions in binary form must reproduce the above copyright 106899SN/A * notice, this list of conditions and the following disclaimer in the 116899SN/A * documentation and/or other materials provided with the distribution; 126899SN/A * neither the name of the copyright holders nor the names of its 136899SN/A * contributors may be used to endorse or promote products derived from 146899SN/A * this software without specific prior written permission. 156899SN/A * 166899SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176899SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186899SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196899SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206899SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216899SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226899SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236899SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246899SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256899SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266899SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276899SN/A */ 286899SN/A 296899SN/A#include <cassert> 307632SBrad.Beckmann@amd.com#include <numeric> 317053SN/A 326899SN/A#include "base/stl_helpers.hh" 336899SN/A#include "mem/protocol/MachineType.hh" 346899SN/A#include "mem/protocol/Protocol.hh" 357053SN/A#include "mem/protocol/TopologyType.hh" 367053SN/A#include "mem/ruby/buffers/MessageBuffer.hh" 377053SN/A#include "mem/ruby/common/NetDest.hh" 387053SN/A#include "mem/ruby/network/simple/SimpleNetwork.hh" 397053SN/A#include "mem/ruby/network/simple/Switch.hh" 406899SN/A#include "mem/ruby/network/simple/Throttle.hh" 417053SN/A#include "mem/ruby/network/Topology.hh" 426899SN/A#include "mem/ruby/profiler/Profiler.hh" 437053SN/A#include "mem/ruby/system/System.hh" 447053SN/A 457053SN/Ausing namespace std; 467053SN/Ausing m5::stl_helpers::deletePointers; 477053SN/A 487053SN/A#if 0 496899SN/A// ***BIG HACK*** - This is actually code that _should_ be in Network.cc 506899SN/A 517053SN/A// Note: Moved to Princeton Network 527053SN/A// calls new to abstract away from the network 536899SN/ANetwork* 547053SN/ANetwork::createNetwork(int nodes) 557053SN/A{ 566899SN/A return new SimpleNetwork(nodes); 577053SN/A} 587053SN/A#endif 597053SN/A 607053SN/ASimpleNetwork::SimpleNetwork(const Params *p) 616899SN/A : Network(p) 627053SN/A{ 637053SN/A // Note: the parent Network Object constructor is called before the 647053SN/A // SimpleNetwork child constructor. Therefore, the member variables 657053SN/A // used below should already be initialized. 667053SN/A 677053SN/A m_endpoint_switches.resize(m_nodes); 687053SN/A 697053SN/A m_in_use.resize(m_virtual_networks); 707053SN/A m_ordered.resize(m_virtual_networks); 716899SN/A for (int i = 0; i < m_virtual_networks; i++) { 726899SN/A m_in_use[i] = false; 737053SN/A m_ordered[i] = false; 747053SN/A } 756899SN/A 767053SN/A // Allocate to and from queues 776899SN/A m_toNetQueues.resize(m_nodes); 787053SN/A m_fromNetQueues.resize(m_nodes); 797053SN/A for (int node = 0; node < m_nodes; node++) { 807053SN/A m_toNetQueues[node].resize(m_virtual_networks); 816899SN/A m_fromNetQueues[node].resize(m_virtual_networks); 827053SN/A for (int j = 0; j < m_virtual_networks; j++) { 837053SN/A m_toNetQueues[node][j] = 846899SN/A new MessageBuffer(csprintf("toNet node %d j %d", node, j)); 857053SN/A m_fromNetQueues[node][j] = 866899SN/A new MessageBuffer(csprintf("fromNet node %d j %d", node, j)); 877053SN/A } 887053SN/A } 897053SN/A} 907053SN/A 917053SN/Avoid 927053SN/ASimpleNetwork::init() 937053SN/A{ 947053SN/A Network::init(); 957053SN/A 967053SN/A // The topology pointer should have already been initialized in 977053SN/A // the parent class network constructor. 986899SN/A assert(m_topology_ptr != NULL); 996899SN/A int number_of_switches = m_topology_ptr->numSwitches(); 1007568SN/A for (int i = 0; i < number_of_switches; i++) { 1017568SN/A m_switch_ptr_vector.push_back(new Switch(i, this)); 1027568SN/A } 1037568SN/A 1047053SN/A // false because this isn't a reconfiguration 1056899SN/A m_topology_ptr->createLinks(this, false); 1067053SN/A} 1077053SN/A 1087053SN/Avoid 1097053SN/ASimpleNetwork::reset() 1106899SN/A{ 1117053SN/A for (int node = 0; node < m_nodes; node++) { 1127053SN/A for (int j = 0; j < m_virtual_networks; j++) { 1137053SN/A m_toNetQueues[node][j]->clear(); 1147053SN/A m_fromNetQueues[node][j]->clear(); 1157053SN/A } 1167053SN/A } 1177053SN/A 1187053SN/A for(int i = 0; i < m_switch_ptr_vector.size(); i++){ 1197053SN/A m_switch_ptr_vector[i]->clearBuffers(); 1206899SN/A } 1217053SN/A} 1227053SN/A 1237053SN/ASimpleNetwork::~SimpleNetwork() 1246899SN/A{ 1256899SN/A for (int i = 0; i < m_nodes; i++) { 1267053SN/A deletePointers(m_toNetQueues[i]); 1277053SN/A deletePointers(m_fromNetQueues[i]); 1286899SN/A } 1297053SN/A deletePointers(m_switch_ptr_vector); 1307053SN/A deletePointers(m_buffers_to_free); 1316899SN/A // delete m_topology_ptr; 1327053SN/A} 1337053SN/A 1347053SN/A// From a switch to an endpoint node 1356899SN/Avoid 1367053SN/ASimpleNetwork::makeOutLink(SwitchID src, NodeID dest, 1376899SN/A const NetDest& routing_table_entry, int link_latency, int link_weight, 1387053SN/A int bw_multiplier, bool isReconfiguration) 1397053SN/A{ 1406899SN/A assert(dest < m_nodes); 1417053SN/A assert(src < m_switch_ptr_vector.size()); 1427053SN/A assert(m_switch_ptr_vector[src] != NULL); 1437053SN/A 1446899SN/A if (isReconfiguration) { 1457053SN/A m_switch_ptr_vector[src]->reconfigureOutPort(routing_table_entry); 1467053SN/A return; 1477053SN/A } 1487053SN/A 1497053SN/A m_switch_ptr_vector[src]->addOutPort(m_fromNetQueues[dest], 1507053SN/A routing_table_entry, link_latency, bw_multiplier); 1516899SN/A m_endpoint_switches[dest] = m_switch_ptr_vector[src]; 1527053SN/A} 1536899SN/A 1547053SN/A// From an endpoint node to a switch 1557053SN/Avoid 1567053SN/ASimpleNetwork::makeInLink(NodeID src, SwitchID dest, 1577053SN/A const NetDest& routing_table_entry, int link_latency, int bw_multiplier, 1586899SN/A bool isReconfiguration) 1597053SN/A{ 1607053SN/A assert(src < m_nodes); 1616899SN/A if (isReconfiguration) { 1627053SN/A // do nothing 1637053SN/A return; 1647053SN/A } 1657053SN/A 1666899SN/A m_switch_ptr_vector[dest]->addInPort(m_toNetQueues[src]); 1677053SN/A} 1687053SN/A 1697053SN/A// From a switch to a switch 1707053SN/Avoid 1717053SN/ASimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest, 1727053SN/A const NetDest& routing_table_entry, int link_latency, int link_weight, 1737053SN/A int bw_multiplier, bool isReconfiguration) 1747053SN/A{ 1757053SN/A if (isReconfiguration) { 1767053SN/A m_switch_ptr_vector[src]->reconfigureOutPort(routing_table_entry); 1777053SN/A return; 1787053SN/A } 1797053SN/A 1807053SN/A // Create a set of new MessageBuffers 1817053SN/A std::vector<MessageBuffer*> queues; 1827053SN/A for (int i = 0; i < m_virtual_networks; i++) { 1837053SN/A // allocate a buffer 1847053SN/A MessageBuffer* buffer_ptr = new MessageBuffer; 1857053SN/A buffer_ptr->setOrdering(true); 1866899SN/A if (m_buffer_size > 0) { 1876899SN/A buffer_ptr->resize(m_buffer_size); 1886899SN/A } 1897053SN/A queues.push_back(buffer_ptr); 1907053SN/A // remember to deallocate it 1916899SN/A m_buffers_to_free.push_back(buffer_ptr); 1927053SN/A } 1937053SN/A // Connect it to the two switches 1946899SN/A m_switch_ptr_vector[dest]->addInPort(queues); 1957053SN/A m_switch_ptr_vector[src]->addOutPort(queues, routing_table_entry, 1967053SN/A link_latency, bw_multiplier); 1977053SN/A} 1986899SN/A 1997053SN/Avoid 2006899SN/ASimpleNetwork::checkNetworkAllocation(NodeID id, bool ordered, int network_num) 2017053SN/A{ 2027053SN/A assert(id < m_nodes); 2037053SN/A assert(network_num < m_virtual_networks); 2047053SN/A 2056899SN/A if (ordered) { 2067568SN/A m_ordered[network_num] = true; 2077568SN/A } 2087568SN/A m_in_use[network_num] = true; 2097568SN/A} 2107053SN/A 2117053SN/AMessageBuffer* 2127053SN/ASimpleNetwork::getToNetQueue(NodeID id, bool ordered, int network_num) 2136899SN/A{ 2147053SN/A checkNetworkAllocation(id, ordered, network_num); 2157053SN/A return m_toNetQueues[id][network_num]; 2167053SN/A} 2177053SN/A 2186899SN/AMessageBuffer* 2197053SN/ASimpleNetwork::getFromNetQueue(NodeID id, bool ordered, int network_num) 2207053SN/A{ 2217053SN/A checkNetworkAllocation(id, ordered, network_num); 2227053SN/A return m_fromNetQueues[id][network_num]; 2237053SN/A} 2247053SN/A 2257053SN/Aconst std::vector<Throttle*>* 2267053SN/ASimpleNetwork::getThrottles(NodeID id) const 2277053SN/A{ 2287053SN/A assert(id >= 0); 2297053SN/A assert(id < m_nodes); 2307053SN/A assert(m_endpoint_switches[id] != NULL); 2317053SN/A return m_endpoint_switches[id]->getThrottles(); 2327053SN/A} 2336899SN/A 2347053SN/Avoid 2357053SN/ASimpleNetwork::printStats(ostream& out) const 2367053SN/A{ 2377053SN/A out << endl; 2387053SN/A out << "Network Stats" << endl; 2396899SN/A out << "-------------" << endl; 2406899SN/A out << endl; 2417053SN/A 2427053SN/A // 2436899SN/A // Determine total counts before printing out each switch's stats 2447053SN/A // 2456899SN/A std::vector<uint64> total_msg_counts; 2467053SN/A total_msg_counts.resize(MessageSizeType_NUM); 2477053SN/A for (MessageSizeType type = MessageSizeType_FIRST; 2486899SN/A type < MessageSizeType_NUM; 2497053SN/A ++type) { 2507053SN/A total_msg_counts[type] = 0; 2517053SN/A } 2527053SN/A 2536899SN/A for (int i = 0; i < m_switch_ptr_vector.size(); i++) { 2546899SN/A const std::vector<Throttle*>* throttles = 2557053SN/A m_switch_ptr_vector[i]->getThrottles(); 2567053SN/A 2577053SN/A for (int p = 0; p < throttles->size(); p++) { 2587053SN/A 2597053SN/A const std::vector<std::vector<int> >& message_counts = 2607053SN/A ((*throttles)[p])->getCounters(); 2617053SN/A 2627053SN/A for (MessageSizeType type = MessageSizeType_FIRST; 2637053SN/A type < MessageSizeType_NUM; 2647053SN/A ++type) { 2657053SN/A 2667053SN/A const std::vector<int> &mct = message_counts[type]; 2677053SN/A int sum = accumulate(mct.begin(), mct.end(), 0); 2687053SN/A total_msg_counts[type] += uint64(sum); 2697053SN/A } 2707053SN/A } 2717053SN/A } 2727053SN/A uint64 total_msgs = 0; 2737805Snilay@cs.wisc.edu uint64 total_bytes = 0; 2747805Snilay@cs.wisc.edu for (MessageSizeType type = MessageSizeType_FIRST; 2757805Snilay@cs.wisc.edu type < MessageSizeType_NUM; 2767805Snilay@cs.wisc.edu ++type) { 2777805Snilay@cs.wisc.edu 2787805Snilay@cs.wisc.edu if (total_msg_counts[type] > 0) { 2797805Snilay@cs.wisc.edu out << "total_msg_count_" << type << ": " << total_msg_counts[type] 2807053SN/A << " " << total_msg_counts[type] * 2817053SN/A uint64(RubySystem::getNetwork()->MessageSizeType_to_int(type)) 2827053SN/A << endl; 2837053SN/A 2846899SN/A total_msgs += total_msg_counts[type]; 2857053SN/A 2867053SN/A total_bytes += total_msg_counts[type] * 2876899SN/A uint64(RubySystem::getNetwork()->MessageSizeType_to_int(type)); 2887053SN/A 2897053SN/A } 2907053SN/A } 2917053SN/A 2927805Snilay@cs.wisc.edu out << "total_msgs: " << total_msgs 2937805Snilay@cs.wisc.edu << " total_bytes: " << total_bytes << endl; 2947805Snilay@cs.wisc.edu 2957053SN/A out << endl; 2967053SN/A for (int i = 0; i < m_switch_ptr_vector.size(); i++) { 2977053SN/A m_switch_ptr_vector[i]->printStats(out); 2987053SN/A } 2997053SN/A m_topology_ptr->printStats(out); 3007053SN/A} 3016899SN/A 3026899SN/Avoid 3037053SN/ASimpleNetwork::clearStats() 3047053SN/A{ 3056899SN/A for (int i = 0; i < m_switch_ptr_vector.size(); i++) { 3067053SN/A m_switch_ptr_vector[i]->clearStats(); 3077053SN/A } 3087053SN/A m_topology_ptr->clearStats(); 3097053SN/A} 3106899SN/A 3116899SN/Avoid 3127053SN/ASimpleNetwork::printConfig(ostream& out) const 3137053SN/A{ 3146899SN/A out << endl; 3157053SN/A out << "Network Configuration" << endl; 3167053SN/A out << "---------------------" << endl; 3177053SN/A out << "network: SIMPLE_NETWORK" << endl; 3187053SN/A out << "topology: " << m_topology_ptr->getName() << endl; 3196899SN/A out << endl; 3206899SN/A 3217053SN/A for (int i = 0; i < m_virtual_networks; i++) { 3227053SN/A out << "virtual_net_" << i << ": "; 3236899SN/A if (m_in_use[i]) { 3247053SN/A out << "active, "; 3257053SN/A if (m_ordered[i]) { 3267053SN/A out << "ordered" << endl; 3277053SN/A } else { 3287053SN/A out << "unordered" << endl; 3296899SN/A } 3306899SN/A } else { 3317053SN/A out << "inactive" << endl; 3327055SN/A } 3336899SN/A } 3347053SN/A out << endl; 3357053SN/A 3367053SN/A for(int i = 0; i < m_switch_ptr_vector.size(); i++) { 3377053SN/A m_switch_ptr_vector[i]->printConfig(out); 3387053SN/A } 3397053SN/A 3407055SN/A m_topology_ptr->printConfig(out); 3416899SN/A} 3426899SN/A 3437053SN/Avoid 3447053SN/ASimpleNetwork::print(ostream& out) const 3456899SN/A{ 3467053SN/A out << "[SimpleNetwork]"; 3477053SN/A} 3487053SN/A 3497053SN/A 3507053SN/ASimpleNetwork * 3516899SN/ASimpleNetworkParams::create() 352{ 353 return new SimpleNetwork(this); 354} 355