From 69f2911e04ffb1b19eef1fafb8c040af271f656e Mon Sep 17 00:00:00 2001 From: Tor Aamodt Date: Thu, 15 Jul 2010 18:09:46 -0800 Subject: creating branch for adding support for CUDA 3.x and Fermi [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 6829] --- src/intersim/interconnect_interface.cpp | 574 ++++++++++++++++++++++++++++++++ 1 file changed, 574 insertions(+) create mode 100644 src/intersim/interconnect_interface.cpp (limited to 'src/intersim/interconnect_interface.cpp') diff --git a/src/intersim/interconnect_interface.cpp b/src/intersim/interconnect_interface.cpp new file mode 100644 index 0000000..bb30f81 --- /dev/null +++ b/src/intersim/interconnect_interface.cpp @@ -0,0 +1,574 @@ +#include "booksim.hpp" +#include +#include +#include +#include +#include + +#include "routefunc.hpp" +#include "traffic.hpp" +#include "booksim_config.hpp" +#include "trafficmanager.hpp" +#include "random_utils.hpp" +#include "network.hpp" +#include "singlenet.hpp" +#include "kncube.hpp" +#include "fly.hpp" +#include "injection.hpp" +#include "interconnect_interface.h" +#include "../gpgpu-sim/mem_fetch.h" +#include + +extern unsigned long long gpu_sim_cycle; +int _flit_size ; +extern unsigned int warp_size; + +bool doub_net = false; //double networks disabled by default + +BookSimConfig icnt_config; +TrafficManager** traffic; +unsigned int g_num_vcs; //number of virtual channels +queue ** ejection_buf; +vector round_robin_turn; //keep track of boundary_buf last used in icnt_pop +unsigned int ejection_buffer_capacity ; +unsigned int boundary_buf_capacity ; + +unsigned int input_buffer_capacity ; + +class boundary_buf{ +private: + queue buf; + queue tail_flag; + int packet_n; + unsigned capacity; +public: + boundary_buf(){ + capacity = boundary_buf_capacity; //maximum flits the buffer can hold + packet_n=0; + } + bool is_full(void){ + return (buf.size()>=capacity); + } + bool has_packet() { + return (packet_n); + } + void * pop_packet(){ + assert (packet_n); + void * data = NULL; + void * temp_d = buf.front(); + while (data==NULL) { + if (tail_flag.front()) { + data = buf.front(); + packet_n--; + } + assert(temp_d == buf.front()); //all flits must belong to the same packet + buf.pop(); + tail_flag.pop(); + } + return data; + } + void push_flit_data(void* data,bool is_tail) { + buf.push(data); + tail_flag.push(is_tail); + if (is_tail) { + packet_n++; + } + } +}; + +boundary_buf** clock_boundary_buf; + +class mycomparison { +public: + bool operator() (const void* lhs, const void* rhs) const + { + return( ((mem_fetch_t *)lhs)->icnt_receive_time > ((mem_fetch_t *) rhs)->icnt_receive_time); + } +}; + +bool perfect_icnt = 0; +int fixed_lat_icnt = 0; + +priority_queue, mycomparison> * out_buf_fixedlat_buf; + + +//perfect icnt stats: +unsigned int* max_fixedlat_buf_size; + +static unsigned int net_c; //number of inetrconnection networks + +static unsigned int _n_shader = 0; +static unsigned int _n_mem = 0; + +static int * node_map; //deviceID to mesh location map + //deviceID : Starts from 0 for shaders and then continues until mem nodes + // which starts at location n_shader and then continues to n_shader+n_mem (last device) +static int * reverse_map; + +void map_gen(int dim,int memcount, int memnodes[]) +{ + int k = 0; + int i=0 ; + int j=0 ; + int memfound=0; + for (i = 0; i < dim*dim ; i++) { + memfound=0; + for (j = 0; jShowStats(); + if (icnt_config.GetInt("enable_link_stats")) { + cout << "%=================================" << endl; + cout <<"Traffic "<_net->Display(); + } + } + } else { + //show max queue sizes + cout<<"Max Fixed Latency ICNT queue size for"<ShowOveralStat(); + } + } +} + +void icnt_init_grid (){ + for (unsigned i=0; iIcntInitPerGrid(0/*_time*/); //initialization before gpu grid start + } +} + +int interconnect_has_buffer(unsigned int input_node, + unsigned int *size) +{ + + unsigned int input = node_map[input_node]; + int has_buffer; + int tot_req_size = 0; + for (unsigned int i=0; i<(_n_mem+_n_shader);i++ ) { + if (size[i]) { + tot_req_size+= size[i]; + } + } + unsigned int n_flits = tot_req_size / _flit_size + ((tot_req_size % _flit_size)? 1:0); + if (!(fixed_lat_icnt || perfect_icnt)) { + has_buffer = (traffic[0]->_partial_packets[input][0].size() + n_flits) <= input_buffer_capacity; + if ((net_c>1) && is_mem(input)) { + has_buffer = (traffic[1]->_partial_packets[input][0].size() + n_flits) <= input_buffer_capacity; + } + } else { + has_buffer = 1; + } + return has_buffer; +} + +void interconnect_push ( unsigned int input_node, unsigned int output_node, + void* data, unsigned int size) +{ + int output = node_map[output_node]; + int input = node_map[input_node]; + +#if 0 + cout<<"Call interconnect push input: "<icnt_receive_time = gpu_sim_cycle + fixed_latency(input,output); + out_buf_fixedlat_buf[output].push(data); //deliver the whole packet to destination in zero cycles + if (out_buf_fixedlat_buf[output].size() > max_fixedlat_buf_size[output]) { + max_fixedlat_buf_size[output]= out_buf_fixedlat_buf[output].size(); + } + } else { + + unsigned int n_flits = size / _flit_size + ((size % _flit_size)? 1:0); + int nc; + if (!doub_net) { + nc=0; + } else //doub_net enabled + if (is_shd(input) ) { + nc=0; + } else { + nc=1; + } + traffic[nc]->_GeneratePacket( input, n_flits, 0 /*class*/, traffic[nc]->_time, data, output); +#if DOUB + cout <<"Traffic[" << nc << "] (mapped) sending form "<< input << " to " << output <icnt_receive_time <= gpu_sim_cycle) { + data = out_buf_fixedlat_buf[output].top(); + out_buf_fixedlat_buf[output].pop(); + assert (((mem_fetch_t *)data)->icnt_receive_time); + } + } + } else { + unsigned vc; + unsigned turn = round_robin_turn[output]; + for (vc=0;(vc2) { + cout <InsertRandomFaults( icnt_config ); + } + + traffic[i] = new TrafficManager ( icnt_config, net[i], i/*id*/ ); + } + + fixed_lat_icnt = icnt_config.GetInt( "fixed_lat_per_hop" ); + + if (icnt_config.GetInt( "perfect_icnt" )) { + perfect_icnt = true; + fixed_lat_icnt = 1; + } + _flit_size = icnt_config.GetInt( "flit_size" ); + if (icnt_config.GetInt("ejection_buf_size")) { + ejection_buffer_capacity = icnt_config.GetInt( "ejection_buf_size" ) ; + } else { + ejection_buffer_capacity = icnt_config.GetInt( "vc_buf_size" ); + } + boundary_buf_capacity = icnt_config.GetInt( "boundary_buf_size" ) ; + if (icnt_config.GetInt("input_buf_size")) { + input_buffer_capacity = icnt_config.GetInt("input_buf_size"); + } else { + if (gpgpu_cache_dl1_opt && !gpgpu_no_dl1) { + int l1cache_linesize = 32; + sscanf(gpgpu_cache_dl1_opt,"%*d:%d:%*d:%*c", &l1cache_linesize); + input_buffer_capacity = gpu_n_thread_per_shader*(l1cache_linesize/_flit_size+(int)ceil(8.0f/_flit_size)); + } else { + input_buffer_capacity = gpu_n_thread_per_shader*((int)ceil(8.0f/_flit_size)); + } + } + create_buf(traffic[0]->_dests,warp_size,icnt_config.GetInt( "num_vcs" )); + MATLAB_OUTPUT = icnt_config.GetInt("MATLAB_OUTPUT"); + DISPLAY_LAT_DIST = icnt_config.GetInt("DISPLAY_LAT_DIST"); + DISPLAY_HOP_DIST = icnt_config.GetInt("DISPLAY_HOP_DIST"); + DISPLAY_PAIR_LATENCY = icnt_config.GetInt("DISPLAY_PAIR_LATENCY"); + create_node_map(n_shader,n_mem,traffic[0]->_dests, icnt_config.GetInt("use_map")); + for (unsigned i=0;i_FirstStep(); + } +} + +void advance_interconnect () +{ + if (!fixed_lat_icnt) { + for (unsigned i=0;i_Step( ); + } + } +} + +unsigned interconnect_busy() +{ + unsigned i,j; + for(i=0; i_measured_in_flight) { + return 1; + } + } + for ( i=0 ;i<(_n_shader+_n_mem);i++ ) { + if ( !traffic[0]->_partial_packets[i] [0].empty() ) { + return 1; + } + if ( doub_net && !traffic[1]->_partial_packets[i] [0].empty() ) { + return 1; + } + for ( j=0;j* [src_n]; + clock_boundary_buf = new boundary_buf* [src_n]; + round_robin_turn.resize( src_n ); + for (i=0;i[vc_n]; + clock_boundary_buf[i]= new boundary_buf[vc_n]; + round_robin_turn[vc_n-1]; + } + if (fixed_lat_icnt) { + out_buf_fixedlat_buf = new priority_queue, mycomparison> [src_n]; + max_fixedlat_buf_size = new unsigned int [src_n]; + for (i=0;ivc; + assert (ejection_buf[output][vc].size() < ejection_buffer_capacity); + ejection_buf[output][vc].push(flit); +} + +void transfer2boundary_buf(int output) { + Flit* flit; + unsigned vc; + for (vc=0; vcdata, flit->tail); + traffic[flit->net_num]->credit_return_queue[output].push(flit); //will send back credit + if ( flit->head ) { + assert (flit->dest == output); + } +#if DOUB + cout <<"Traffic " <write? mf->request_uid : mf->mshr->insts[0].uid; + long int cycle = gpu_sim_cycle + gpu_tot_sim_cycle; + int req_type = mf->write? WT_REQ : RD_REQ; + if (is_mem(input)) { + time_vector_update( uid, MR_2SH_ICNT_INJECTED, cycle, req_type ); + } else { + time_vector_update( uid, MR_ICNT_INJECTED, cycle,req_type ); + } +} -- cgit v1.3