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 <odanrc@yahoo.com.br> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24248 Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu> Reviewed-by: Srikant Bharadwaj <srikant.bharadwaj@amd.com> Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Daniel Carvalho
parent
21e12a0d0e
commit
f5f523ed26
@@ -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++;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@ class CrossbarSwitch : public Consumer
|
||||
double m_crossbar_activity;
|
||||
Router *m_router;
|
||||
std::vector<std::unique_ptr<flitBuffer>> m_switch_buffer;
|
||||
std::vector<OutputUnit *> m_output_unit;
|
||||
};
|
||||
|
||||
#endif // __MEM_RUBY_NETWORK_GARNET2_0_CROSSBARSWITCH_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
|
||||
@@ -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<InputUnit>(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<OutputUnit>(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);
|
||||
|
||||
@@ -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 <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#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<InputUnit *>& get_inputUnit_ref() { return m_input_unit; }
|
||||
std::vector<OutputUnit *>& 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<InputUnit *> m_input_unit;
|
||||
std::vector<OutputUnit *> m_output_unit;
|
||||
RoutingUnit *m_routing_unit;
|
||||
SwitchAllocator *m_sw_alloc;
|
||||
CrossbarSwitch *m_switch;
|
||||
RoutingUnit routingUnit;
|
||||
SwitchAllocator switchAllocator;
|
||||
CrossbarSwitch crossbarSwitch;
|
||||
|
||||
std::vector<std::shared_ptr<InputUnit>> m_input_unit;
|
||||
std::vector<std::shared_ptr<OutputUnit>> m_output_unit;
|
||||
|
||||
// Statistical variables required for power computations
|
||||
Stats::Scalar m_buffer_reads;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<int> m_round_robin_inport;
|
||||
std::vector<std::vector<bool>> m_port_requests;
|
||||
std::vector<std::vector<int>> m_vc_winners; // a list for each outport
|
||||
std::vector<InputUnit *> m_input_unit;
|
||||
std::vector<OutputUnit *> m_output_unit;
|
||||
};
|
||||
|
||||
#endif // __MEM_RUBY_NETWORK_GARNET2_0_SWITCHALLOCATOR_HH__
|
||||
|
||||
Reference in New Issue
Block a user