This patch makes garnet use the info about active and inactive vnets during allocation and power estimations etc
This commit is contained in:
parent
1b9002eefc
commit
46cce440be
8 changed files with 93 additions and 44 deletions
|
@ -300,6 +300,9 @@ GarnetNetwork_d::printStats(ostream& out) const
|
|||
out << "-------------" << endl;
|
||||
|
||||
for (int i = 0; i < m_vcs_per_class*m_virtual_networks; i++) {
|
||||
if (!m_in_use[i/m_vcs_per_class])
|
||||
continue;
|
||||
|
||||
average_vc_load[i] = (double(average_vc_load[i]) /
|
||||
(double(g_eventQueue_ptr->getTime()) - m_ruby_start));
|
||||
out << "Average VC Load [" << i << "] = " << average_vc_load[i]
|
||||
|
|
|
@ -62,6 +62,7 @@ class Router_d
|
|||
int link_weight, CreditLink_d *credit_link);
|
||||
|
||||
int get_num_vcs() { return m_num_vcs; }
|
||||
int get_num_vnets() { return m_virtual_networks; }
|
||||
int get_vc_per_vnet() { return m_vc_per_vnet; }
|
||||
int get_num_inports() { return m_input_unit.size(); }
|
||||
int get_num_outports() { return m_output_unit.size(); }
|
||||
|
|
|
@ -90,14 +90,28 @@ SWallocator_d::arbitrate_inports()
|
|||
// First do round robin arbitration on a set of input vc requests
|
||||
for (int inport = 0; inport < m_num_inports; inport++) {
|
||||
int invc = m_round_robin_inport[inport];
|
||||
m_round_robin_inport[inport]++;
|
||||
|
||||
if (m_round_robin_inport[inport] >= m_num_vcs)
|
||||
m_round_robin_inport[inport] = 0;
|
||||
for (int j = 0; j < m_num_vcs; j++) {
|
||||
// Select next round robin vc candidate within valid vnet
|
||||
int next_round_robin_invc = invc;
|
||||
do {
|
||||
next_round_robin_invc++;
|
||||
|
||||
if (next_round_robin_invc >= m_num_vcs)
|
||||
next_round_robin_invc = 0;
|
||||
} while (!((m_router->get_net_ptr())->validVirtualNetwork(
|
||||
get_vnet(next_round_robin_invc))));
|
||||
|
||||
m_round_robin_inport[inport] = next_round_robin_invc;
|
||||
|
||||
for (int invc_iter = 0; invc_iter < m_num_vcs; invc_iter++) {
|
||||
invc++;
|
||||
if (invc >= m_num_vcs)
|
||||
invc = 0;
|
||||
|
||||
if (!((m_router->get_net_ptr())->validVirtualNetwork(
|
||||
get_vnet(invc))))
|
||||
continue;
|
||||
|
||||
if (m_input_unit[inport]->need_stage(invc, ACTIVE_, SA_) &&
|
||||
m_input_unit[inport]->has_credits(invc)) {
|
||||
if (is_candidate_inport(inport, invc)) {
|
||||
|
@ -141,47 +155,47 @@ SWallocator_d::arbitrate_outports()
|
|||
// Now there are a set of input vc requests for output vcs.
|
||||
// Again do round robin arbitration on these requests
|
||||
for (int outport = 0; outport < m_num_outports; outport++) {
|
||||
int in_port = m_round_robin_outport[outport];
|
||||
int inport = m_round_robin_outport[outport];
|
||||
m_round_robin_outport[outport]++;
|
||||
|
||||
if (m_round_robin_outport[outport] >= m_num_outports)
|
||||
m_round_robin_outport[outport] = 0;
|
||||
|
||||
for (int inport = 0; inport < m_num_inports; inport++) {
|
||||
in_port++;
|
||||
if (in_port >= m_num_inports)
|
||||
in_port = 0;
|
||||
for (int inport_iter = 0; inport_iter < m_num_inports; inport_iter++) {
|
||||
inport++;
|
||||
if (inport >= m_num_inports)
|
||||
inport = 0;
|
||||
|
||||
// in_port has a request this cycle for outport:
|
||||
if (m_port_req[outport][in_port]) {
|
||||
m_port_req[outport][in_port] = false;
|
||||
int invc = m_vc_winners[outport][in_port];
|
||||
int outvc = m_input_unit[in_port]->get_outvc(invc);
|
||||
// inport has a request this cycle for outport:
|
||||
if (m_port_req[outport][inport]) {
|
||||
m_port_req[outport][inport] = false;
|
||||
int invc = m_vc_winners[outport][inport];
|
||||
int outvc = m_input_unit[inport]->get_outvc(invc);
|
||||
|
||||
// remove flit from Input Unit
|
||||
flit_d *t_flit = m_input_unit[in_port]->getTopFlit(invc);
|
||||
flit_d *t_flit = m_input_unit[inport]->getTopFlit(invc);
|
||||
t_flit->advance_stage(ST_);
|
||||
t_flit->set_vc(outvc);
|
||||
t_flit->set_outport(outport);
|
||||
t_flit->set_time(g_eventQueue_ptr->getTime() + 1);
|
||||
m_output_unit[outport]->decrement_credit(outvc);
|
||||
m_router->update_sw_winner(in_port, t_flit);
|
||||
m_router->update_sw_winner(inport, t_flit);
|
||||
m_global_arbiter_activity++;
|
||||
|
||||
if ((t_flit->get_type() == TAIL_) ||
|
||||
t_flit->get_type() == HEAD_TAIL_) {
|
||||
// Send a credit back
|
||||
// along with the information that this VC is now idle
|
||||
m_input_unit[in_port]->increment_credit(invc, true);
|
||||
m_input_unit[inport]->increment_credit(invc, true);
|
||||
// This Input VC should now be empty
|
||||
assert(m_input_unit[in_port]->isReady(invc) == false);
|
||||
assert(m_input_unit[inport]->isReady(invc) == false);
|
||||
|
||||
m_input_unit[in_port]->set_vc_state(IDLE_, invc);
|
||||
m_input_unit[in_port]->set_enqueue_time(invc, INFINITE_);
|
||||
m_input_unit[inport]->set_vc_state(IDLE_, invc);
|
||||
m_input_unit[inport]->set_enqueue_time(invc, INFINITE_);
|
||||
} else {
|
||||
// Send a credit back
|
||||
// but do not indicate that the VC is idle
|
||||
m_input_unit[in_port]->increment_credit(invc, false);
|
||||
m_input_unit[inport]->increment_credit(invc, false);
|
||||
}
|
||||
break; // got a in request for this outport
|
||||
}
|
||||
|
@ -205,13 +219,9 @@ SWallocator_d::check_for_wakeup()
|
|||
int
|
||||
SWallocator_d::get_vnet(int invc)
|
||||
{
|
||||
for (int i = 0; i < RubySystem::getNetwork()->getNumberOfVirtualNetworks();
|
||||
i++) {
|
||||
if (invc >= (i*m_vc_per_vnet) && invc < ((i+1)*m_vc_per_vnet)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
fatal("Could not determine vc");
|
||||
int vnet = invc/m_vc_per_vnet;
|
||||
assert(vnet < m_router->get_num_vnets());
|
||||
return vnet;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -177,6 +177,10 @@ VCallocator_d::arbitrate_invcs()
|
|||
{
|
||||
for (int inport_iter = 0; inport_iter < m_num_inports; inport_iter++) {
|
||||
for (int invc_iter = 0; invc_iter < m_num_vcs; invc_iter++) {
|
||||
if (!((m_router->get_net_ptr())->validVirtualNetwork(
|
||||
get_vnet(invc_iter))))
|
||||
continue;
|
||||
|
||||
if (m_input_unit[inport_iter]->need_stage(
|
||||
invc_iter, VC_AB_, VA_)) {
|
||||
if (!is_invc_candidate(inport_iter, invc_iter))
|
||||
|
@ -240,13 +244,10 @@ VCallocator_d::arbitrate_outvcs()
|
|||
int
|
||||
VCallocator_d::get_vnet(int invc)
|
||||
{
|
||||
for (int i = 0; i < RubySystem::getNetwork()->getNumberOfVirtualNetworks();
|
||||
i++) {
|
||||
if (invc >= (i*m_vc_per_vnet) && invc < ((i+1)*m_vc_per_vnet)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
fatal("Could not determine vc");
|
||||
int vnet = invc/m_vc_per_vnet;
|
||||
assert(vnet < m_router->get_num_vnets());
|
||||
|
||||
return vnet;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -260,6 +260,9 @@ GarnetNetwork::printStats(ostream& out) const
|
|||
out << "-------------" << endl;
|
||||
|
||||
for (int i = 0; i < m_vcs_per_class*m_virtual_networks; i++) {
|
||||
if (!m_in_use[i/m_vcs_per_class])
|
||||
continue;
|
||||
|
||||
average_vc_load[i] = (double(average_vc_load[i]) /
|
||||
(double(g_eventQueue_ptr->getTime()) - m_ruby_start));
|
||||
out << "Average VC Load [" << i << "] = " << average_vc_load[i] <<
|
||||
|
|
|
@ -156,14 +156,27 @@ Router::vc_arbitrate()
|
|||
if (inport >= m_in_link.size())
|
||||
inport = 0;
|
||||
int invc = m_round_robin_invc[inport];
|
||||
m_round_robin_invc[inport]++;
|
||||
|
||||
if (m_round_robin_invc[inport] >= m_num_vcs)
|
||||
m_round_robin_invc[inport] = 0;
|
||||
int next_round_robin_invc = invc;
|
||||
do {
|
||||
next_round_robin_invc++;
|
||||
|
||||
if (next_round_robin_invc >= m_num_vcs)
|
||||
next_round_robin_invc = 0;
|
||||
|
||||
} while (!(m_net_ptr->validVirtualNetwork(
|
||||
get_vnet(next_round_robin_invc))));
|
||||
|
||||
m_round_robin_invc[inport] = next_round_robin_invc;
|
||||
|
||||
for (int vc_iter = 0; vc_iter < m_num_vcs; vc_iter++) {
|
||||
invc++;
|
||||
if (invc >= m_num_vcs)
|
||||
invc = 0;
|
||||
|
||||
if (!(m_net_ptr->validVirtualNetwork(get_vnet(invc))))
|
||||
continue;
|
||||
|
||||
InVcState *in_vc_state = m_in_vc_state[inport][invc];
|
||||
|
||||
if (in_vc_state->isInState(VC_AB_, g_eventQueue_ptr->getTime())) {
|
||||
|
@ -330,9 +343,17 @@ Router::scheduleOutputLinks()
|
|||
{
|
||||
for (int port = 0; port < m_out_link.size(); port++) {
|
||||
int vc_tolookat = m_vc_round_robin[port];
|
||||
m_vc_round_robin[port]++;
|
||||
if (m_vc_round_robin[port] == m_num_vcs)
|
||||
m_vc_round_robin[port] = 0;
|
||||
|
||||
int next_round_robin_vc_tolookat = vc_tolookat;
|
||||
do {
|
||||
next_round_robin_vc_tolookat++;
|
||||
|
||||
if (next_round_robin_vc_tolookat == m_num_vcs)
|
||||
next_round_robin_vc_tolookat = 0;
|
||||
} while (!(m_net_ptr->validVirtualNetwork(
|
||||
get_vnet(next_round_robin_vc_tolookat))));
|
||||
|
||||
m_vc_round_robin[port] = next_round_robin_vc_tolookat;
|
||||
|
||||
for (int i = 0; i < m_num_vcs; i++) {
|
||||
vc_tolookat++;
|
||||
|
@ -358,6 +379,14 @@ Router::scheduleOutputLinks()
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
Router::get_vnet(int vc)
|
||||
{
|
||||
int vnet = vc/m_vc_per_vnet;
|
||||
assert(vnet < m_virtual_networks);
|
||||
return vnet;
|
||||
}
|
||||
|
||||
void
|
||||
Router::checkReschedule()
|
||||
{
|
||||
|
|
|
@ -62,6 +62,7 @@ class Router : public FlexibleConsumer
|
|||
void grant_vc(int out_port, int vc, Time grant_time);
|
||||
void release_vc(int out_port, int vc, Time release_time);
|
||||
void vc_arbitrate();
|
||||
int get_vnet(int vc);
|
||||
|
||||
void printConfig(std::ostream& out) const;
|
||||
void print(std::ostream& out) const;
|
||||
|
|
|
@ -55,9 +55,10 @@ Router_d::calculate_power()
|
|||
std::vector<double > buf_write_count_active;
|
||||
|
||||
for (int i =0; i < m_virtual_networks; i++) {
|
||||
if (vc_local_arbit_count[i] > 0) {
|
||||
|
||||
active_vclass_ary[i] = (get_net_ptr())->validVirtualNetwork(i);
|
||||
if (active_vclass_ary[i]) {
|
||||
num_active_vclass++;
|
||||
active_vclass_ary[i] = true;
|
||||
vc_local_arbit_count_active.push_back(vc_local_arbit_count[i]);
|
||||
vc_global_arbit_count_active.push_back(vc_global_arbit_count[i]);
|
||||
buf_read_count_active.push_back(buf_read_count[i]);
|
||||
|
@ -66,7 +67,7 @@ Router_d::calculate_power()
|
|||
else {
|
||||
// Inactive vclass
|
||||
assert(vc_global_arbit_count[i] == 0);
|
||||
active_vclass_ary[i] = false;
|
||||
assert(vc_local_arbit_count[i] == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue