diff --git a/src/mem/ruby/network/simple/SimpleLink.py b/src/mem/ruby/network/simple/SimpleLink.py index ccf6b92653..04975945d0 100644 --- a/src/mem/ruby/network/simple/SimpleLink.py +++ b/src/mem/ruby/network/simple/SimpleLink.py @@ -63,12 +63,29 @@ class SimpleIntLink(BasicIntLink): if len(self.buffers) > 0: fatal("User should not manually set links' \ in_buffers or out_buffers") - # Note that all SimpleNetwork MessageBuffers are currently ordered # The network needs number_of_virtual_networks buffers per # in and out port buffers = [] for i in range(int(network.number_of_virtual_networks)): - buffers.append(MessageBuffer(ordered = True, - buffer_size = network.vnet_buffer_size(i))) + buffers.append(MessageBuffer(ordered = True)) + + # If physical_vnets_channels is set we adjust the buffer sizes and + # the max_dequeue_rate in order to achieve the expected thoughput + # assuming a fully pipelined link, i.e., throughput of 1 msg per cycle + # per channel (assuming the channels width matches the protocol + # logical message size, otherwise maximum thoughput may be smaller). + # In MessageBuffer, an entry occupied by a dequeued message at cycle + # X will available for enqueuing another message at cycle X+1. So + # for a 1 cy enqueue latency, 2 entries are needed. For any latency, + # the size should be at least latency+1. + if len(network.physical_vnets_channels) != 0: + assert(len(network.physical_vnets_channels) == \ + int(network.number_of_virtual_networks)) + for i in range(int(network.number_of_virtual_networks)): + buffers[i].buffer_size = \ + network.physical_vnets_channels[i] * (self.latency + 1) + buffers[i].max_dequeue_rate = \ + network.physical_vnets_channels[i] + self.buffers = buffers diff --git a/src/mem/ruby/network/simple/SimpleNetwork.py b/src/mem/ruby/network/simple/SimpleNetwork.py index 1d4772d09a..42484a144a 100644 --- a/src/mem/ruby/network/simple/SimpleNetwork.py +++ b/src/mem/ruby/network/simple/SimpleNetwork.py @@ -63,18 +63,6 @@ class SimpleNetwork(RubyNetwork): "Only valid when physical_vnets_channels is set. This overrides the" "bandwidth_factor parameter set for the individual links.") - def vnet_buffer_size(self, vnet): - """ - Gets the size of the message buffers associated to a vnet - If physical_vnets_channels is set we just multiply the size of the - buffers as SimpleNetwork does not actually creates multiple physical - channels per vnet. - """ - if len(self.physical_vnets_channels) == 0: - return self.buffer_size - else: - return self.buffer_size * self.physical_vnets_channels[vnet] - def setup_buffers(self): # Setup internal buffers for links and routers for link in self.int_links: @@ -128,8 +116,22 @@ class Switch(BasicRouter): "Routing strategy to be used") def setup_buffers(self, network): + def vnet_buffer_size(vnet): + """ + Gets the size of the message buffers associated to a vnet + If physical_vnets_channels is set we just multiply the size of the + buffers as SimpleNetwork does not actually creates multiple phy + channels per vnet. + """ + if len(network.physical_vnets_channels) == 0: + return network.buffer_size + else: + return network.buffer_size * \ + network.physical_vnets_channels[vnet] + if len(self.port_buffers) > 0: fatal("User should not manually set routers' port_buffers") + router_buffers = [] # Add message buffers to routers at the end of each # unidirectional internal link @@ -137,7 +139,7 @@ class Switch(BasicRouter): if link.dst_node == self: for i in range(int(network.number_of_virtual_networks)): router_buffers.append(SwitchPortBuffer( - buffer_size = network.vnet_buffer_size(i))) + buffer_size = vnet_buffer_size(i))) # Add message buffers to routers for each external link connection for link in network.ext_links: @@ -145,6 +147,6 @@ class Switch(BasicRouter): if link.int_node == self: for i in range(int(network.number_of_virtual_networks)): router_buffers.append(SwitchPortBuffer( - buffer_size = network.vnet_buffer_size(i))) + buffer_size = vnet_buffer_size(i))) self.port_buffers = router_buffers