summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
authorTushar Krishna <tushar@ece.gatech.edu>2017-02-12 15:00:03 -0500
committerTushar Krishna <tushar@ece.gatech.edu>2017-02-12 15:00:03 -0500
commit1be05afa068c6898ae13c6207beebb2a700a8678 (patch)
tree344621e26c68ed7d1bbdc497aedf460c7bffeb13 /src/mem
parentf3643c8a60571604466bc78cc404fbfec704a1cf (diff)
downloadgem5-1be05afa068c6898ae13c6207beebb2a700a8678.tar.xz
ruby: fix round robin arbiter in garnet2.0
The rr arbiter pointer in garnet was getting updated on every request, even if there is no grant. This was leading to a huge variance in wait time at a router at high injection rates. This patch corrects it to update upon a grant.
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/ruby/network/garnet2.0/SwitchAllocator.cc22
1 files changed, 11 insertions, 11 deletions
diff --git a/src/mem/ruby/network/garnet2.0/SwitchAllocator.cc b/src/mem/ruby/network/garnet2.0/SwitchAllocator.cc
index 7916802a5..4619b0b8a 100644
--- a/src/mem/ruby/network/garnet2.0/SwitchAllocator.cc
+++ b/src/mem/ruby/network/garnet2.0/SwitchAllocator.cc
@@ -116,13 +116,6 @@ SwitchAllocator::arbitrate_inports()
for (int inport = 0; inport < m_num_inports; inport++) {
int invc = m_round_robin_invc[inport];
- // Select next round robin vc candidate within valid vnet
- int next_round_robin_invc = invc;
- next_round_robin_invc++;
- if (next_round_robin_invc >= m_num_vcs)
- next_round_robin_invc = 0;
- m_round_robin_invc[inport] = next_round_robin_invc;
-
for (int invc_iter = 0; invc_iter < m_num_vcs; invc_iter++) {
if (m_input_unit[inport]->need_stage(invc, SA_,
@@ -142,6 +135,12 @@ SwitchAllocator::arbitrate_inports()
m_input_arbiter_activity++;
m_port_requests[outport][inport] = true;
m_vc_winners[outport][inport]= invc;
+
+ // Update Round Robin pointer
+ m_round_robin_invc[inport]++;
+ if (m_round_robin_invc[inport] >= m_num_vcs)
+ m_round_robin_invc[inport] = 0;
+
break; // got one vc winner for this port
}
}
@@ -175,10 +174,6 @@ SwitchAllocator::arbitrate_outports()
// Independent arbiter at each output port
for (int outport = 0; outport < m_num_outports; outport++) {
int inport = m_round_robin_inport[outport];
- m_round_robin_inport[outport]++;
-
- if (m_round_robin_inport[outport] >= m_num_inports)
- m_round_robin_inport[outport] = 0;
for (int inport_iter = 0; inport_iter < m_num_inports;
inport_iter++) {
@@ -256,6 +251,11 @@ SwitchAllocator::arbitrate_outports()
// remove this request
m_port_requests[outport][inport] = false;
+ // Update Round Robin pointer
+ m_round_robin_inport[outport]++;
+ if (m_round_robin_inport[outport] >= m_num_inports)
+ m_round_robin_inport[outport] = 0;
+
break; // got a input winner for this outport
}