Switch.cc revision 9858
12623SN/A/* 210030SAli.Saidi@ARM.com * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 38926Sandreas.hansson@arm.com * All rights reserved. 48926Sandreas.hansson@arm.com * 58926Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68926Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 78926Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 88926Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 98926Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 108926Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 118926Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 128926Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 138926Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 142623SN/A * this software without specific prior written permission. 152623SN/A * 162623SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172623SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182623SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192623SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202623SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212623SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222623SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232623SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242623SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252623SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262623SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272623SN/A */ 282623SN/A 292623SN/A#include <numeric> 302623SN/A 312623SN/A#include "base/cast.hh" 322623SN/A#include "base/stl_helpers.hh" 332623SN/A#include "mem/protocol/MessageSizeType.hh" 342623SN/A#include "mem/ruby/buffers/MessageBuffer.hh" 352623SN/A#include "mem/ruby/network/simple/PerfectSwitch.hh" 362623SN/A#include "mem/ruby/network/simple/SimpleNetwork.hh" 372623SN/A#include "mem/ruby/network/simple/Switch.hh" 382623SN/A#include "mem/ruby/network/simple/Throttle.hh" 392665Ssaidi@eecs.umich.edu 402665Ssaidi@eecs.umich.eduusing namespace std; 412623SN/Ausing m5::stl_helpers::deletePointers; 422623SN/Ausing m5::stl_helpers::operator<<; 433170Sstever@eecs.umich.edu 448105Sgblack@eecs.umich.eduSwitch::Switch(const Params *p) : BasicRouter(p) 452623SN/A{ 464040Ssaidi@eecs.umich.edu m_perfect_switch = new PerfectSwitch(m_id, this, p->virt_nets); 479647Sdam.sunwoo@arm.com} 486658Snate@binkert.org 498229Snate@binkert.orgSwitch::~Switch() 502623SN/A{ 519443SAndreas.Sandberg@ARM.com delete m_perfect_switch; 528232Snate@binkert.org 538232Snate@binkert.org // Delete throttles (one per output port) 543348Sbinkertn@umich.edu deletePointers(m_throttles); 553348Sbinkertn@umich.edu 568926Sandreas.hansson@arm.com // Delete MessageBuffers 574762Snate@binkert.org deletePointers(m_buffers_to_free); 587678Sgblack@eecs.umich.edu} 592901Ssaidi@eecs.umich.edu 608779Sgblack@eecs.umich.eduvoid 612623SN/ASwitch::init() 622623SN/A{ 632623SN/A BasicRouter::init(); 642623SN/A m_perfect_switch->init(m_network_ptr); 652623SN/A} 665606Snate@binkert.org 672623SN/Avoid 682623SN/ASwitch::addInPort(const vector<MessageBuffer*>& in) 692623SN/A{ 702623SN/A m_perfect_switch->addInPort(in); 712623SN/A 722623SN/A for (int i = 0; i < in.size(); i++) { 732623SN/A in[i]->setReceiver(this); 742623SN/A } 752623SN/A} 762623SN/A 772623SN/Avoid 785336Shines@cs.fsu.eduSwitch::addOutPort(const vector<MessageBuffer*>& out, 792623SN/A const NetDest& routing_table_entry, Cycles link_latency, int bw_multiplier) 804873Sstever@eecs.umich.edu{ 812623SN/A // Create a throttle 822623SN/A Throttle* throttle_ptr = new Throttle(m_id, m_throttles.size(), 832623SN/A link_latency, bw_multiplier, m_network_ptr->getEndpointBandwidth(), 842623SN/A this); 852623SN/A m_throttles.push_back(throttle_ptr); 862623SN/A 878921Sandreas.hansson@arm.com // Create one buffer per vnet (these are intermediaryQueues) 888921Sandreas.hansson@arm.com vector<MessageBuffer*> intermediateBuffers; 898921Sandreas.hansson@arm.com for (int i = 0; i < out.size(); i++) { 908921Sandreas.hansson@arm.com out[i]->setSender(this); 919433SAndreas.Sandberg@ARM.com 928779Sgblack@eecs.umich.edu MessageBuffer* buffer_ptr = new MessageBuffer; 938779Sgblack@eecs.umich.edu // Make these queues ordered 948779Sgblack@eecs.umich.edu buffer_ptr->setOrdering(true); 958779Sgblack@eecs.umich.edu if (m_network_ptr->getBufferSize() > 0) { 968779Sgblack@eecs.umich.edu buffer_ptr->resize(m_network_ptr->getBufferSize()); 978779Sgblack@eecs.umich.edu } 982623SN/A 998706Sandreas.hansson@arm.com intermediateBuffers.push_back(buffer_ptr); 1005714Shsul@eecs.umich.edu m_buffers_to_free.push_back(buffer_ptr); 1015712Shsul@eecs.umich.edu 1025712Shsul@eecs.umich.edu buffer_ptr->setSender(this); 1035712Shsul@eecs.umich.edu buffer_ptr->setReceiver(this); 1042623SN/A } 1052623SN/A 1065529Snate@binkert.org // Hook the queues to the PerfectSwitch 1076078Sgblack@eecs.umich.edu m_perfect_switch->addOutPort(intermediateBuffers, routing_table_entry); 1085487Snate@binkert.org 1095487Snate@binkert.org // Hook the queues to the Throttle 1109443SAndreas.Sandberg@ARM.com throttle_ptr->addLinks(intermediateBuffers, out); 1119095Sandreas.hansson@arm.com} 1129095Sandreas.hansson@arm.com 11310381Sdam.sunwoo@arm.comvoid 1142623SN/ASwitch::clearRoutingTables() 1152623SN/A{ 1162623SN/A m_perfect_switch->clearRoutingTables(); 1172623SN/A} 1182623SN/A 1192623SN/Avoid 1202623SN/ASwitch::clearBuffers() 1216775SBrad.Beckmann@amd.com{ 1226775SBrad.Beckmann@amd.com m_perfect_switch->clearBuffers(); 1236775SBrad.Beckmann@amd.com for (int i = 0; i < m_throttles.size(); i++) { 1242623SN/A if (m_throttles[i] != NULL) { 1252623SN/A m_throttles[i]->clear(); 1269443SAndreas.Sandberg@ARM.com } 1279443SAndreas.Sandberg@ARM.com } 1282623SN/A} 1299443SAndreas.Sandberg@ARM.com 1309448SAndreas.Sandberg@ARM.comvoid 1319443SAndreas.Sandberg@ARM.comSwitch::reconfigureOutPort(const NetDest& routing_table_entry) 1322623SN/A{ 1339443SAndreas.Sandberg@ARM.com m_perfect_switch->reconfigureOutPort(routing_table_entry); 1349443SAndreas.Sandberg@ARM.com} 1359443SAndreas.Sandberg@ARM.com 1369443SAndreas.Sandberg@ARM.comconst Throttle* 1379443SAndreas.Sandberg@ARM.comSwitch::getThrottle(LinkID link_number) const 1389443SAndreas.Sandberg@ARM.com{ 1399443SAndreas.Sandberg@ARM.com assert(m_throttles[link_number] != NULL); 1402915Sktlim@umich.edu return m_throttles[link_number]; 1419443SAndreas.Sandberg@ARM.com} 1429443SAndreas.Sandberg@ARM.com 1439443SAndreas.Sandberg@ARM.comconst vector<Throttle*>* 1449342SAndreas.Sandberg@arm.comSwitch::getThrottles() const 1459342SAndreas.Sandberg@arm.com{ 1462915Sktlim@umich.edu return &m_throttles; 1479342SAndreas.Sandberg@arm.com} 1482915Sktlim@umich.edu 1499448SAndreas.Sandberg@ARM.comvoid 1509443SAndreas.Sandberg@ARM.comSwitch::printStats(std::ostream& out) const 1519448SAndreas.Sandberg@ARM.com{ 1525220Ssaidi@eecs.umich.edu ccprintf(out, "switch_%d_inlinks: %d\n", m_id, 1535220Ssaidi@eecs.umich.edu m_perfect_switch->getInLinks()); 1544940Snate@binkert.org ccprintf(out, "switch_%d_outlinks: %d\n", m_id, 1559523SAndreas.Sandberg@ARM.com m_perfect_switch->getOutLinks()); 1563324Shsul@eecs.umich.edu 1579448SAndreas.Sandberg@ARM.com // Average link utilizations 1589448SAndreas.Sandberg@ARM.com double average_utilization = 0.0; 1599448SAndreas.Sandberg@ARM.com int throttle_count = 0; 1609448SAndreas.Sandberg@ARM.com 1619448SAndreas.Sandberg@ARM.com for (int i = 0; i < m_throttles.size(); i++) { 1629443SAndreas.Sandberg@ARM.com Throttle* throttle_ptr = m_throttles[i]; 1639448SAndreas.Sandberg@ARM.com if (throttle_ptr) { 1649837Slena@cs.wisc,edu average_utilization += throttle_ptr->getUtilization(); 1659448SAndreas.Sandberg@ARM.com throttle_count++; 1669448SAndreas.Sandberg@ARM.com } 1679837Slena@cs.wisc,edu } 1689448SAndreas.Sandberg@ARM.com average_utilization = 1699443SAndreas.Sandberg@ARM.com throttle_count == 0 ? 0 : average_utilization / throttle_count; 1707897Shestness@cs.utexas.edu 1712623SN/A // Individual link utilizations 1722623SN/A out << "links_utilized_percent_switch_" << m_id << ": " 1739443SAndreas.Sandberg@ARM.com << average_utilization << endl; 1749443SAndreas.Sandberg@ARM.com 1759443SAndreas.Sandberg@ARM.com for (int link = 0; link < m_throttles.size(); link++) { 1769443SAndreas.Sandberg@ARM.com Throttle* throttle_ptr = m_throttles[link]; 1779443SAndreas.Sandberg@ARM.com if (throttle_ptr != NULL) { 1789443SAndreas.Sandberg@ARM.com out << " links_utilized_percent_switch_" << m_id 1799443SAndreas.Sandberg@ARM.com << "_link_" << link << ": " 1809443SAndreas.Sandberg@ARM.com << throttle_ptr->getUtilization() << " bw: " 1819443SAndreas.Sandberg@ARM.com << throttle_ptr->getLinkBandwidth() 1829443SAndreas.Sandberg@ARM.com << " base_latency: " << throttle_ptr->getLatency() << endl; 1839443SAndreas.Sandberg@ARM.com } 1849443SAndreas.Sandberg@ARM.com } 1859443SAndreas.Sandberg@ARM.com out << endl; 1869443SAndreas.Sandberg@ARM.com 1879443SAndreas.Sandberg@ARM.com // Traffic breakdown 1889443SAndreas.Sandberg@ARM.com for (int link = 0; link < m_throttles.size(); link++) { 1899443SAndreas.Sandberg@ARM.com Throttle* throttle_ptr = m_throttles[link]; 1909443SAndreas.Sandberg@ARM.com if (!throttle_ptr) 1912623SN/A continue; 1922798Sktlim@umich.edu 1932623SN/A const vector<vector<int> >& message_counts = 1949429SAndreas.Sandberg@ARM.com throttle_ptr->getCounters(); 1959429SAndreas.Sandberg@ARM.com for (int int_type = 0; int_type < MessageSizeType_NUM; int_type++) { 1969443SAndreas.Sandberg@ARM.com MessageSizeType type = MessageSizeType(int_type); 1979342SAndreas.Sandberg@arm.com const vector<int> &mct = message_counts[type]; 1989443SAndreas.Sandberg@ARM.com int sum = accumulate(mct.begin(), mct.end(), 0); 1992623SN/A if (sum == 0) 2002623SN/A continue; 2012623SN/A 2022623SN/A out << " outgoing_messages_switch_" << m_id 2032623SN/A << "_link_" << link << "_" << type << ": " << sum << " " 2042623SN/A << sum * m_network_ptr->MessageSizeType_to_int(type) 2059429SAndreas.Sandberg@ARM.com << " "; 2062623SN/A out << mct; 2079443SAndreas.Sandberg@ARM.com out << " base_latency: " 2082623SN/A << throttle_ptr->getLatency() << endl; 2092623SN/A } 2105712Shsul@eecs.umich.edu } 2115712Shsul@eecs.umich.edu out << endl; 2125712Shsul@eecs.umich.edu} 2132623SN/A 2142623SN/Avoid 2159523SAndreas.Sandberg@ARM.comSwitch::clearStats() 2169523SAndreas.Sandberg@ARM.com{ 2179523SAndreas.Sandberg@ARM.com m_perfect_switch->clearStats(); 2189524SAndreas.Sandberg@ARM.com for (int i = 0; i < m_throttles.size(); i++) { 2199523SAndreas.Sandberg@ARM.com if (m_throttles[i] != NULL) 2209523SAndreas.Sandberg@ARM.com m_throttles[i]->clearStats(); 2219523SAndreas.Sandberg@ARM.com } 2229523SAndreas.Sandberg@ARM.com} 2232623SN/A 2242623SN/Avoid 22510407Smitch.hayenga@arm.comSwitch::print(std::ostream& out) const 2262623SN/A{ 22710407Smitch.hayenga@arm.com // FIXME printing 2284940Snate@binkert.org out << "[Switch]"; 2292623SN/A} 2302683Sktlim@umich.edu 2312623SN/Abool 2322623SN/ASwitch::functionalRead(Packet *pkt) 2332623SN/A{ 2342623SN/A // Access the buffers in the switch for performing a functional read 2359837Slena@cs.wisc,edu for (unsigned int i = 0; i < m_buffers_to_free.size(); ++i) { 23610464SAndreas.Sandberg@ARM.com if (m_buffers_to_free[i]->functionalRead(pkt)) { 23710464SAndreas.Sandberg@ARM.com return true; 23810464SAndreas.Sandberg@ARM.com } 2393686Sktlim@umich.edu } 2403430Sgblack@eecs.umich.edu return false; 24110407Smitch.hayenga@arm.com} 2429342SAndreas.Sandberg@arm.com 2432623SN/Auint32_t 2442623SN/ASwitch::functionalWrite(Packet *pkt) 2452623SN/A{ 2462623SN/A // Access the buffers in the switch for performing a functional write 2478737Skoansin.tan@gmail.com uint32_t num_functional_writes = 0; 2482623SN/A for (unsigned int i = 0; i < m_buffers_to_free.size(); ++i) { 2494940Snate@binkert.org num_functional_writes += m_buffers_to_free[i]->functionalWrite(pkt); 2504940Snate@binkert.org } 2512623SN/A return num_functional_writes; 2522683Sktlim@umich.edu} 2532623SN/A 2546043Sgblack@eecs.umich.eduSwitch * 2556043Sgblack@eecs.umich.eduSwitchParams::create() 2566043Sgblack@eecs.umich.edu{ 2579342SAndreas.Sandberg@arm.com return new Switch(this); 2582626SN/A} 2592626SN/A