From f5f523ed26932d00be8cc1e2668b53fd6997105b Mon Sep 17 00:00:00 2001 From: "Daniel R. Carvalho" Date: Tue, 7 Jan 2020 23:59:43 +0100 Subject: [PATCH] mem-garnet: Use smart pointers in Router's members Use smart pointers for the pointers managed by Router, and do static allocation when possible. Change-Id: I5fad8b2d17ac7950d478d37000ac80a4d2f68b15 Signed-off-by: Daniel R. Carvalho Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24248 Reviewed-by: Bobby R. Bruce Reviewed-by: Srikant Bharadwaj Maintainer: Bobby R. Bruce Tested-by: kokoro --- .../ruby/network/garnet2.0/CrossbarSwitch.cc | 4 +- .../ruby/network/garnet2.0/CrossbarSwitch.hh | 1 - src/mem/ruby/network/garnet2.0/Router.cc | 68 +++++++------------ src/mem/ruby/network/garnet2.0/Router.hh | 42 ++++++++---- .../ruby/network/garnet2.0/SwitchAllocator.cc | 60 ++++++++-------- .../ruby/network/garnet2.0/SwitchAllocator.hh | 5 +- 6 files changed, 86 insertions(+), 94 deletions(-) diff --git a/src/mem/ruby/network/garnet2.0/CrossbarSwitch.cc b/src/mem/ruby/network/garnet2.0/CrossbarSwitch.cc index bfebe6509..dba3474b7 100644 --- a/src/mem/ruby/network/garnet2.0/CrossbarSwitch.cc +++ b/src/mem/ruby/network/garnet2.0/CrossbarSwitch.cc @@ -46,8 +46,6 @@ CrossbarSwitch::CrossbarSwitch(Router *router) void CrossbarSwitch::init() { - m_output_unit = m_router->get_outputUnit_ref(); - m_num_inports = m_router->get_num_inports(); m_switch_buffer.resize(m_num_inports); for (int i = 0; i < m_num_inports; i++) { @@ -82,7 +80,7 @@ CrossbarSwitch::wakeup() // This will take care of waking up the Network Link // in the next cycle - m_output_unit[outport]->insert_flit(t_flit); + m_router->getOutputUnit(outport)->insert_flit(t_flit); m_switch_buffer[inport]->getTopFlit(); m_crossbar_activity++; } diff --git a/src/mem/ruby/network/garnet2.0/CrossbarSwitch.hh b/src/mem/ruby/network/garnet2.0/CrossbarSwitch.hh index 3464f4e79..95418d82b 100644 --- a/src/mem/ruby/network/garnet2.0/CrossbarSwitch.hh +++ b/src/mem/ruby/network/garnet2.0/CrossbarSwitch.hh @@ -66,7 +66,6 @@ class CrossbarSwitch : public Consumer double m_crossbar_activity; Router *m_router; std::vector> m_switch_buffer; - std::vector m_output_unit; }; #endif // __MEM_RUBY_NETWORK_GARNET2_0_CROSSBARSWITCH_HH__ diff --git a/src/mem/ruby/network/garnet2.0/Router.cc b/src/mem/ruby/network/garnet2.0/Router.cc index d8e8fe509..14c0e8408 100644 --- a/src/mem/ruby/network/garnet2.0/Router.cc +++ b/src/mem/ruby/network/garnet2.0/Router.cc @@ -1,6 +1,7 @@ /* - * Copyright (c) 2008 Princeton University + * Copyright (c) 2020 Inria * Copyright (c) 2016 Georgia Institute of Technology + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,52 +31,32 @@ #include "mem/ruby/network/garnet2.0/Router.hh" -#include "base/stl_helpers.hh" #include "debug/RubyNetwork.hh" #include "mem/ruby/network/garnet2.0/CreditLink.hh" -#include "mem/ruby/network/garnet2.0/CrossbarSwitch.hh" #include "mem/ruby/network/garnet2.0/GarnetNetwork.hh" #include "mem/ruby/network/garnet2.0/InputUnit.hh" #include "mem/ruby/network/garnet2.0/NetworkLink.hh" #include "mem/ruby/network/garnet2.0/OutputUnit.hh" -#include "mem/ruby/network/garnet2.0/RoutingUnit.hh" -#include "mem/ruby/network/garnet2.0/SwitchAllocator.hh" using namespace std; -using m5::stl_helpers::deletePointers; Router::Router(const Params *p) - : BasicRouter(p), Consumer(this) + : BasicRouter(p), Consumer(this), m_latency(p->latency), + m_virtual_networks(p->virt_nets), m_vc_per_vnet(p->vcs_per_vnet), + m_num_vcs(m_virtual_networks * m_vc_per_vnet), m_network_ptr(nullptr), + routingUnit(this), switchAllocator(this), crossbarSwitch(this) { - m_latency = p->latency; - m_virtual_networks = p->virt_nets; - m_vc_per_vnet = p->vcs_per_vnet; - m_num_vcs = m_virtual_networks * m_vc_per_vnet; - - m_routing_unit = new RoutingUnit(this); - m_sw_alloc = new SwitchAllocator(this); - m_switch = new CrossbarSwitch(this); - m_input_unit.clear(); m_output_unit.clear(); } -Router::~Router() -{ - deletePointers(m_input_unit); - deletePointers(m_output_unit); - delete m_routing_unit; - delete m_sw_alloc; - delete m_switch; -} - void Router::init() { BasicRouter::init(); - m_sw_alloc->init(); - m_switch->init(); + switchAllocator.init(); + crossbarSwitch.init(); } void @@ -99,10 +80,10 @@ Router::wakeup() } // Switch Allocation - m_sw_alloc->wakeup(); + switchAllocator.wakeup(); // Switch Traversal - m_switch->wakeup(); + crossbarSwitch.wakeup(); } void @@ -117,9 +98,9 @@ Router::addInPort(PortDirection inport_dirn, in_link->setLinkConsumer(this); credit_link->setSourceQueue(input_unit->getCreditQueue()); - m_input_unit.push_back(input_unit); + m_input_unit.push_back(std::shared_ptr(input_unit)); - m_routing_unit->addInDirection(inport_dirn, port_num); + routingUnit.addInDirection(inport_dirn, port_num); } void @@ -136,11 +117,11 @@ Router::addOutPort(PortDirection outport_dirn, credit_link->setLinkConsumer(this); out_link->setSourceQueue(output_unit->getOutQueue()); - m_output_unit.push_back(output_unit); + m_output_unit.push_back(std::shared_ptr(output_unit)); - m_routing_unit->addRoute(routing_table_entry); - m_routing_unit->addWeight(link_weight); - m_routing_unit->addOutDirection(outport_dirn, port_num); + routingUnit.addRoute(routing_table_entry); + routingUnit.addWeight(link_weight); + routingUnit.addOutDirection(outport_dirn, port_num); } PortDirection @@ -158,13 +139,13 @@ Router::getInportDirection(int inport) int Router::route_compute(RouteInfo route, int inport, PortDirection inport_dirn) { - return m_routing_unit->outportCompute(route, inport, inport_dirn); + return routingUnit.outportCompute(route, inport, inport_dirn); } void Router::grant_switch(int inport, flit *t_flit) { - m_switch->update_sw_winner(inport, t_flit); + crossbarSwitch.update_sw_winner(inport, t_flit); } void @@ -225,9 +206,10 @@ Router::collateStats() } } - m_sw_input_arbiter_activity = m_sw_alloc->get_input_arbiter_activity(); - m_sw_output_arbiter_activity = m_sw_alloc->get_output_arbiter_activity(); - m_crossbar_activity = m_switch->get_crossbar_activity(); + m_sw_input_arbiter_activity = switchAllocator.get_input_arbiter_activity(); + m_sw_output_arbiter_activity = + switchAllocator.get_output_arbiter_activity(); + m_crossbar_activity = crossbarSwitch.get_crossbar_activity(); } void @@ -239,8 +221,8 @@ Router::resetStats() } } - m_switch->resetStats(); - m_sw_alloc->resetStats(); + crossbarSwitch.resetStats(); + switchAllocator.resetStats(); } void @@ -276,7 +258,7 @@ uint32_t Router::functionalWrite(Packet *pkt) { uint32_t num_functional_writes = 0; - num_functional_writes += m_switch->functionalWrite(pkt); + num_functional_writes += crossbarSwitch.functionalWrite(pkt); for (uint32_t i = 0; i < m_input_unit.size(); i++) { num_functional_writes += m_input_unit[i]->functionalWrite(pkt); diff --git a/src/mem/ruby/network/garnet2.0/Router.hh b/src/mem/ruby/network/garnet2.0/Router.hh index 9248905ef..19fc7f007 100644 --- a/src/mem/ruby/network/garnet2.0/Router.hh +++ b/src/mem/ruby/network/garnet2.0/Router.hh @@ -1,6 +1,7 @@ /* - * Copyright (c) 2008 Princeton University + * Copyright (c) 2020 Inria * Copyright (c) 2016 Georgia Institute of Technology + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,13 +33,17 @@ #define __MEM_RUBY_NETWORK_GARNET2_0_ROUTER_HH__ #include +#include #include #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/common/NetDest.hh" #include "mem/ruby/network/BasicRouter.hh" #include "mem/ruby/network/garnet2.0/CommonTypes.hh" +#include "mem/ruby/network/garnet2.0/CrossbarSwitch.hh" #include "mem/ruby/network/garnet2.0/GarnetNetwork.hh" +#include "mem/ruby/network/garnet2.0/RoutingUnit.hh" +#include "mem/ruby/network/garnet2.0/SwitchAllocator.hh" #include "mem/ruby/network/garnet2.0/flit.hh" #include "params/GarnetRouter.hh" @@ -46,9 +51,6 @@ class NetworkLink; class CreditLink; class InputUnit; class OutputUnit; -class RoutingUnit; -class SwitchAllocator; -class CrossbarSwitch; class FaultModel; class Router : public BasicRouter, public Consumer @@ -57,7 +59,7 @@ class Router : public BasicRouter, public Consumer typedef GarnetRouterParams Params; Router(const Params *p); - ~Router(); + ~Router() = default; void wakeup(); void print(std::ostream& out) const {}; @@ -83,8 +85,21 @@ class Router : public BasicRouter, public Consumer } GarnetNetwork* get_net_ptr() { return m_network_ptr; } - std::vector& get_inputUnit_ref() { return m_input_unit; } - std::vector& get_outputUnit_ref() { return m_output_unit; } + + InputUnit* + getInputUnit(unsigned port) + { + assert(port < m_input_unit.size()); + return m_input_unit[port].get(); + } + + OutputUnit* + getOutputUnit(unsigned port) + { + assert(port < m_output_unit.size()); + return m_output_unit[port].get(); + } + PortDirection getOutportDirection(int outport); PortDirection getInportDirection(int inport); @@ -115,14 +130,15 @@ class Router : public BasicRouter, public Consumer private: Cycles m_latency; - int m_virtual_networks, m_num_vcs, m_vc_per_vnet; + int m_virtual_networks, m_vc_per_vnet, m_num_vcs; GarnetNetwork *m_network_ptr; - std::vector m_input_unit; - std::vector m_output_unit; - RoutingUnit *m_routing_unit; - SwitchAllocator *m_sw_alloc; - CrossbarSwitch *m_switch; + RoutingUnit routingUnit; + SwitchAllocator switchAllocator; + CrossbarSwitch crossbarSwitch; + + std::vector> m_input_unit; + std::vector> m_output_unit; // Statistical variables required for power computations Stats::Scalar m_buffer_reads; diff --git a/src/mem/ruby/network/garnet2.0/SwitchAllocator.cc b/src/mem/ruby/network/garnet2.0/SwitchAllocator.cc index 873d92c95..33cddc3f8 100644 --- a/src/mem/ruby/network/garnet2.0/SwitchAllocator.cc +++ b/src/mem/ruby/network/garnet2.0/SwitchAllocator.cc @@ -1,6 +1,7 @@ /* - * Copyright (c) 2008 Princeton University + * Copyright (c) 2020 Inria * Copyright (c) 2016 Georgia Institute of Technology + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,9 +51,6 @@ SwitchAllocator::SwitchAllocator(Router *router) void SwitchAllocator::init() { - m_input_unit = m_router->get_inputUnit_ref(); - m_output_unit = m_router->get_outputUnit_ref(); - m_num_inports = m_router->get_num_inports(); m_num_outports = m_router->get_num_outports(); m_round_robin_inport.resize(m_num_outports); @@ -114,14 +112,13 @@ SwitchAllocator::arbitrate_inports() int invc = m_round_robin_invc[inport]; for (int invc_iter = 0; invc_iter < m_num_vcs; invc_iter++) { + auto input_unit = m_router->getInputUnit(inport); - if (m_input_unit[inport]->need_stage(invc, SA_, - m_router->curCycle())) { - + if (input_unit->need_stage(invc, SA_, m_router->curCycle())) { // This flit is in SA stage - int outport = m_input_unit[inport]->get_outport(invc); - int outvc = m_input_unit[inport]->get_outvc(invc); + int outport = input_unit->get_outport(invc); + int outvc = input_unit->get_outvc(invc); // check if the flit in this InputVC is allowed to be sent // send_allowed conditions described in that function. @@ -177,18 +174,20 @@ SwitchAllocator::arbitrate_outports() // inport has a request this cycle for outport if (m_port_requests[outport][inport]) { + auto output_unit = m_router->getOutputUnit(outport); + auto input_unit = m_router->getInputUnit(inport); // grant this outport to this inport int invc = m_vc_winners[outport][inport]; - int outvc = m_input_unit[inport]->get_outvc(invc); + int outvc = input_unit->get_outvc(invc); if (outvc == -1) { // VC Allocation - select any free VC from outport outvc = vc_allocate(outport, inport, invc); } // remove flit from Input VC - flit *t_flit = m_input_unit[inport]->getTopFlit(invc); + flit *t_flit = input_unit->getTopFlit(invc); DPRINTF(RubyNetwork, "SwitchAllocator at Router %d " "granted outvc %d at outport %d " @@ -196,10 +195,10 @@ SwitchAllocator::arbitrate_outports() "time: %lld\n", m_router->get_id(), outvc, m_router->getPortDirectionName( - m_output_unit[outport]->get_direction()), + output_unit->get_direction()), invc, m_router->getPortDirectionName( - m_input_unit[inport]->get_direction()), + input_unit->get_direction()), *t_flit, m_router->curCycle()); @@ -216,7 +215,7 @@ SwitchAllocator::arbitrate_outports() t_flit->set_vc(outvc); // decrement credit in outvc - m_output_unit[outport]->decrement_credit(outvc); + output_unit->decrement_credit(outvc); // flit ready for Switch Traversal t_flit->advance_stage(ST_, m_router->curCycle()); @@ -227,21 +226,19 @@ SwitchAllocator::arbitrate_outports() t_flit->get_type() == HEAD_TAIL_) { // This Input VC should now be empty - assert(!(m_input_unit[inport]->isReady(invc, - m_router->curCycle()))); + assert(!(input_unit->isReady(invc, m_router->curCycle()))); // Free this VC - m_input_unit[inport]->set_vc_idle(invc, - m_router->curCycle()); + input_unit->set_vc_idle(invc, m_router->curCycle()); // Send a credit back // along with the information that this VC is now idle - m_input_unit[inport]->increment_credit(invc, true, + input_unit->increment_credit(invc, true, m_router->curCycle()); } else { // Send a credit back // but do not indicate that the VC is idle - m_input_unit[inport]->increment_credit(invc, false, + input_unit->increment_credit(invc, false, m_router->curCycle()); } @@ -288,12 +285,13 @@ SwitchAllocator::send_allowed(int inport, int invc, int outport, int outvc) bool has_outvc = (outvc != -1); bool has_credit = false; + auto output_unit = m_router->getOutputUnit(outport); if (!has_outvc) { // needs outvc // this is only true for HEAD and HEAD_TAIL flits. - if (m_output_unit[outport]->has_free_vc(vnet)) { + if (output_unit->has_free_vc(vnet)) { has_outvc = true; @@ -302,7 +300,7 @@ SwitchAllocator::send_allowed(int inport, int invc, int outport, int outvc) has_credit = true; } } else { - has_credit = m_output_unit[outport]->has_credit(outvc); + has_credit = output_unit->has_credit(outvc); } // cannot send if no outvc or no credit. @@ -312,20 +310,19 @@ SwitchAllocator::send_allowed(int inport, int invc, int outport, int outvc) // protocol ordering check if ((m_router->get_net_ptr())->isVNetOrdered(vnet)) { + auto input_unit = m_router->getInputUnit(inport); // enqueue time of this flit - Cycles t_enqueue_time = m_input_unit[inport]->get_enqueue_time(invc); + Cycles t_enqueue_time = input_unit->get_enqueue_time(invc); // check if any other flit is ready for SA and for same output port // and was enqueued before this flit int vc_base = vnet*m_vc_per_vnet; for (int vc_offset = 0; vc_offset < m_vc_per_vnet; vc_offset++) { int temp_vc = vc_base + vc_offset; - if (m_input_unit[inport]->need_stage(temp_vc, SA_, - m_router->curCycle()) && - (m_input_unit[inport]->get_outport(temp_vc) == outport) && - (m_input_unit[inport]->get_enqueue_time(temp_vc) < - t_enqueue_time)) { + if (input_unit->need_stage(temp_vc, SA_, m_router->curCycle()) && + (input_unit->get_outport(temp_vc) == outport) && + (input_unit->get_enqueue_time(temp_vc) < t_enqueue_time)) { return false; } } @@ -339,11 +336,12 @@ int SwitchAllocator::vc_allocate(int outport, int inport, int invc) { // Select a free VC from the output port - int outvc = m_output_unit[outport]->select_free_vc(get_vnet(invc)); + int outvc = + m_router->getOutputUnit(outport)->select_free_vc(get_vnet(invc)); // has to get a valid VC since it checked before performing SA assert(outvc != -1); - m_input_unit[inport]->grant_outvc(invc, outvc); + m_router->getInputUnit(inport)->grant_outvc(invc, outvc); return outvc; } @@ -356,7 +354,7 @@ SwitchAllocator::check_for_wakeup() for (int i = 0; i < m_num_inports; i++) { for (int j = 0; j < m_num_vcs; j++) { - if (m_input_unit[i]->need_stage(j, SA_, nextCycle)) { + if (m_router->getInputUnit(i)->need_stage(j, SA_, nextCycle)) { m_router->schedule_wakeup(Cycles(1)); return; } diff --git a/src/mem/ruby/network/garnet2.0/SwitchAllocator.hh b/src/mem/ruby/network/garnet2.0/SwitchAllocator.hh index f61ca5a97..b30973599 100644 --- a/src/mem/ruby/network/garnet2.0/SwitchAllocator.hh +++ b/src/mem/ruby/network/garnet2.0/SwitchAllocator.hh @@ -1,6 +1,7 @@ /* - * Copyright (c) 2008 Princeton University + * Copyright (c) 2020 Inria * Copyright (c) 2016 Georgia Institute of Technology + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -80,8 +81,6 @@ class SwitchAllocator : public Consumer std::vector m_round_robin_inport; std::vector> m_port_requests; std::vector> m_vc_winners; // a list for each outport - std::vector m_input_unit; - std::vector m_output_unit; }; #endif // __MEM_RUBY_NETWORK_GARNET2_0_SWITCHALLOCATOR_HH__ -- 2.30.2