Switch.cc revision 9508
12623SN/A/* 210596Sgabeblack@google.com * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 311147Smitch.hayenga@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 148926Sandreas.hansson@arm.com * 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" 392623SN/A 402665Ssaidi@eecs.umich.eduusing namespace std; 412665Ssaidi@eecs.umich.eduusing m5::stl_helpers::deletePointers; 422623SN/Ausing m5::stl_helpers::operator<<; 432623SN/A 443170Sstever@eecs.umich.eduSwitch::Switch(const Params *p) : BasicRouter(p) 458105Sgblack@eecs.umich.edu{ 462623SN/A m_perfect_switch_ptr = new PerfectSwitch(m_id, this, p->virt_nets); 474040Ssaidi@eecs.umich.edu} 489647Sdam.sunwoo@arm.com 496658Snate@binkert.orgSwitch::~Switch() 508229Snate@binkert.org{ 512623SN/A delete m_perfect_switch_ptr; 529443SAndreas.Sandberg@ARM.com 538232Snate@binkert.org // Delete throttles (one per output port) 548232Snate@binkert.org deletePointers(m_throttles); 553348Sbinkertn@umich.edu 563348Sbinkertn@umich.edu // Delete MessageBuffers 578926Sandreas.hansson@arm.com deletePointers(m_buffers_to_free); 584762Snate@binkert.org} 597678Sgblack@eecs.umich.edu 602901Ssaidi@eecs.umich.eduvoid 618779Sgblack@eecs.umich.eduSwitch::init() 622623SN/A{ 632623SN/A BasicRouter::init(); 642623SN/A m_perfect_switch_ptr->init(m_network_ptr); 652623SN/A} 662623SN/A 675606Snate@binkert.orgvoid 682623SN/ASwitch::addInPort(const vector<MessageBuffer*>& in) 692623SN/A{ 702623SN/A m_perfect_switch_ptr->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 782623SN/ASwitch::addOutPort(const vector<MessageBuffer*>& out, 795336Shines@cs.fsu.edu const NetDest& routing_table_entry, Cycles link_latency, int bw_multiplier) 802623SN/A{ 814873Sstever@eecs.umich.edu // 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 8711147Smitch.hayenga@arm.com // Create one buffer per vnet (these are intermediaryQueues) 888921Sandreas.hansson@arm.com vector<MessageBuffer*> intermediateBuffers; 8911147Smitch.hayenga@arm.com for (int i = 0; i < out.size(); i++) { 9011147Smitch.hayenga@arm.com out[i]->setSender(this); 9111147Smitch.hayenga@arm.com 922623SN/A MessageBuffer* buffer_ptr = new MessageBuffer; 932623SN/A // Make these queues ordered 945529Snate@binkert.org buffer_ptr->setOrdering(true); 956078Sgblack@eecs.umich.edu if (m_network_ptr->getBufferSize() > 0) { 965487Snate@binkert.org buffer_ptr->resize(m_network_ptr->getBufferSize()); 975487Snate@binkert.org } 989095Sandreas.hansson@arm.com 999095Sandreas.hansson@arm.com intermediateBuffers.push_back(buffer_ptr); 10010537Sandreas.hansson@arm.com m_buffers_to_free.push_back(buffer_ptr); 10110537Sandreas.hansson@arm.com 1022623SN/A buffer_ptr->setSender(this); 1032623SN/A buffer_ptr->setReceiver(this); 1042623SN/A } 1052623SN/A 1062623SN/A // Hook the queues to the PerfectSwitch 1072623SN/A m_perfect_switch_ptr->addOutPort(intermediateBuffers, routing_table_entry); 1082623SN/A 1096775SBrad.Beckmann@amd.com // Hook the queues to the Throttle 1106775SBrad.Beckmann@amd.com throttle_ptr->addLinks(intermediateBuffers, out); 1116775SBrad.Beckmann@amd.com} 1122623SN/A 1132623SN/Avoid 11410913Sandreas.sandberg@arm.comSwitch::clearRoutingTables() 11510913Sandreas.sandberg@arm.com{ 1162623SN/A m_perfect_switch_ptr->clearRoutingTables(); 1179448SAndreas.Sandberg@ARM.com} 11810913Sandreas.sandberg@arm.com 1192623SN/Avoid 1209443SAndreas.Sandberg@ARM.comSwitch::clearBuffers() 12111147Smitch.hayenga@arm.com{ 12210913Sandreas.sandberg@arm.com m_perfect_switch_ptr->clearBuffers(); 1239443SAndreas.Sandberg@ARM.com for (int i = 0; i < m_throttles.size(); i++) { 1249443SAndreas.Sandberg@ARM.com if (m_throttles[i] != NULL) { 1259443SAndreas.Sandberg@ARM.com m_throttles[i]->clear(); 1262915Sktlim@umich.edu } 12711147Smitch.hayenga@arm.com } 1289443SAndreas.Sandberg@ARM.com} 12910913Sandreas.sandberg@arm.com 1309443SAndreas.Sandberg@ARM.comvoid 1319342SAndreas.Sandberg@arm.comSwitch::reconfigureOutPort(const NetDest& routing_table_entry) 1329342SAndreas.Sandberg@arm.com{ 1332915Sktlim@umich.edu m_perfect_switch_ptr->reconfigureOutPort(routing_table_entry); 1349342SAndreas.Sandberg@arm.com} 1352915Sktlim@umich.edu 1369448SAndreas.Sandberg@ARM.comconst Throttle* 1379448SAndreas.Sandberg@ARM.comSwitch::getThrottle(LinkID link_number) const 1385220Ssaidi@eecs.umich.edu{ 1395220Ssaidi@eecs.umich.edu assert(m_throttles[link_number] != NULL); 1404940Snate@binkert.org return m_throttles[link_number]; 1419523SAndreas.Sandberg@ARM.com} 1423324Shsul@eecs.umich.edu 1439448SAndreas.Sandberg@ARM.comconst vector<Throttle*>* 1449448SAndreas.Sandberg@ARM.comSwitch::getThrottles() const 14511147Smitch.hayenga@arm.com{ 14611147Smitch.hayenga@arm.com return &m_throttles; 14711147Smitch.hayenga@arm.com} 14811147Smitch.hayenga@arm.com 14911147Smitch.hayenga@arm.comvoid 15011147Smitch.hayenga@arm.comSwitch::printStats(std::ostream& out) const 15111147Smitch.hayenga@arm.com{ 15211147Smitch.hayenga@arm.com ccprintf(out, "switch_%d_inlinks: %d\n", m_id, 15311147Smitch.hayenga@arm.com m_perfect_switch_ptr->getInLinks()); 15411147Smitch.hayenga@arm.com ccprintf(out, "switch_%d_outlinks: %d\n", m_id, 15511147Smitch.hayenga@arm.com m_perfect_switch_ptr->getOutLinks()); 15611147Smitch.hayenga@arm.com 15711147Smitch.hayenga@arm.com // Average link utilizations 15811147Smitch.hayenga@arm.com double average_utilization = 0.0; 15911147Smitch.hayenga@arm.com int throttle_count = 0; 1609448SAndreas.Sandberg@ARM.com 1612623SN/A for (int i = 0; i < m_throttles.size(); i++) { 1622623SN/A Throttle* throttle_ptr = m_throttles[i]; 1639443SAndreas.Sandberg@ARM.com if (throttle_ptr) { 1649443SAndreas.Sandberg@ARM.com average_utilization += throttle_ptr->getUtilization(); 1659443SAndreas.Sandberg@ARM.com throttle_count++; 16610913Sandreas.sandberg@arm.com } 1679443SAndreas.Sandberg@ARM.com } 1689443SAndreas.Sandberg@ARM.com average_utilization = 16911147Smitch.hayenga@arm.com throttle_count == 0 ? 0 : average_utilization / throttle_count; 1709443SAndreas.Sandberg@ARM.com 1719443SAndreas.Sandberg@ARM.com // Individual link utilizations 1729443SAndreas.Sandberg@ARM.com out << "links_utilized_percent_switch_" << m_id << ": " 1739443SAndreas.Sandberg@ARM.com << average_utilization << endl; 17410913Sandreas.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 << ": " 1802623SN/A << throttle_ptr->getUtilization() << " bw: " 1812798Sktlim@umich.edu << throttle_ptr->getLinkBandwidth() 1822623SN/A << " base_latency: " << throttle_ptr->getLatency() << endl; 1839429SAndreas.Sandberg@ARM.com } 1849429SAndreas.Sandberg@ARM.com } 1859443SAndreas.Sandberg@ARM.com out << endl; 1869342SAndreas.Sandberg@arm.com 1879443SAndreas.Sandberg@ARM.com // Traffic breakdown 1882623SN/A for (int link = 0; link < m_throttles.size(); link++) { 1892623SN/A Throttle* throttle_ptr = m_throttles[link]; 1902623SN/A if (!throttle_ptr) 1912623SN/A continue; 1922623SN/A 1932623SN/A const vector<vector<int> >& message_counts = 1949429SAndreas.Sandberg@ARM.com throttle_ptr->getCounters(); 1952623SN/A for (int int_type = 0; int_type < MessageSizeType_NUM; int_type++) { 1969443SAndreas.Sandberg@ARM.com MessageSizeType type = MessageSizeType(int_type); 1972623SN/A const vector<int> &mct = message_counts[type]; 1982623SN/A int sum = accumulate(mct.begin(), mct.end(), 0); 1992623SN/A if (sum == 0) 2009523SAndreas.Sandberg@ARM.com continue; 2019523SAndreas.Sandberg@ARM.com 2029523SAndreas.Sandberg@ARM.com out << " outgoing_messages_switch_" << m_id 2039524SAndreas.Sandberg@ARM.com << "_link_" << link << "_" << type << ": " << sum << " " 2049523SAndreas.Sandberg@ARM.com << sum * m_network_ptr->MessageSizeType_to_int(type) 2059523SAndreas.Sandberg@ARM.com << " "; 2069523SAndreas.Sandberg@ARM.com out << mct; 2079523SAndreas.Sandberg@ARM.com out << " base_latency: " 2082623SN/A << throttle_ptr->getLatency() << endl; 2092623SN/A } 21010407Smitch.hayenga@arm.com } 2112623SN/A out << endl; 21210407Smitch.hayenga@arm.com} 2134940Snate@binkert.org 21411147Smitch.hayenga@arm.comvoid 2152623SN/ASwitch::clearStats() 21611147Smitch.hayenga@arm.com{ 21711147Smitch.hayenga@arm.com m_perfect_switch_ptr->clearStats(); 21811147Smitch.hayenga@arm.com for (int i = 0; i < m_throttles.size(); i++) { 21910464SAndreas.Sandberg@ARM.com if (m_throttles[i] != NULL) 22010464SAndreas.Sandberg@ARM.com m_throttles[i]->clearStats(); 2213686Sktlim@umich.edu } 22211147Smitch.hayenga@arm.com} 22311147Smitch.hayenga@arm.com 22411147Smitch.hayenga@arm.comvoid 22511147Smitch.hayenga@arm.comSwitch::print(std::ostream& out) const 2269342SAndreas.Sandberg@arm.com{ 22711147Smitch.hayenga@arm.com // FIXME printing 22811147Smitch.hayenga@arm.com out << "[Switch]"; 22911147Smitch.hayenga@arm.com} 23011147Smitch.hayenga@arm.com 2312623SN/Abool 2322623SN/ASwitch::functionalRead(Packet *pkt) 2332623SN/A{ 2342623SN/A // Access the buffers in the switch for performing a functional read 2358737Skoansin.tan@gmail.com for (unsigned int i = 0; i < m_buffers_to_free.size(); ++i) { 2362623SN/A if (m_buffers_to_free[i]->functionalRead(pkt)) { 2374940Snate@binkert.org return true; 2384940Snate@binkert.org } 23911147Smitch.hayenga@arm.com } 24011147Smitch.hayenga@arm.com return false; 2412623SN/A} 2426043Sgblack@eecs.umich.edu 2436043Sgblack@eecs.umich.eduuint32_t 2446043Sgblack@eecs.umich.eduSwitch::functionalWrite(Packet *pkt) 2459342SAndreas.Sandberg@arm.com{ 2462626SN/A // Access the buffers in the switch for performing a functional write 24711147Smitch.hayenga@arm.com uint32_t num_functional_writes = 0; 2482623SN/A for (unsigned int i = 0; i < m_buffers_to_free.size(); ++i) { 24911147Smitch.hayenga@arm.com num_functional_writes += m_buffers_to_free[i]->functionalWrite(pkt); 25011147Smitch.hayenga@arm.com } 25111147Smitch.hayenga@arm.com return num_functional_writes; 25211147Smitch.hayenga@arm.com} 25311147Smitch.hayenga@arm.com 25411147Smitch.hayenga@arm.comSwitch * 25511147Smitch.hayenga@arm.comSwitchParams::create() 25611147Smitch.hayenga@arm.com{ 2572623SN/A return new Switch(this); 2582623SN/A} 2592623SN/A