#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 "../gpgpu-sim/gpu-sim.h" #include "../gpgpu-sim/shader.h" #include int _flit_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 *)lhs)->icnt_receive_time > ((mem_fetch *) 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 interconnection 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 tot_req_size) { unsigned int input = node_map[input_node]; int has_buffer; 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 *)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 (shader_config->gpgpu_cache_dl1_opt && !shader_config->gpgpu_no_dl1) { int l1cache_linesize = 32; sscanf(shader_config->gpgpu_cache_dl1_opt,"%*d:%d:%*d:%*c", &l1cache_linesize); input_buffer_capacity = shader_config->n_thread_per_shader*(l1cache_linesize/_flit_size+(int)ceil(8.0f/_flit_size)); } else { input_buffer_capacity = shader_config->n_thread_per_shader*((int)ceil(8.0f/_flit_size)); } } create_buf(traffic[0]->_dests,shader_config->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 " <mshr && !mf->mshr->isinst() ) { unsigned uid=mf->m_write? mf->request_uid : mf->mshr->get_insts_uid(); long int cycle = gpu_sim_cycle + gpu_tot_sim_cycle; int req_type = mf->m_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 ); } } }