Switch.cc revision 8229:78bf55f23338
11060SN/A/* 27944SGiacomo.Gabrielli@arm.com * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 37944SGiacomo.Gabrielli@arm.com * All rights reserved. 47944SGiacomo.Gabrielli@arm.com * 57944SGiacomo.Gabrielli@arm.com * Redistribution and use in source and binary forms, with or without 67944SGiacomo.Gabrielli@arm.com * modification, are permitted provided that the following conditions are 77944SGiacomo.Gabrielli@arm.com * met: redistributions of source code must retain the above copyright 87944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer; 97944SGiacomo.Gabrielli@arm.com * redistributions in binary form must reproduce the above copyright 107944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer in the 117944SGiacomo.Gabrielli@arm.com * documentation and/or other materials provided with the distribution; 127944SGiacomo.Gabrielli@arm.com * neither the name of the copyright holders nor the names of its 137944SGiacomo.Gabrielli@arm.com * contributors may be used to endorse or promote products derived from 142702Sktlim@umich.edu * this software without specific prior written permission. 156973Stjones1@inf.ed.ac.uk * 161060SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171060SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181060SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191060SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201060SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211060SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221060SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231060SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241060SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251060SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261060SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271060SN/A */ 281060SN/A 291060SN/A#include <numeric> 301060SN/A 311060SN/A#include "base/stl_helpers.hh" 321060SN/A#include "mem/protocol/MessageSizeType.hh" 331060SN/A#include "mem/protocol/Protocol.hh" 341060SN/A#include "mem/ruby/buffers/MessageBuffer.hh" 351060SN/A#include "mem/ruby/network/simple/PerfectSwitch.hh" 361060SN/A#include "mem/ruby/network/simple/Switch.hh" 371060SN/A#include "mem/ruby/network/simple/Throttle.hh" 381060SN/A#include "mem/ruby/network/Network.hh" 391060SN/A 402665Ssaidi@eecs.umich.eduusing namespace std; 412665Ssaidi@eecs.umich.eduusing m5::stl_helpers::deletePointers; 426973Stjones1@inf.ed.ac.ukusing m5::stl_helpers::operator<<; 431060SN/A 441060SN/ASwitch::Switch(SwitchID sid, SimpleNetwork* network_ptr) 451464SN/A{ 461464SN/A m_perfect_switch_ptr = new PerfectSwitch(sid, network_ptr); 471060SN/A m_switch_id = sid; 482731Sktlim@umich.edu} 492292SN/A 501464SN/ASwitch::~Switch() 518733Sgeoffrey.blake@arm.com{ 521060SN/A delete m_perfect_switch_ptr; 532669Sktlim@umich.edu 547720Sgblack@eecs.umich.edu // Delete throttles (one per output port) 551060SN/A deletePointers(m_throttles); 561060SN/A 571858SN/A // Delete MessageBuffers 586658Snate@binkert.org deletePointers(m_buffers_to_free); 598733Sgeoffrey.blake@arm.com} 603770Sgblack@eecs.umich.edu 611464SN/Avoid 621464SN/ASwitch::addInPort(const vector<MessageBuffer*>& in) 632669Sktlim@umich.edu{ 641060SN/A m_perfect_switch_ptr->addInPort(in); 656973Stjones1@inf.ed.ac.uk} 662669Sktlim@umich.edu 677678Sgblack@eecs.umich.eduvoid 682292SN/ASwitch::addOutPort(const vector<MessageBuffer*>& out, 696023Snate@binkert.org const NetDest& routing_table_entry, int link_latency, int bw_multiplier) 701060SN/A{ 711060SN/A Throttle* throttle_ptr = NULL; 721060SN/A 731060SN/A // Create a throttle 741060SN/A throttle_ptr = new Throttle(m_switch_id, m_throttles.size(), link_latency, 751060SN/A bw_multiplier); 761060SN/A m_throttles.push_back(throttle_ptr); 771061SN/A 781060SN/A // Create one buffer per vnet (these are intermediaryQueues) 791060SN/A vector<MessageBuffer*> intermediateBuffers; 801060SN/A for (int i = 0; i < out.size(); i++) { 812733Sktlim@umich.edu MessageBuffer* buffer_ptr = new MessageBuffer; 822733Sktlim@umich.edu // Make these queues ordered 831060SN/A buffer_ptr->setOrdering(true); 842292SN/A Network* net_ptr = RubySystem::getNetwork(); 852107SN/A if (net_ptr->getBufferSize() > 0) { 862690Sktlim@umich.edu buffer_ptr->resize(net_ptr->getBufferSize()); 872107SN/A } 882690Sktlim@umich.edu intermediateBuffers.push_back(buffer_ptr); 892690Sktlim@umich.edu m_buffers_to_free.push_back(buffer_ptr); 901060SN/A } 912292SN/A 922292SN/A // Hook the queues to the PerfectSwitch 938486Sgblack@eecs.umich.edu m_perfect_switch_ptr->addOutPort(intermediateBuffers, routing_table_entry); 942292SN/A 952292SN/A // Hook the queues to the Throttle 962292SN/A throttle_ptr->addLinks(intermediateBuffers, out); 972292SN/A} 981060SN/A 995543Ssaidi@eecs.umich.eduvoid 1005543Ssaidi@eecs.umich.eduSwitch::clearRoutingTables() 1011060SN/A{ 1021060SN/A m_perfect_switch_ptr->clearRoutingTables(); 1032292SN/A} 1042107SN/A 1058502Sgblack@eecs.umich.eduvoid 1061060SN/ASwitch::clearBuffers() 1071060SN/A{ 1081060SN/A m_perfect_switch_ptr->clearBuffers(); 1091060SN/A for (int i = 0; i < m_throttles.size(); i++) { 1101060SN/A if (m_throttles[i] != NULL) { 1111060SN/A m_throttles[i]->clear(); 1122292SN/A } 1131060SN/A } 1141060SN/A} 1155358Sgblack@eecs.umich.edu 1165358Sgblack@eecs.umich.eduvoid 1175358Sgblack@eecs.umich.eduSwitch::reconfigureOutPort(const NetDest& routing_table_entry) 1185358Sgblack@eecs.umich.edu{ 1195358Sgblack@eecs.umich.edu m_perfect_switch_ptr->reconfigureOutPort(routing_table_entry); 1205358Sgblack@eecs.umich.edu} 1215358Sgblack@eecs.umich.edu 1225358Sgblack@eecs.umich.educonst Throttle* 1235358Sgblack@eecs.umich.eduSwitch::getThrottle(LinkID link_number) const 1245358Sgblack@eecs.umich.edu{ 1255358Sgblack@eecs.umich.edu assert(m_throttles[link_number] != NULL); 1265358Sgblack@eecs.umich.edu return m_throttles[link_number]; 1275358Sgblack@eecs.umich.edu} 1288444Sgblack@eecs.umich.edu 1297520Sgblack@eecs.umich.educonst vector<Throttle*>* 1308444Sgblack@eecs.umich.eduSwitch::getThrottles() const 1318444Sgblack@eecs.umich.edu{ 1327520Sgblack@eecs.umich.edu return &m_throttles; 1336974Stjones1@inf.ed.ac.uk} 1346974Stjones1@inf.ed.ac.uk 1356974Stjones1@inf.ed.ac.ukvoid 1366974Stjones1@inf.ed.ac.ukSwitch::printStats(std::ostream& out) const 1376973Stjones1@inf.ed.ac.uk{ 1386974Stjones1@inf.ed.ac.uk ccprintf(out, "switch_%d_inlinks: %d\n", m_switch_id, 1396974Stjones1@inf.ed.ac.uk m_perfect_switch_ptr->getInLinks()); 1406973Stjones1@inf.ed.ac.uk ccprintf(out, "switch_%d_outlinks: %d\n", m_switch_id, 1416973Stjones1@inf.ed.ac.uk m_perfect_switch_ptr->getOutLinks()); 1426973Stjones1@inf.ed.ac.uk 1436973Stjones1@inf.ed.ac.uk // Average link utilizations 1441060SN/A double average_utilization = 0.0; 1457944SGiacomo.Gabrielli@arm.com int throttle_count = 0; 1467944SGiacomo.Gabrielli@arm.com 1477944SGiacomo.Gabrielli@arm.com for (int i = 0; i < m_throttles.size(); i++) { 1487944SGiacomo.Gabrielli@arm.com Throttle* throttle_ptr = m_throttles[i]; 1497944SGiacomo.Gabrielli@arm.com if (throttle_ptr) { 1507944SGiacomo.Gabrielli@arm.com average_utilization += throttle_ptr->getUtilization(); 1518545Ssaidi@eecs.umich.edu throttle_count++; 1528545Ssaidi@eecs.umich.edu } 1538545Ssaidi@eecs.umich.edu } 1548545Ssaidi@eecs.umich.edu average_utilization = 1558545Ssaidi@eecs.umich.edu throttle_count == 0 ? 0 : average_utilization / throttle_count; 1568545Ssaidi@eecs.umich.edu 1578545Ssaidi@eecs.umich.edu // Individual link utilizations 1588545Ssaidi@eecs.umich.edu out << "links_utilized_percent_switch_" << m_switch_id << ": " 1598545Ssaidi@eecs.umich.edu << average_utilization << endl; 1608545Ssaidi@eecs.umich.edu 1618545Ssaidi@eecs.umich.edu for (int link = 0; link < m_throttles.size(); link++) { 1628545Ssaidi@eecs.umich.edu Throttle* throttle_ptr = m_throttles[link]; 1638545Ssaidi@eecs.umich.edu if (throttle_ptr != NULL) { 1647944SGiacomo.Gabrielli@arm.com out << " links_utilized_percent_switch_" << m_switch_id 1657944SGiacomo.Gabrielli@arm.com << "_link_" << link << ": " 1667944SGiacomo.Gabrielli@arm.com << throttle_ptr->getUtilization() << " bw: " 1677944SGiacomo.Gabrielli@arm.com << throttle_ptr->getLinkBandwidth() 1687944SGiacomo.Gabrielli@arm.com << " base_latency: " << throttle_ptr->getLatency() << endl; 1697944SGiacomo.Gabrielli@arm.com } 1707944SGiacomo.Gabrielli@arm.com } 1717944SGiacomo.Gabrielli@arm.com out << endl; 1727944SGiacomo.Gabrielli@arm.com 1737944SGiacomo.Gabrielli@arm.com // Traffic breakdown 1747944SGiacomo.Gabrielli@arm.com for (int link = 0; link < m_throttles.size(); link++) { 1757944SGiacomo.Gabrielli@arm.com Throttle* throttle_ptr = m_throttles[link]; 1767944SGiacomo.Gabrielli@arm.com if (!throttle_ptr) 1777944SGiacomo.Gabrielli@arm.com continue; 1787944SGiacomo.Gabrielli@arm.com 1797944SGiacomo.Gabrielli@arm.com const vector<vector<int> >& message_counts = 1807944SGiacomo.Gabrielli@arm.com throttle_ptr->getCounters(); 1818733Sgeoffrey.blake@arm.com for (int int_type = 0; int_type < MessageSizeType_NUM; int_type++) { 1828733Sgeoffrey.blake@arm.com MessageSizeType type = MessageSizeType(int_type); 1838733Sgeoffrey.blake@arm.com const vector<int> &mct = message_counts[type]; 1848733Sgeoffrey.blake@arm.com int sum = accumulate(mct.begin(), mct.end(), 0); 1858733Sgeoffrey.blake@arm.com if (sum == 0) 1861684SN/A continue; 1871060SN/A 1881060SN/A out << " outgoing_messages_switch_" << m_switch_id 1891060SN/A << "_link_" << link << "_" << type << ": " << sum << " " 1901060SN/A << sum * RubySystem::getNetwork()->MessageSizeType_to_int(type) 1912731Sktlim@umich.edu << " "; 1922731Sktlim@umich.edu out << mct; 1932731Sktlim@umich.edu out << " base_latency: " 1942731Sktlim@umich.edu << throttle_ptr->getLatency() << endl; 1952731Sktlim@umich.edu } 1962731Sktlim@umich.edu } 1972731Sktlim@umich.edu out << endl; 1982731Sktlim@umich.edu} 1992731Sktlim@umich.edu 2002731Sktlim@umich.eduvoid 2012731Sktlim@umich.eduSwitch::clearStats() 2022731Sktlim@umich.edu{ 2032731Sktlim@umich.edu m_perfect_switch_ptr->clearStats(); 2042731Sktlim@umich.edu for (int i = 0; i < m_throttles.size(); i++) { 2052731Sktlim@umich.edu if (m_throttles[i] != NULL) 2062731Sktlim@umich.edu m_throttles[i]->clearStats(); 2072731Sktlim@umich.edu } 2082731Sktlim@umich.edu} 2092731Sktlim@umich.edu 2102731Sktlim@umich.eduvoid 2112731Sktlim@umich.eduSwitch::printConfig(std::ostream& out) const 2122731Sktlim@umich.edu{ 2132731Sktlim@umich.edu m_perfect_switch_ptr->printConfig(out); 2142731Sktlim@umich.edu for (int i = 0; i < m_throttles.size(); i++) { 2152731Sktlim@umich.edu if (m_throttles[i] != NULL) 2162292SN/A m_throttles[i]->printConfig(out); 2172731Sktlim@umich.edu } 2182731Sktlim@umich.edu} 2191060SN/A 2201060SN/Avoid 2216221Snate@binkert.orgSwitch::print(std::ostream& out) const 2221060SN/A{ 2231060SN/A // FIXME printing 2241060SN/A out << "[Switch]"; 2251060SN/A} 2262292SN/A 2272292SN/A