diff options
| author | Mahmoud <[email protected]> | 2020-05-23 20:06:25 -0400 |
|---|---|---|
| committer | Mahmoud <[email protected]> | 2020-05-23 20:06:25 -0400 |
| commit | d610fd81420979e956bf37100f7e1c7f1d153831 (patch) | |
| tree | 392a841f21fec5136339ff36ad9b5c7b1b4cb480 /src/gpgpu-sim/local_interconnect.cc | |
| parent | 6cedd3ef4973f3785757413db89a7c5d0ee2b58b (diff) | |
| parent | e9e9fcf5957530ecb927aecb5ea238e4b78a4f45 (diff) | |
Merge branch 'dev' of https://github.com/purdue-aalp/gpgpu-sim_distribution into dev-traces
Diffstat (limited to 'src/gpgpu-sim/local_interconnect.cc')
| -rw-r--r-- | src/gpgpu-sim/local_interconnect.cc | 459 |
1 files changed, 210 insertions, 249 deletions
diff --git a/src/gpgpu-sim/local_interconnect.cc b/src/gpgpu-sim/local_interconnect.cc index 93a2e6e..f74960e 100644 --- a/src/gpgpu-sim/local_interconnect.cc +++ b/src/gpgpu-sim/local_interconnect.cc @@ -7,162 +7,151 @@ // // 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. +// 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. +// 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 <algorithm> +#include <cmath> #include <fstream> +#include <iomanip> #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, enum Interconnect_type m_type, unsigned n_shader, unsigned n_mem, const struct inct_config& m_localinct_config) { - m_id=router_id; - router_type=m_type; - _n_mem = n_mem; - _n_shader = n_shader; - total_nodes = n_shader+n_mem; + m_id = router_id; + router_type = m_type; + _n_mem = n_mem; + _n_shader = n_shader; + total_nodes = n_shader + n_mem; verbose=m_localinct_config.verbose; grant_cycles = m_localinct_config.grant_cycles; grant_cycles_count = m_localinct_config.grant_cycles; - in_buffers.resize(total_nodes); - out_buffers.resize(total_nodes); - next_node.resize(total_nodes,0); + in_buffers.resize(total_nodes); + out_buffers.resize(total_nodes); + next_node.resize(total_nodes, 0); in_buffer_limit = m_localinct_config.in_buffer_limit; out_buffer_limit = m_localinct_config.out_buffer_limit; arbit_type = m_localinct_config.arbiter_algo; - next_node_id=0; - if(m_type == REQ_NET) { - active_in_buffers=n_shader; - active_out_buffers=n_mem; - } - else if(m_type == REPLY_NET) { - active_in_buffers=n_mem; - active_out_buffers=n_shader; - } + next_node_id = 0; + if (m_type == REQ_NET) { + active_in_buffers = n_shader; + active_out_buffers = n_mem; + } else if (m_type == REPLY_NET) { + active_in_buffers = n_mem; + active_out_buffers = n_shader; + } - cycles = 0; - conflicts= 0; - out_buffer_full=0; - in_buffer_full=0; - out_buffer_util=0; - in_buffer_util=0; - packets_num=0; + cycles = 0; + conflicts = 0; + out_buffer_full = 0; + in_buffer_full = 0; + out_buffer_util = 0; + in_buffer_util = 0; + packets_num = 0; conflicts_util=0; cycles_util=0; reqs_util=0; } +xbar_router::~xbar_router() {} -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::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; -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(); - } + if (!out_buffers[ouput_deviceID].empty()) { + data = out_buffers[ouput_deviceID].front().data; + out_buffers[ouput_deviceID].pop(); + } - return data; + return data; } +bool xbar_router::Has_Buffer_In(unsigned input_deviceID, unsigned size, + bool update_counter) { + assert(input_deviceID < total_nodes); -bool xbar_router::Has_Buffer_In(unsigned input_deviceID, unsigned size, bool update_counter){ - - assert(input_deviceID < total_nodes); - - bool has_buffer = (in_buffers[input_deviceID].size() + size <= in_buffer_limit); - if(update_counter && !has_buffer) - in_buffer_full++; - - return has_buffer; + bool has_buffer = + (in_buffers[input_deviceID].size() + size <= in_buffer_limit); + if (update_counter && !has_buffer) in_buffer_full++; + return has_buffer; } -bool xbar_router::Has_Buffer_Out(unsigned output_deviceID, unsigned size){ - return (out_buffers[output_deviceID].size() + size <= out_buffer_limit); +bool xbar_router::Has_Buffer_Out(unsigned output_deviceID, unsigned size) { + return (out_buffers[output_deviceID].size() + size <= out_buffer_limit); } void xbar_router::Advance() { - - if(arbit_type == NAIVE_RR) - RR_Advance(); - else if(arbit_type == iSLIP) - iSLIP_Advance(); - else - assert(0); - + if (arbit_type == NAIVE_RR) + RR_Advance(); + else if (arbit_type == iSLIP) + iSLIP_Advance(); + else + assert(0); } void xbar_router::RR_Advance() { bool active = false; - vector<bool> issued(total_nodes, false); + vector<bool> issued(total_nodes, false); unsigned conflict_sub =0 ; unsigned reqs =0 ; - for(unsigned i=0; i<total_nodes; ++i){ - unsigned node_id = (i+next_node_id)%total_nodes; + for (unsigned i = 0; i < total_nodes; ++i) { + unsigned node_id = (i + next_node_id) % total_nodes; - if(!in_buffers[node_id].empty()) { + if (!in_buffers[node_id].empty()) { active=true; - 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; + 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; reqs++; - } - else + } else conflict_sub++; - } - else { - out_buffer_full++; + } else { + out_buffer_full++; if(issued[_packet.output_deviceID]) conflict_sub++; - } - } - } + } + } + } - next_node_id = (++next_node_id % total_nodes); + next_node_id = (++next_node_id % total_nodes); conflicts += conflict_sub; if(active){ @@ -176,69 +165,66 @@ void xbar_router::RR_Advance() { printf("%d : cycle %d : passing reqs = %d\n", m_id, cycles, reqs); } - //collect some stats about buffer util - for(unsigned i=0; i<total_nodes; ++i){ - in_buffer_util+=in_buffers[i].size(); - out_buffer_util+=out_buffers[i].size(); - } + // collect some stats about buffer util + for (unsigned i = 0; i < total_nodes; ++i) { + in_buffer_util += in_buffers[i].size(); + out_buffer_util += out_buffers[i].size(); + } cycles++; } -//iSLIP algorithm -//McKeown, Nick. "The iSLIP scheduling algorithm for input-queued switches." IEEE/ACM transactions on networking 2 (1999): 188-201. -//https://www.cs.rutgers.edu/~sn624/552-F18/papers/islip.pdf +// iSLIP algorithm +// McKeown, Nick. "The iSLIP scheduling algorithm for input-queued switches." +// IEEE/ACM transactions on networking 2 (1999): 188-201. +// https://www.cs.rutgers.edu/~sn624/552-F18/papers/islip.pdf void xbar_router::iSLIP_Advance() { - vector<unsigned> node_tmp; + vector<unsigned> node_tmp; bool active = false; unsigned conflict_sub =0 ; unsigned reqs =0 ; - - //calculate how many conflicts are there for stats - for (unsigned i=0; i<total_nodes; ++i){ - - if(!in_buffers[i].empty()){ - Packet _packet_tmp = in_buffers[i].front(); - if (!node_tmp.empty()){ - if (std::find(node_tmp.begin(), node_tmp.end(), _packet_tmp.output_deviceID)!=node_tmp.end()){ + //calcaulte how many conflicts are there for stats + for (unsigned i = 0; i < total_nodes; ++i) { + + if (!in_buffers[i].empty()) { + Packet _packet_tmp = in_buffers[i].front(); + if (!node_tmp.empty()) { + if (std::find(node_tmp.begin(), node_tmp.end(), + _packet_tmp.output_deviceID) != node_tmp.end()) { conflict_sub++; - } - else - node_tmp.push_back(_packet_tmp.output_deviceID); - } - else{ - node_tmp.push_back(_packet_tmp.output_deviceID); - } + } else + node_tmp.push_back(_packet_tmp.output_deviceID); + } else { + node_tmp.push_back(_packet_tmp.output_deviceID); + } active=true; - } - } + } + } conflicts += conflict_sub; if(active){ conflicts_util += conflict_sub; cycles_util++; } + // do iSLIP + for (unsigned i = 0; i < total_nodes; ++i) { + if (Has_Buffer_Out(i, 1)) { + for (unsigned j = 0; j < total_nodes; ++j) { + unsigned node_id = (j + next_node[i]) % total_nodes; - //do iSLIP - for(unsigned i=0; i<total_nodes; ++i){ - - if(Has_Buffer_Out(i, 1)) { - for(unsigned j=0; j<total_nodes; ++j){ - unsigned node_id = (j+next_node[i])%total_nodes; - - if(!in_buffers[node_id].empty()) { - Packet _packet = in_buffers[node_id].front(); - if(_packet.output_deviceID==i){ - out_buffers[_packet.output_deviceID].push(_packet); - in_buffers[node_id].pop(); + if (!in_buffers[node_id].empty()) { + Packet _packet = in_buffers[node_id].front(); + if (_packet.output_deviceID == i) { + out_buffers[_packet.output_deviceID].push(_packet); + in_buffers[node_id].pop(); if(verbose) printf("%d : cycle %d : send req from %d to %d\n", m_id, cycles, node_id, i-_n_shader); if(grant_cycles_count == 1) - next_node[i] = (++node_id % total_nodes); + next_node[i] = (++node_id % total_nodes); if(verbose){ for(unsigned k=j+1; k<total_nodes; ++k){ unsigned node_id2 = (k+next_node[i])%total_nodes; @@ -252,14 +238,13 @@ void xbar_router::iSLIP_Advance() { } reqs++; - break; - } - } - } - } - else - out_buffer_full++; - } + break; + } + } + } + } else + out_buffer_full++; + } if(active){ reqs_util+=reqs; @@ -280,140 +265,122 @@ void xbar_router::iSLIP_Advance() { } - //collect some stats about buffer util - for(unsigned i=0; i<total_nodes; ++i){ - in_buffer_util+=in_buffers[i].size(); - out_buffer_util+=out_buffers[i].size(); - } + // collect some stats about buffer util + for (unsigned i = 0; i < total_nodes; ++i) { + in_buffer_util += in_buffers[i].size(); + out_buffer_util += out_buffers[i].size(); + } cycles++; } - - bool xbar_router::Busy() const { + for (unsigned i = 0; i < total_nodes; ++i) { + if (!in_buffers[i].empty()) return true; - for(unsigned i=0; i<total_nodes; ++i){ - if(!in_buffers[i].empty()) - return true; - - if(!out_buffers[i].empty()) - return true; - } - return false; + if (!out_buffers[i].empty()) return true; + } + return false; } - //////////////////////////////////////////////////// /////////////LocalInterconnect///////////////////// -//assume all the packets are one flit +// 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); +LocalInterconnect* LocalInterconnect::New( + const struct inct_config& m_localinct_config) { + LocalInterconnect* icnt_interface = new LocalInterconnect(m_localinct_config); - return icnt_interface; + 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( + 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 (unsigned i = 0; i < m_inct_config.subnets; ++i) { - delete net[i]; - } +LocalInterconnect::~LocalInterconnect() { + for (unsigned 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; +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.resize(n_subnets); + for (unsigned i = 0; i < n_subnets; ++i) { net[i] = new xbar_router( i, static_cast<Interconnect_type>(i), m_n_shader, m_n_mem, m_inct_config); - } - + } } - void LocalInterconnect::Init() { - //empty - //there is nothing to do - + // empty + // there is nothing to do } -void LocalInterconnect::Push(unsigned input_deviceID, unsigned output_deviceID, void* data, unsigned int size){ +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; + } + } - 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); + // 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::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(); - } - +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::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; +bool LocalInterconnect::HasBuffer(unsigned deviceID, unsigned int size) const { + bool has_buffer = false; - if ((n_subnets>1) && deviceID >= n_shader) // deviceID is memory node - has_buffer = net[REPLY_NET]->Has_Buffer_In(deviceID, 1, true); - else - has_buffer = net[REQ_NET]->Has_Buffer_In(deviceID, 1, true); - - return has_buffer; + if ((n_subnets > 1) && deviceID >= n_shader) // deviceID is memory node + has_buffer = net[REPLY_NET]->Has_Buffer_In(deviceID, 1, true); + else + has_buffer = net[REQ_NET]->Has_Buffer_In(deviceID, 1, true); + return has_buffer; } -void LocalInterconnect::DisplayStats() const{ - +void LocalInterconnect::DisplayStats() const { printf("Req_Network_injected_packets_num = %lld\n", net[REQ_NET]->packets_num); printf("Req_Network_cycles = %lld\n", net[REQ_NET]->cycles); printf("Req_Network_injected_packets_per_cycle = %12.4f \n", (float)(net[REQ_NET]->packets_num) / (net[REQ_NET]->cycles)); @@ -439,16 +406,10 @@ void LocalInterconnect::DisplayStats() const{ } -void LocalInterconnect::DisplayOverallStats() const{ +void LocalInterconnect::DisplayOverallStats() const {} -} +unsigned LocalInterconnect::GetFlitSize() const { return LOCAL_INCT_FLIT_SIZE; } -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"); } - -void LocalInterconnect::DisplayState(FILE* fp) const{ - - fprintf(fp, "GPGPU-Sim uArch: ICNT:Display State: Under implementation\n"); -} - |
