Switch.cc revision 7054
14309Sgblack@eecs.umich.edu/*
24309Sgblack@eecs.umich.edu * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
35426Sgblack@eecs.umich.edu * All rights reserved.
44309Sgblack@eecs.umich.edu *
54309Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
64309Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
74309Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
84309Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
94309Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
104309Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
114309Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
124309Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
134309Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
144309Sgblack@eecs.umich.edu * this software without specific prior written permission.
154309Sgblack@eecs.umich.edu *
164309Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
174309Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
184309Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
194309Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
204309Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
214309Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
224309Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
234309Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
244309Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254309Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
264309Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274309Sgblack@eecs.umich.edu */
284309Sgblack@eecs.umich.edu
294309Sgblack@eecs.umich.edu#include "mem/protocol/MessageSizeType.hh"
304309Sgblack@eecs.umich.edu#include "mem/protocol/Protocol.hh"
314309Sgblack@eecs.umich.edu#include "mem/ruby/buffers/MessageBuffer.hh"
324309Sgblack@eecs.umich.edu#include "mem/ruby/network/Network.hh"
334309Sgblack@eecs.umich.edu#include "mem/ruby/network/simple/PerfectSwitch.hh"
344309Sgblack@eecs.umich.edu#include "mem/ruby/network/simple/Switch.hh"
354309Sgblack@eecs.umich.edu#include "mem/ruby/network/simple/Throttle.hh"
364309Sgblack@eecs.umich.edu
374309Sgblack@eecs.umich.eduSwitch::Switch(SwitchID sid, SimpleNetwork* network_ptr)
384309Sgblack@eecs.umich.edu{
394309Sgblack@eecs.umich.edu    m_perfect_switch_ptr = new PerfectSwitch(sid, network_ptr);
404309Sgblack@eecs.umich.edu    m_switch_id = sid;
414309Sgblack@eecs.umich.edu    m_throttles.setSize(0);
424309Sgblack@eecs.umich.edu}
434309Sgblack@eecs.umich.edu
444309Sgblack@eecs.umich.eduSwitch::~Switch()
454309Sgblack@eecs.umich.edu{
464309Sgblack@eecs.umich.edu    delete m_perfect_switch_ptr;
474309Sgblack@eecs.umich.edu
484309Sgblack@eecs.umich.edu    // Delete throttles (one per output port)
494309Sgblack@eecs.umich.edu    m_throttles.deletePointers();
504309Sgblack@eecs.umich.edu
514309Sgblack@eecs.umich.edu    // Delete MessageBuffers
524309Sgblack@eecs.umich.edu    m_buffers_to_free.deletePointers();
534309Sgblack@eecs.umich.edu}
544309Sgblack@eecs.umich.edu
554309Sgblack@eecs.umich.eduvoid
564309Sgblack@eecs.umich.eduSwitch::addInPort(const Vector<MessageBuffer*>& in)
574309Sgblack@eecs.umich.edu{
584533Sgblack@eecs.umich.edu    m_perfect_switch_ptr->addInPort(in);
594679Sgblack@eecs.umich.edu}
604679Sgblack@eecs.umich.edu
614679Sgblack@eecs.umich.eduvoid
624533Sgblack@eecs.umich.eduSwitch::addOutPort(const Vector<MessageBuffer*>& out,
634533Sgblack@eecs.umich.edu    const NetDest& routing_table_entry, int link_latency, int bw_multiplier)
644537Sgblack@eecs.umich.edu{
654533Sgblack@eecs.umich.edu    Throttle* throttle_ptr = NULL;
664528Sgblack@eecs.umich.edu
675666Sgblack@eecs.umich.edu    // Create a throttle
685666Sgblack@eecs.umich.edu    throttle_ptr = new Throttle(m_switch_id, m_throttles.size(), link_latency,
695666Sgblack@eecs.umich.edu        bw_multiplier);
704528Sgblack@eecs.umich.edu    m_throttles.insertAtBottom(throttle_ptr);
714528Sgblack@eecs.umich.edu
724528Sgblack@eecs.umich.edu    // Create one buffer per vnet (these are intermediaryQueues)
734528Sgblack@eecs.umich.edu    Vector<MessageBuffer*> intermediateBuffers;
744605Sgblack@eecs.umich.edu    for (int i = 0; i < out.size(); i++) {
755666Sgblack@eecs.umich.edu        MessageBuffer* buffer_ptr = new MessageBuffer;
765666Sgblack@eecs.umich.edu        // Make these queues ordered
774528Sgblack@eecs.umich.edu        buffer_ptr->setOrdering(true);
786345Sgblack@eecs.umich.edu        Network* net_ptr = RubySystem::getNetwork();
796345Sgblack@eecs.umich.edu        if (net_ptr->getBufferSize() > 0) {
806345Sgblack@eecs.umich.edu            buffer_ptr->setSize(net_ptr->getBufferSize());
816345Sgblack@eecs.umich.edu        }
826345Sgblack@eecs.umich.edu        intermediateBuffers.insertAtBottom(buffer_ptr);
836345Sgblack@eecs.umich.edu        m_buffers_to_free.insertAtBottom(buffer_ptr);
844615Sgblack@eecs.umich.edu  }
855854Sgblack@eecs.umich.edu
866345Sgblack@eecs.umich.edu    // Hook the queues to the PerfectSwitch
875854Sgblack@eecs.umich.edu    m_perfect_switch_ptr->addOutPort(intermediateBuffers, routing_table_entry);
886345Sgblack@eecs.umich.edu
896345Sgblack@eecs.umich.edu    // Hook the queues to the Throttle
904615Sgblack@eecs.umich.edu    throttle_ptr->addLinks(intermediateBuffers, out);
915671Sgblack@eecs.umich.edu}
926345Sgblack@eecs.umich.edu
936345Sgblack@eecs.umich.eduvoid
945291Sgblack@eecs.umich.eduSwitch::clearRoutingTables()
955428Sgblack@eecs.umich.edu{
965674Sgblack@eecs.umich.edu    m_perfect_switch_ptr->clearRoutingTables();
975899Sgblack@eecs.umich.edu}
985936Sgblack@eecs.umich.edu
995428Sgblack@eecs.umich.eduvoid
1005428Sgblack@eecs.umich.eduSwitch::clearBuffers()
1015294Sgblack@eecs.umich.edu{
1026345Sgblack@eecs.umich.edu    m_perfect_switch_ptr->clearBuffers();
1035291Sgblack@eecs.umich.edu    for (int i = 0; i < m_throttles.size(); i++) {
1045294Sgblack@eecs.umich.edu        if (m_throttles[i] != NULL) {
1056345Sgblack@eecs.umich.edu            m_throttles[i]->clear();
1065294Sgblack@eecs.umich.edu        }
1074615Sgblack@eecs.umich.edu    }
1084615Sgblack@eecs.umich.edu}
1096345Sgblack@eecs.umich.edu
1106345Sgblack@eecs.umich.eduvoid
1116345Sgblack@eecs.umich.eduSwitch::reconfigureOutPort(const NetDest& routing_table_entry)
1126345Sgblack@eecs.umich.edu{
1136345Sgblack@eecs.umich.edu    m_perfect_switch_ptr->reconfigureOutPort(routing_table_entry);
1146345Sgblack@eecs.umich.edu}
1156517Sgblack@eecs.umich.edu
1166517Sgblack@eecs.umich.educonst Throttle*
1175161Sgblack@eecs.umich.eduSwitch::getThrottle(LinkID link_number) const
1185161Sgblack@eecs.umich.edu{
1196345Sgblack@eecs.umich.edu    assert(m_throttles[link_number] != NULL);
1204615Sgblack@eecs.umich.edu    return m_throttles[link_number];
1216345Sgblack@eecs.umich.edu}
1226345Sgblack@eecs.umich.edu
1234615Sgblack@eecs.umich.educonst Vector<Throttle*>*
1244953Sgblack@eecs.umich.eduSwitch::getThrottles() const
1254615Sgblack@eecs.umich.edu{
1264615Sgblack@eecs.umich.edu    return &m_throttles;
1274863Sgblack@eecs.umich.edu}
1284863Sgblack@eecs.umich.edu
1295326Sgblack@eecs.umich.eduvoid
1305326Sgblack@eecs.umich.eduSwitch::printStats(std::ostream& out) const
1315326Sgblack@eecs.umich.edu{
1325326Sgblack@eecs.umich.edu    using namespace std;
1335326Sgblack@eecs.umich.edu
1345326Sgblack@eecs.umich.edu    ccprintf(out, "switch_%d_inlinks: %d\n", m_switch_id,
1355326Sgblack@eecs.umich.edu        m_perfect_switch_ptr->getInLinks());
1365326Sgblack@eecs.umich.edu    ccprintf(out, "switch_%d_outlinks: %d\n", m_switch_id,
1375326Sgblack@eecs.umich.edu        m_perfect_switch_ptr->getOutLinks());
1384863Sgblack@eecs.umich.edu
1394863Sgblack@eecs.umich.edu    // Average link utilizations
1404863Sgblack@eecs.umich.edu    double average_utilization = 0.0;
1414863Sgblack@eecs.umich.edu    int throttle_count = 0;
1424863Sgblack@eecs.umich.edu
1434620Sgblack@eecs.umich.edu    for (int i = 0; i < m_throttles.size(); i++) {
1445149Sgblack@eecs.umich.edu        Throttle* throttle_ptr = m_throttles[i];
1455149Sgblack@eecs.umich.edu        if (throttle_ptr) {
1466345Sgblack@eecs.umich.edu            average_utilization += throttle_ptr->getUtilization();
1475294Sgblack@eecs.umich.edu            throttle_count++;
1485294Sgblack@eecs.umich.edu        }
1496345Sgblack@eecs.umich.edu    }
1505149Sgblack@eecs.umich.edu    average_utilization =
1515906Sgblack@eecs.umich.edu        throttle_count == 0 ? 0 : average_utilization / throttle_count;
1525906Sgblack@eecs.umich.edu
1536345Sgblack@eecs.umich.edu    // Individual link utilizations
1546345Sgblack@eecs.umich.edu    out << "links_utilized_percent_switch_" << m_switch_id << ": "
1554615Sgblack@eecs.umich.edu        << average_utilization << endl;
1566457Sgblack@eecs.umich.edu
1576457Sgblack@eecs.umich.edu    for (int link = 0; link < m_throttles.size(); link++) {
1586457Sgblack@eecs.umich.edu        Throttle* throttle_ptr = m_throttles[link];
1596457Sgblack@eecs.umich.edu        if (throttle_ptr != NULL) {
1605854Sgblack@eecs.umich.edu            out << "  links_utilized_percent_switch_" << m_switch_id
1616345Sgblack@eecs.umich.edu                << "_link_" << link << ": "
1625241Sgblack@eecs.umich.edu                << throttle_ptr->getUtilization() << " bw: "
1635426Sgblack@eecs.umich.edu                << throttle_ptr->getLinkBandwidth()
1645426Sgblack@eecs.umich.edu                << " base_latency: " << throttle_ptr->getLatency() << endl;
1654686Sgblack@eecs.umich.edu        }
1664686Sgblack@eecs.umich.edu    }
1674686Sgblack@eecs.umich.edu    out << endl;
1684953Sgblack@eecs.umich.edu
1694686Sgblack@eecs.umich.edu    // Traffic breakdown
1704686Sgblack@eecs.umich.edu    for (int link = 0; link < m_throttles.size(); link++) {
1714686Sgblack@eecs.umich.edu        Throttle* throttle_ptr = m_throttles[link];
1724686Sgblack@eecs.umich.edu        if (!throttle_ptr)
1734953Sgblack@eecs.umich.edu            continue;
1744953Sgblack@eecs.umich.edu
1754686Sgblack@eecs.umich.edu        const Vector<Vector<int> >& message_counts =
1764686Sgblack@eecs.umich.edu            throttle_ptr->getCounters();
1774686Sgblack@eecs.umich.edu        for (int int_type = 0; int_type < MessageSizeType_NUM; int_type++) {
1784686Sgblack@eecs.umich.edu            MessageSizeType type = MessageSizeType(int_type);
1795682Sgblack@eecs.umich.edu            int sum = message_counts[type].sum();
1805682Sgblack@eecs.umich.edu            if (sum == 0)
1815682Sgblack@eecs.umich.edu                continue;
1826345Sgblack@eecs.umich.edu
1835682Sgblack@eecs.umich.edu            out << "  outgoing_messages_switch_" << m_switch_id
1844615Sgblack@eecs.umich.edu                << "_link_" << link << "_" << type << ": " << sum << " "
1854615Sgblack@eecs.umich.edu                << sum * RubySystem::getNetwork()->MessageSizeType_to_int(type)
1864615Sgblack@eecs.umich.edu                << " " << message_counts[type] << " base_latency: "
1874615Sgblack@eecs.umich.edu                << throttle_ptr->getLatency() << endl;
1884615Sgblack@eecs.umich.edu        }
1894615Sgblack@eecs.umich.edu    }
1904615Sgblack@eecs.umich.edu    out << endl;
1915930Sgblack@eecs.umich.edu}
1925291Sgblack@eecs.umich.edu
1935291Sgblack@eecs.umich.eduvoid
1945291Sgblack@eecs.umich.eduSwitch::clearStats()
1955291Sgblack@eecs.umich.edu{
1965291Sgblack@eecs.umich.edu    m_perfect_switch_ptr->clearStats();
1975291Sgblack@eecs.umich.edu    for (int i = 0; i < m_throttles.size(); i++) {
1985161Sgblack@eecs.umich.edu        if (m_throttles[i] != NULL)
1995161Sgblack@eecs.umich.edu            m_throttles[i]->clearStats();
2005161Sgblack@eecs.umich.edu    }
2015161Sgblack@eecs.umich.edu}
2025161Sgblack@eecs.umich.edu
2035008Sgblack@eecs.umich.eduvoid
2045008Sgblack@eecs.umich.eduSwitch::printConfig(std::ostream& out) const
2055008Sgblack@eecs.umich.edu{
2065008Sgblack@eecs.umich.edu    m_perfect_switch_ptr->printConfig(out);
2075008Sgblack@eecs.umich.edu    for (int i = 0; i < m_throttles.size(); i++) {
2085667Sgblack@eecs.umich.edu        if (m_throttles[i] != NULL)
2095667Sgblack@eecs.umich.edu            m_throttles[i]->printConfig(out);
2105667Sgblack@eecs.umich.edu    }
2115667Sgblack@eecs.umich.edu}
2125667Sgblack@eecs.umich.edu
2135676Sgblack@eecs.umich.eduvoid
2145676Sgblack@eecs.umich.eduSwitch::print(std::ostream& out) const
2155676Sgblack@eecs.umich.edu{
2165676Sgblack@eecs.umich.edu    // FIXME printing
2175676Sgblack@eecs.umich.edu    out << "[Switch]";
2185082Sgblack@eecs.umich.edu}
2196345Sgblack@eecs.umich.edu
2205082Sgblack@eecs.umich.edu