diff options
Diffstat (limited to 'src/gpgpu-sim/local_interconnect.cc')
| -rw-r--r-- | src/gpgpu-sim/local_interconnect.cc | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/src/gpgpu-sim/local_interconnect.cc b/src/gpgpu-sim/local_interconnect.cc new file mode 100644 index 0000000..1d93fe6 --- /dev/null +++ b/src/gpgpu-sim/local_interconnect.cc @@ -0,0 +1,277 @@ +// Copyright (c) 2009-2013, Tor M. Aamodt, Dongdong Li, Ali Bakhoda +// The University of British Columbia +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// Redistributions in binary form must reproduce the above copyright notice, this +// list of conditions and the following disclaimer in the documentation and/or +// other materials provided with the distribution. +// Neither the name of The University of British Columbia nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <fstream> +#include <iostream> +#include <sstream> +#include <iomanip> +#include <cmath> +#include <utility> +#include <algorithm> + +#include "local_interconnect.h" +#include "mem_fetch.h" + +xbar_router::xbar_router(unsigned router_id, unsigned n_shader, unsigned n_mem, unsigned m_in_buffer_limit, unsigned m_out_buffer_limit) +{ + m_id=router_id; + _n_mem = n_mem; + _n_shader = n_shader; + total_nodes = n_shader+n_mem; + in_buffers.resize(total_nodes); + out_buffers.resize(total_nodes); + next_node=0; + in_buffer_limit = m_in_buffer_limit; + out_buffer_limit = m_out_buffer_limit; + + cycles = 0; + conflicts= 0; + out_buffer_full=0; + packets_num=0; +} + + +xbar_router::~xbar_router() +{ + +} + +void xbar_router::Push(unsigned input_deviceID, unsigned output_deviceID, void* data, unsigned int size) +{ + assert(input_deviceID < total_nodes); + in_buffers[input_deviceID].push(Packet(data, output_deviceID)); + packets_num++; +} + +void* xbar_router::Pop(unsigned ouput_deviceID) +{ + assert(ouput_deviceID < total_nodes); + void* data = NULL; + + if(!out_buffers[ouput_deviceID].empty()) { + data = out_buffers[ouput_deviceID].front().data; + out_buffers[ouput_deviceID].pop(); + } + + return data; +} + + +bool xbar_router::Has_Buffer_In(unsigned input_deviceID, unsigned size) const{ + + assert(input_deviceID < total_nodes); + return (in_buffers[input_deviceID].size() + size <= in_buffer_limit); + +} + +bool xbar_router::Has_Buffer_Out(unsigned output_deviceID, unsigned size) const{ + return (out_buffers[output_deviceID].size() + size <= out_buffer_limit); +} + +void xbar_router::Advance() { + cycles++; + + vector<bool> issued(total_nodes, false); + + for(unsigned i=0; i<total_nodes; ++i){ + unsigned node_id = (i+next_node)%total_nodes; + + if(!in_buffers[node_id].empty()) { + Packet _packet = in_buffers[node_id].front(); + //ensure that the outbuffer has space and not issued before in this cycle + if(Has_Buffer_Out(_packet.output_deviceID, 1)){ + if(!issued[_packet.output_deviceID]) { + out_buffers[_packet.output_deviceID].push(_packet); + in_buffers[node_id].pop(); + issued[_packet.output_deviceID]=true; + } + else + conflicts++; + } + else + out_buffer_full++; + } + } + + next_node = (++next_node % total_nodes); +} + +bool xbar_router::Busy() const { + + for(unsigned i=0; i<total_nodes; ++i){ + if(!in_buffers[i].empty()) + return true; + + if(!out_buffers[i].empty()) + return true; + } + return false; +} + + +//////////////////////////////////////////////////// +/////////////LocalInterconnect///////////////////// + +//assume all the packets are one flit +#define LOCAL_INCT_FLIT_SIZE 40 + +LocalInterconnect* LocalInterconnect::New(const struct inct_config& m_localinct_config) +{ + + LocalInterconnect* icnt_interface = new LocalInterconnect(m_localinct_config); + + return icnt_interface; +} + +LocalInterconnect::LocalInterconnect(const struct inct_config& m_localinct_config): m_inct_config(m_localinct_config) +{ + n_shader=0; + n_mem=0; + n_subnets = m_localinct_config.subnets; + +} + +LocalInterconnect::~LocalInterconnect() +{ + for (int i=0; i<m_inct_config.subnets; ++i) { + delete net[i]; + } +} + +void LocalInterconnect::CreateInterconnect(unsigned m_n_shader, unsigned m_n_mem) +{ + n_shader = m_n_shader; + n_mem = m_n_mem; + + net.resize(n_subnets); + for (unsigned i = 0; i < n_subnets; ++i) { + net[i] = new xbar_router( i, m_n_shader, m_n_mem, m_inct_config.in_buffer_limit, m_inct_config.out_buffer_limit ); + } + +} + + +void LocalInterconnect::Init() { + + //empty + //there is nothing to do + +} + +void LocalInterconnect::Push(unsigned input_deviceID, unsigned output_deviceID, void* data, unsigned int size){ + + unsigned subnet; + if (n_subnets == 1) { + subnet = 0; + } else { + if (input_deviceID < n_shader ) { + subnet = 0; + } else { + subnet = 1; + } + } + + // it should have free buffer + //assume all the packets have size of one + //no flits are implemented + assert(net[subnet]->Has_Buffer_In(input_deviceID, 1)); + + net[subnet]->Push(input_deviceID, output_deviceID, data, size); + +} + +void* LocalInterconnect::Pop(unsigned ouput_deviceID){ + + // 0-_n_shader-1 indicates reply(network 1), otherwise request(network 0) + int subnet = 0; + if (ouput_deviceID < n_shader) + subnet = 1; + + return net[subnet]->Pop(ouput_deviceID); + +} + +void LocalInterconnect::Advance(){ + + for (unsigned i = 0; i < n_subnets; ++i) { + net[i]->Advance(); + } + +} + +bool LocalInterconnect::Busy() const{ + + for (unsigned i = 0; i < n_subnets; ++i) { + if(net[i]->Busy()) + return true; + } + return false; +} + +bool LocalInterconnect::HasBuffer(unsigned deviceID, unsigned int size) const{ + + bool has_buffer = false; + + has_buffer = net[0]->Has_Buffer_In(deviceID, size); + + if ((n_subnets>1) && deviceID >= n_shader) // deviceID is memory node + has_buffer = net[1]->Has_Buffer_In(deviceID, size); + + return has_buffer; + +} + +void LocalInterconnect::DisplayStats() const{ + + cout<<"Req_Network_injected_packets_num = "<<net[0]->packets_num<<endl; + cout<<"Req_Network_cycles = "<<net[0]->cycles<<endl; + cout<<"Req_Network_injected_packets_per_cycle = "<<(float)(net[0]->packets_num) / (net[0]->cycles)<<endl; + cout<<"Req_Network_conflicts_per_cycle = "<<(float)(net[0]->conflicts) / (net[0]->cycles)<<endl; + cout<<"Req_Network_out_buffer_full_per_cycle = "<<(float)(net[0]->out_buffer_full) / (net[0]->cycles)<<endl; + + cout<<endl; + cout<<"Reply_Network_injected_packets_num = "<<net[1]->packets_num<<endl; + cout<<"ReplyNetwork_cycles = "<<net[1]->cycles<<endl; + cout<<"ReplyNetwork_injected_packets_per_cycle = "<<(float)(net[1]->packets_num) / (net[1]->cycles)<<endl; + cout<<"ReplyNetwork_conflicts_per_cycle = "<<(float)(net[1]->conflicts) / (net[1]->cycles)<<endl; + cout<<"ReplyNetwork_out_buffer_full_per_cycle = "<<(float)(net[1]->out_buffer_full) / (net[1]->cycles)<<endl; + +} + +void LocalInterconnect::DisplayOverallStats() const{ + +} + +unsigned LocalInterconnect::GetFlitSize() const{ + return LOCAL_INCT_FLIT_SIZE; +} + +void LocalInterconnect::DisplayState(FILE* fp) const{ + + fprintf(fp, "GPGPU-Sim uArch: ICNT:Display State: Under implementation\n"); +} + |
