mem-garnet: Use static allocation in NetworkInterface

Use static allocation for the pointers managed by NetworkInterface.

Change-Id: Ib97d95165337659f92cb8a078020692baae5b5ca
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24247
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Srikant Bharadwaj <srikant.bharadwaj@amd.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Daniel R. Carvalho
2020-01-08 22:46:23 +01:00
committed by Daniel Carvalho
parent 0fa704526d
commit 5fce5056fd
2 changed files with 48 additions and 61 deletions

View File

@@ -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
@@ -34,7 +35,6 @@
#include <cmath>
#include "base/cast.hh"
#include "base/stl_helpers.hh"
#include "debug/RubyNetwork.hh"
#include "mem/ruby/network/MessageBuffer.hh"
#include "mem/ruby/network/garnet2.0/Credit.hh"
@@ -42,30 +42,22 @@
#include "mem/ruby/slicc_interface/Message.hh"
using namespace std;
using m5::stl_helpers::deletePointers;
NetworkInterface::NetworkInterface(const Params *p)
: ClockedObject(p), Consumer(this), m_id(p->id),
m_virtual_networks(p->virt_nets), m_vc_per_vnet(p->vcs_per_vnet),
m_num_vcs(m_vc_per_vnet * m_virtual_networks),
m_deadlock_threshold(p->garnet_deadlock_threshold),
vc_busy_counter(m_virtual_networks, 0)
: ClockedObject(p), Consumer(this), m_id(p->id),
m_virtual_networks(p->virt_nets), m_vc_per_vnet(p->vcs_per_vnet),
m_router_id(-1), m_vc_allocator(m_virtual_networks, 0),
m_vc_round_robin(0), outFlitQueue(), outCreditQueue(),
m_deadlock_threshold(p->garnet_deadlock_threshold),
vc_busy_counter(m_virtual_networks, 0)
{
m_router_id = -1;
m_vc_round_robin = 0;
m_ni_out_vcs.resize(m_num_vcs);
m_ni_out_vcs_enqueue_time.resize(m_num_vcs);
outCreditQueue = new flitBuffer();
const int num_vcs = m_vc_per_vnet * m_virtual_networks;
niOutVcs.resize(num_vcs);
m_ni_out_vcs_enqueue_time.resize(num_vcs);
// instantiating the NI flit buffers
for (int i = 0; i < m_num_vcs; i++) {
m_ni_out_vcs[i] = new flitBuffer();
m_ni_out_vcs_enqueue_time[i] = Cycles(INFINITE_);
}
m_vc_allocator.resize(m_virtual_networks); // 1 allocator per vnet
for (int i = 0; i < m_virtual_networks; i++) {
m_vc_allocator[i] = 0;
for (auto& time : m_ni_out_vcs_enqueue_time) {
time = Cycles(INFINITE_);
}
m_stall_count.resize(m_virtual_networks);
@@ -74,19 +66,13 @@ NetworkInterface::NetworkInterface(const Params *p)
void
NetworkInterface::init()
{
for (int i = 0; i < m_num_vcs; i++) {
m_out_vc_state.push_back(new OutVcState(i, m_net_ptr));
const int num_vcs = m_vc_per_vnet * m_virtual_networks;
outVcState.reserve(num_vcs);
for (int i = 0; i < num_vcs; i++) {
outVcState.emplace_back(i, m_net_ptr);
}
}
NetworkInterface::~NetworkInterface()
{
deletePointers(m_out_vc_state);
deletePointers(m_ni_out_vcs);
delete outCreditQueue;
delete outFlitQueue;
}
void
NetworkInterface::addInPort(NetworkLink *in_link,
CreditLink *credit_link)
@@ -94,7 +80,7 @@ NetworkInterface::addInPort(NetworkLink *in_link,
inNetLink = in_link;
in_link->setLinkConsumer(this);
outCreditLink = credit_link;
credit_link->setSourceQueue(outCreditQueue);
credit_link->setSourceQueue(&outCreditQueue);
}
void
@@ -106,8 +92,7 @@ NetworkInterface::addOutPort(NetworkLink *out_link,
credit_link->setLinkConsumer(this);
outNetLink = out_link;
outFlitQueue = new flitBuffer();
out_link->setSourceQueue(outFlitQueue);
out_link->setSourceQueue(&outFlitQueue);
m_router_id = router_id;
}
@@ -250,9 +235,9 @@ NetworkInterface::wakeup()
if (inCreditLink->isReady(curCycle())) {
Credit *t_credit = (Credit*) inCreditLink->consumeLink();
m_out_vc_state[t_credit->get_vc()]->increment_credit();
outVcState[t_credit->get_vc()].increment_credit();
if (t_credit->is_free_signal()) {
m_out_vc_state[t_credit->get_vc()]->setState(IDLE_, curCycle());
outVcState[t_credit->get_vc()].setState(IDLE_, curCycle());
}
delete t_credit;
}
@@ -262,7 +247,7 @@ NetworkInterface::wakeup()
// was unstalled in the same cycle as a new message arrives. In this
// case, we should schedule another wakeup to ensure the credit is sent
// back.
if (outCreditQueue->getSize() > 0) {
if (outCreditQueue.getSize() > 0) {
outCreditLink->scheduleEventAbsolute(clockEdge(Cycles(1)));
}
}
@@ -271,7 +256,7 @@ void
NetworkInterface::sendCredit(flit *t_flit, bool is_free)
{
Credit *credit_flit = new Credit(t_flit->get_vc(), is_free, curCycle());
outCreditQueue->insert(credit_flit);
outCreditQueue.insert(credit_flit);
}
bool
@@ -389,11 +374,11 @@ NetworkInterface::flitisizeMessage(MsgPtr msg_ptr, int vnet)
curCycle());
fl->set_src_delay(curCycle() - ticksToCycles(msg_ptr->getTime()));
m_ni_out_vcs[vc]->insert(fl);
niOutVcs[vc].insert(fl);
}
m_ni_out_vcs_enqueue_time[vc] = curCycle();
m_out_vc_state[vc]->setState(ACTIVE_, curCycle());
outVcState[vc].setState(ACTIVE_, curCycle());
}
return true ;
}
@@ -408,7 +393,7 @@ NetworkInterface::calculateVC(int vnet)
if (m_vc_allocator[vnet] == m_vc_per_vnet)
m_vc_allocator[vnet] = 0;
if (m_out_vc_state[(vnet*m_vc_per_vnet) + delta]->isInState(
if (outVcState[(vnet*m_vc_per_vnet) + delta].isInState(
IDLE_, curCycle())) {
vc_busy_counter[vnet] = 0;
return ((vnet*m_vc_per_vnet) + delta);
@@ -435,14 +420,14 @@ NetworkInterface::scheduleOutputLink()
{
int vc = m_vc_round_robin;
for (int i = 0; i < m_num_vcs; i++) {
for (int i = 0; i < niOutVcs.size(); i++) {
vc++;
if (vc == m_num_vcs)
if (vc == niOutVcs.size())
vc = 0;
// model buffer backpressure
if (m_ni_out_vcs[vc]->isReady(curCycle()) &&
m_out_vc_state[vc]->has_credit()) {
if (niOutVcs[vc].isReady(curCycle()) &&
outVcState[vc].has_credit()) {
bool is_candidate_vc = true;
int t_vnet = get_vnet(vc);
@@ -452,7 +437,7 @@ NetworkInterface::scheduleOutputLink()
for (int vc_offset = 0; vc_offset < m_vc_per_vnet;
vc_offset++) {
int t_vc = vc_base + vc_offset;
if (m_ni_out_vcs[t_vc]->isReady(curCycle())) {
if (niOutVcs[t_vc].isReady(curCycle())) {
if (m_ni_out_vcs_enqueue_time[t_vc] <
m_ni_out_vcs_enqueue_time[vc]) {
is_candidate_vc = false;
@@ -466,11 +451,11 @@ NetworkInterface::scheduleOutputLink()
m_vc_round_robin = vc;
m_out_vc_state[vc]->decrement_credit();
outVcState[vc].decrement_credit();
// Just removing the flit
flit *t_flit = m_ni_out_vcs[vc]->getTopFlit();
flit *t_flit = niOutVcs[vc].getTopFlit();
t_flit->set_time(curCycle() + Cycles(1));
outFlitQueue->insert(t_flit);
outFlitQueue.insert(t_flit);
// schedule the out link
outNetLink->scheduleEventAbsolute(clockEdge(Cycles(1)));
@@ -512,8 +497,8 @@ NetworkInterface::checkReschedule()
}
}
for (int vc = 0; vc < m_num_vcs; vc++) {
if (m_ni_out_vcs[vc]->isReady(curCycle() + Cycles(1))) {
for (auto& ni_out_vc : niOutVcs) {
if (ni_out_vc.isReady(curCycle() + Cycles(1))) {
scheduleEvent(Cycles(1));
return;
}
@@ -530,11 +515,11 @@ uint32_t
NetworkInterface::functionalWrite(Packet *pkt)
{
uint32_t num_functional_writes = 0;
for (unsigned int i = 0; i < m_num_vcs; ++i) {
num_functional_writes += m_ni_out_vcs[i]->functionalWrite(pkt);
for (auto& ni_out_vc : niOutVcs) {
num_functional_writes += ni_out_vc.functionalWrite(pkt);
}
num_functional_writes += outFlitQueue->functionalWrite(pkt);
num_functional_writes += outFlitQueue.functionalWrite(pkt);
return num_functional_writes;
}

View File

@@ -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
@@ -51,7 +52,7 @@ class NetworkInterface : public ClockedObject, public Consumer
public:
typedef GarnetNetworkInterfaceParams Params;
NetworkInterface(const Params *p);
~NetworkInterface();
~NetworkInterface() = default;
void init();
@@ -74,14 +75,15 @@ class NetworkInterface : public ClockedObject, public Consumer
private:
GarnetNetwork *m_net_ptr;
const NodeID m_id;
const int m_virtual_networks, m_vc_per_vnet, m_num_vcs;
const int m_virtual_networks, m_vc_per_vnet;
int m_router_id; // id of my router
std::vector<OutVcState *> m_out_vc_state;
std::vector<int> m_vc_allocator;
int m_vc_round_robin; // For round robin scheduling
flitBuffer *outFlitQueue; // For modeling link contention
flitBuffer *outCreditQueue;
/** Used to model link contention. */
flitBuffer outFlitQueue;
flitBuffer outCreditQueue;
int m_deadlock_threshold;
std::vector<OutVcState> outVcState;
NetworkLink *inNetLink;
NetworkLink *outNetLink;
@@ -94,7 +96,7 @@ class NetworkInterface : public ClockedObject, public Consumer
// Input Flit Buffers
// The flit buffers which will serve the Consumer
std::vector<flitBuffer *> m_ni_out_vcs;
std::vector<flitBuffer> niOutVcs;
std::vector<Cycles> m_ni_out_vcs_enqueue_time;
// The Message buffers that takes messages from the protocol