SimpleNetwork.cc revision 8255
11758SN/A/* 21762SN/A * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 31758SN/A * All rights reserved. 41758SN/A * 51758SN/A * Redistribution and use in source and binary forms, with or without 61758SN/A * modification, are permitted provided that the following conditions are 71758SN/A * met: redistributions of source code must retain the above copyright 81758SN/A * notice, this list of conditions and the following disclaimer; 91758SN/A * redistributions in binary form must reproduce the above copyright 101758SN/A * notice, this list of conditions and the following disclaimer in the 111758SN/A * documentation and/or other materials provided with the distribution; 121758SN/A * neither the name of the copyright holders nor the names of its 131758SN/A * contributors may be used to endorse or promote products derived from 141758SN/A * this software without specific prior written permission. 151758SN/A * 161758SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171758SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181758SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191758SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201758SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211758SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221758SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231758SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241758SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251758SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261758SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292665Ssaidi@eecs.umich.edu#include <cassert> 301758SN/A#include <numeric> 312SN/A 322984Sgblack@eecs.umich.edu#include "base/stl_helpers.hh" 33732SN/A#include "mem/protocol/MachineType.hh" 343565Sgblack@eecs.umich.edu#include "mem/protocol/Protocol.hh" 35732SN/A#include "mem/protocol/TopologyType.hh" 362984Sgblack@eecs.umich.edu#include "mem/ruby/buffers/MessageBuffer.hh" 373536Sgblack@eecs.umich.edu#include "mem/ruby/common/NetDest.hh" 38732SN/A#include "mem/ruby/network/simple/SimpleNetwork.hh" 39732SN/A#include "mem/ruby/network/simple/Switch.hh" 401858SN/A#include "mem/ruby/network/simple/Throttle.hh" 411717SN/A#include "mem/ruby/network/Topology.hh" 422683Sktlim@umich.edu#include "mem/ruby/profiler/Profiler.hh" 432680Sktlim@umich.edu#include "mem/ruby/system/System.hh" 44676SN/A 452710Sstever@eecs.umich.eduusing namespace std; 462SN/Ausing m5::stl_helpers::deletePointers; 475568Snate@binkert.org 485566Snate@binkert.org#if 0 491858SN/A// ***BIG HACK*** - This is actually code that _should_ be in Network.cc 502SN/A 512SN/A// Note: Moved to Princeton Network 522SN/A// calls new to abstract away from the network 532SN/ANetwork* 542SN/ANetwork::createNetwork(int nodes) 552SN/A{ 565568Snate@binkert.org return new SimpleNetwork(nodes); 572SN/A} 582680Sktlim@umich.edu#endif 59190SN/A 602680Sktlim@umich.eduSimpleNetwork::SimpleNetwork(const Params *p) 612680Sktlim@umich.edu : Network(p) 622114SN/A{ 635568Snate@binkert.org // Note: the parent Network Object constructor is called before the 642700Sktlim@umich.edu // SimpleNetwork child constructor. Therefore, the member variables 654172Ssaidi@eecs.umich.edu // used below should already be initialized. 662680Sktlim@umich.edu 672700Sktlim@umich.edu m_endpoint_switches.resize(m_nodes); 682700Sktlim@umich.edu 692SN/A m_in_use.resize(m_virtual_networks); 702SN/A m_ordered.resize(m_virtual_networks); 712SN/A for (int i = 0; i < m_virtual_networks; i++) { 721133SN/A m_in_use[i] = false; 73716SN/A m_ordered[i] = false; 745568Snate@binkert.org } 75716SN/A 76716SN/A // Allocate to and from queues 77716SN/A m_toNetQueues.resize(m_nodes); 78716SN/A m_fromNetQueues.resize(m_nodes); 79716SN/A for (int node = 0; node < m_nodes; node++) { 80716SN/A m_toNetQueues[node].resize(m_virtual_networks); 814172Ssaidi@eecs.umich.edu m_fromNetQueues[node].resize(m_virtual_networks); 82716SN/A for (int j = 0; j < m_virtual_networks; j++) { 83716SN/A m_toNetQueues[node][j] = 844172Ssaidi@eecs.umich.edu new MessageBuffer(csprintf("toNet node %d j %d", node, j)); 85716SN/A m_fromNetQueues[node][j] = 86716SN/A new MessageBuffer(csprintf("fromNet node %d j %d", node, j)); 874172Ssaidi@eecs.umich.edu } 88716SN/A } 89716SN/A} 90716SN/A 91716SN/Avoid 92716SN/ASimpleNetwork::init() 93716SN/A{ 94716SN/A Network::init(); 951133SN/A 96716SN/A // The topology pointer should have already been initialized in 97716SN/A // the parent class network constructor. 98716SN/A assert(m_topology_ptr != NULL); 99716SN/A int number_of_switches = m_topology_ptr->numSwitches(); 100716SN/A for (int i = 0; i < number_of_switches; i++) { 101716SN/A m_switch_ptr_vector.push_back(new Switch(i, this)); 102716SN/A } 103716SN/A 104716SN/A // false because this isn't a reconfiguration 105716SN/A m_topology_ptr->createLinks(this, false); 106716SN/A} 107716SN/A 1084172Ssaidi@eecs.umich.eduvoid 1094172Ssaidi@eecs.umich.eduSimpleNetwork::reset() 1104172Ssaidi@eecs.umich.edu{ 1112147SN/A for (int node = 0; node < m_nodes; node++) { 112716SN/A for (int j = 0; j < m_virtual_networks; j++) { 1134172Ssaidi@eecs.umich.edu m_toNetQueues[node][j]->clear(); 114716SN/A m_fromNetQueues[node][j]->clear(); 115716SN/A } 116716SN/A } 117716SN/A 1181133SN/A for(int i = 0; i < m_switch_ptr_vector.size(); i++){ 119716SN/A m_switch_ptr_vector[i]->clearBuffers(); 1205568Snate@binkert.org } 121716SN/A} 122716SN/A 123739SN/ASimpleNetwork::~SimpleNetwork() 124739SN/A{ 1252683Sktlim@umich.edu for (int i = 0; i < m_nodes; i++) { 1262683Sktlim@umich.edu deletePointers(m_toNetQueues[i]); 127716SN/A deletePointers(m_fromNetQueues[i]); 128716SN/A } 1295568Snate@binkert.org deletePointers(m_switch_ptr_vector); 1305568Snate@binkert.org deletePointers(m_buffers_to_free); 1312SN/A // delete m_topology_ptr; 1325568Snate@binkert.org} 1332SN/A 1342SN/A// From a switch to an endpoint node 1352245SN/Avoid 1365568Snate@binkert.orgSimpleNetwork::makeOutLink(SwitchID src, NodeID dest, 1372245SN/A const NetDest& routing_table_entry, int link_latency, int link_weight, 1385568Snate@binkert.org int bw_multiplier, bool isReconfiguration) 1392245SN/A{ 1402245SN/A assert(dest < m_nodes); 1414997Sgblack@eecs.umich.edu assert(src < m_switch_ptr_vector.size()); 1424997Sgblack@eecs.umich.edu assert(m_switch_ptr_vector[src] != NULL); 1434997Sgblack@eecs.umich.edu 1444997Sgblack@eecs.umich.edu if (isReconfiguration) { 1454997Sgblack@eecs.umich.edu m_switch_ptr_vector[src]->reconfigureOutPort(routing_table_entry); 1464997Sgblack@eecs.umich.edu return; 1474997Sgblack@eecs.umich.edu } 1485568Snate@binkert.org 1494997Sgblack@eecs.umich.edu m_switch_ptr_vector[src]->addOutPort(m_fromNetQueues[dest], 1504997Sgblack@eecs.umich.edu routing_table_entry, link_latency, bw_multiplier); 1514997Sgblack@eecs.umich.edu m_endpoint_switches[dest] = m_switch_ptr_vector[src]; 1524997Sgblack@eecs.umich.edu} 1534997Sgblack@eecs.umich.edu 1545568Snate@binkert.org// From an endpoint node to a switch 1554997Sgblack@eecs.umich.eduvoid 1564997Sgblack@eecs.umich.eduSimpleNetwork::makeInLink(NodeID src, SwitchID dest, 1574997Sgblack@eecs.umich.edu const NetDest& routing_table_entry, int link_latency, int bw_multiplier, 1584997Sgblack@eecs.umich.edu bool isReconfiguration) 1595568Snate@binkert.org{ 1605568Snate@binkert.org assert(src < m_nodes); 1612159SN/A if (isReconfiguration) { 1625543Ssaidi@eecs.umich.edu // do nothing 1632SN/A return; 1642SN/A } 1655568Snate@binkert.org 1665568Snate@binkert.org m_switch_ptr_vector[dest]->addInPort(m_toNetQueues[src]); 1675568Snate@binkert.org} 1685568Snate@binkert.org 1695568Snate@binkert.org// From a switch to a switch 1705568Snate@binkert.orgvoid 1715568Snate@binkert.orgSimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest, 1725568Snate@binkert.org const NetDest& routing_table_entry, int link_latency, int link_weight, 1735568Snate@binkert.org int bw_multiplier, bool isReconfiguration) 1745568Snate@binkert.org{ 1755568Snate@binkert.org if (isReconfiguration) { 1765568Snate@binkert.org m_switch_ptr_vector[src]->reconfigureOutPort(routing_table_entry); 1775568Snate@binkert.org return; 1785568Snate@binkert.org } 1795568Snate@binkert.org 1805568Snate@binkert.org // Create a set of new MessageBuffers 1815568Snate@binkert.org std::vector<MessageBuffer*> queues; 1825568Snate@binkert.org for (int i = 0; i < m_virtual_networks; i++) { 1835568Snate@binkert.org // allocate a buffer 1845568Snate@binkert.org MessageBuffer* buffer_ptr = new MessageBuffer; 1855568Snate@binkert.org buffer_ptr->setOrdering(true); 1865568Snate@binkert.org if (m_buffer_size > 0) { 1875568Snate@binkert.org buffer_ptr->resize(m_buffer_size); 1885568Snate@binkert.org } 1895568Snate@binkert.org queues.push_back(buffer_ptr); 1902SN/A // remember to deallocate it 1915568Snate@binkert.org m_buffers_to_free.push_back(buffer_ptr); 1925568Snate@binkert.org } 1935568Snate@binkert.org // Connect it to the two switches 1945568Snate@binkert.org m_switch_ptr_vector[dest]->addInPort(queues); 1955568Snate@binkert.org m_switch_ptr_vector[src]->addOutPort(queues, routing_table_entry, 1965568Snate@binkert.org link_latency, bw_multiplier); 1975568Snate@binkert.org} 1985568Snate@binkert.org 1995568Snate@binkert.orgvoid 2005568Snate@binkert.orgSimpleNetwork::checkNetworkAllocation(NodeID id, bool ordered, int network_num) 2015568Snate@binkert.org{ 2025568Snate@binkert.org assert(id < m_nodes); 2035568Snate@binkert.org assert(network_num < m_virtual_networks); 2045568Snate@binkert.org 2055568Snate@binkert.org if (ordered) { 2065568Snate@binkert.org m_ordered[network_num] = true; 2075568Snate@binkert.org } 2082SN/A m_in_use[network_num] = true; 2092SN/A} 2102SN/A 2112SN/AMessageBuffer* 2125568Snate@binkert.orgSimpleNetwork::getToNetQueue(NodeID id, bool ordered, int network_num) 213597SN/A{ 2142680Sktlim@umich.edu checkNetworkAllocation(id, ordered, network_num); 215597SN/A return m_toNetQueues[id][network_num]; 216597SN/A} 2175568Snate@binkert.org 2182SN/AMessageBuffer* 2192SN/ASimpleNetwork::getFromNetQueue(NodeID id, bool ordered, int network_num) 2202SN/A{ 2215568Snate@binkert.org checkNetworkAllocation(id, ordered, network_num); 2225568Snate@binkert.org return m_fromNetQueues[id][network_num]; 2235568Snate@binkert.org} 2245568Snate@binkert.org 2255568Snate@binkert.orgconst std::vector<Throttle*>* 2262SN/ASimpleNetwork::getThrottles(NodeID id) const 2272SN/A{ 2282SN/A assert(id >= 0); 2295568Snate@binkert.org assert(id < m_nodes); 2302SN/A assert(m_endpoint_switches[id] != NULL); 2315568Snate@binkert.org return m_endpoint_switches[id]->getThrottles(); 2325004Sgblack@eecs.umich.edu} 2332SN/A 2345004Sgblack@eecs.umich.eduvoid 2355004Sgblack@eecs.umich.eduSimpleNetwork::printStats(ostream& out) const 2365004Sgblack@eecs.umich.edu{ 2375004Sgblack@eecs.umich.edu out << endl; 2385004Sgblack@eecs.umich.edu out << "Network Stats" << endl; 2395004Sgblack@eecs.umich.edu out << "-------------" << endl; 2405004Sgblack@eecs.umich.edu out << endl; 2412SN/A 2422SN/A // 2432SN/A // Determine total counts before printing out each switch's stats 2442SN/A // 2455568Snate@binkert.org std::vector<uint64> total_msg_counts; 2465568Snate@binkert.org total_msg_counts.resize(MessageSizeType_NUM); 2475568Snate@binkert.org for (MessageSizeType type = MessageSizeType_FIRST; 2485568Snate@binkert.org type < MessageSizeType_NUM; 2495568Snate@binkert.org ++type) { 2505568Snate@binkert.org total_msg_counts[type] = 0; 2515568Snate@binkert.org } 2525568Snate@binkert.org 2535568Snate@binkert.org for (int i = 0; i < m_switch_ptr_vector.size(); i++) { 2543468Sgblack@eecs.umich.edu const std::vector<Throttle*>* throttles = 2552SN/A m_switch_ptr_vector[i]->getThrottles(); 2562SN/A 2572SN/A for (int p = 0; p < throttles->size(); p++) { 2582SN/A 2593468Sgblack@eecs.umich.edu const std::vector<std::vector<int> >& message_counts = 2602SN/A ((*throttles)[p])->getCounters(); 2612SN/A 2622SN/A for (MessageSizeType type = MessageSizeType_FIRST; 2632SN/A type < MessageSizeType_NUM; 2642SN/A ++type) { 2652SN/A 2662SN/A const std::vector<int> &mct = message_counts[type]; 2672SN/A int sum = accumulate(mct.begin(), mct.end(), 0); 2682SN/A total_msg_counts[type] += uint64(sum); 2692SN/A } 2702SN/A } 2713468Sgblack@eecs.umich.edu } 2725568Snate@binkert.org uint64 total_msgs = 0; 2732SN/A uint64 total_bytes = 0; 274710SN/A for (MessageSizeType type = MessageSizeType_FIRST; 2752SN/A type < MessageSizeType_NUM; 2762680Sktlim@umich.edu ++type) { 2773468Sgblack@eecs.umich.edu 2782SN/A if (total_msg_counts[type] > 0) { 2792SN/A out << "total_msg_count_" << type << ": " << total_msg_counts[type] 2805568Snate@binkert.org << " " << total_msg_counts[type] * 2815568Snate@binkert.org uint64(RubySystem::getNetwork()->MessageSizeType_to_int(type)) 2825568Snate@binkert.org << endl; 2835568Snate@binkert.org 2845568Snate@binkert.org total_msgs += total_msg_counts[type]; 2855568Snate@binkert.org 2865568Snate@binkert.org total_bytes += total_msg_counts[type] * 2875568Snate@binkert.org uint64(RubySystem::getNetwork()->MessageSizeType_to_int(type)); 2885568Snate@binkert.org 2895568Snate@binkert.org } 2905568Snate@binkert.org } 2915568Snate@binkert.org 2925568Snate@binkert.org out << "total_msgs: " << total_msgs 2935568Snate@binkert.org << " total_bytes: " << total_bytes << endl; 2945568Snate@binkert.org 2955568Snate@binkert.org out << endl; 2965568Snate@binkert.org for (int i = 0; i < m_switch_ptr_vector.size(); i++) { 2975568Snate@binkert.org m_switch_ptr_vector[i]->printStats(out); 2985568Snate@binkert.org } 2995568Snate@binkert.org m_topology_ptr->printStats(out); 3005568Snate@binkert.org} 3015568Snate@binkert.org 3025568Snate@binkert.orgvoid 3035568Snate@binkert.orgSimpleNetwork::clearStats() 3045568Snate@binkert.org{ 3055568Snate@binkert.org for (int i = 0; i < m_switch_ptr_vector.size(); i++) { 3065568Snate@binkert.org m_switch_ptr_vector[i]->clearStats(); 3072SN/A } 3082SN/A m_topology_ptr->clearStats(); 3092SN/A} 3102SN/A 3115568Snate@binkert.orgvoid 312596SN/ASimpleNetwork::printConfig(ostream& out) const 313596SN/A{ 314596SN/A out << endl; 315596SN/A out << "Network Configuration" << endl; 316596SN/A out << "---------------------" << endl; 317596SN/A out << "network: SIMPLE_NETWORK" << endl; 3185568Snate@binkert.org out << "topology: " << m_topology_ptr->getName() << endl; 319596SN/A out << endl; 320596SN/A 321596SN/A for (int i = 0; i < m_virtual_networks; i++) { 322596SN/A out << "virtual_net_" << i << ": "; 323596SN/A if (m_in_use[i]) { 324596SN/A out << "active, "; 3255568Snate@binkert.org if (m_ordered[i]) { 3262SN/A out << "ordered" << endl; 327710SN/A } else { 3282SN/A out << "unordered" << endl; 3294997Sgblack@eecs.umich.edu } 3302680Sktlim@umich.edu } else { 3312680Sktlim@umich.edu out << "inactive" << endl; 3324997Sgblack@eecs.umich.edu } 3332SN/A } 3342SN/A out << endl; 3355568Snate@binkert.org 3362SN/A for(int i = 0; i < m_switch_ptr_vector.size(); i++) { 3372SN/A m_switch_ptr_vector[i]->printConfig(out); 3382SN/A } 3392SN/A 3405568Snate@binkert.org m_topology_ptr->printConfig(out); 3412SN/A} 3422SN/A 3432SN/Avoid 3442SN/ASimpleNetwork::print(ostream& out) const 3455568Snate@binkert.org{ 3465568Snate@binkert.org out << "[SimpleNetwork]"; 3472SN/A} 3482SN/A 3492SN/A 3502SN/ASimpleNetwork * 3515568Snate@binkert.orgSimpleNetworkParams::create() 3522SN/A{ 3532SN/A return new SimpleNetwork(this); 3542SN/A} 3552SN/A