From f06a527258b4a6634f8f148536bb86635b058d55 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Tue, 30 Oct 2018 13:03:50 -0400 Subject: updating the TITANV config --- src/gpgpu-sim/gpu-sim.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index d02e8e1..8bbadf5 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -1043,18 +1043,18 @@ void gpgpu_sim::gpu_print_stat() printf("gpu_stall_dramfull = %d\n", gpu_stall_dramfull); printf("gpu_stall_icnt2sh = %d\n", gpu_stall_icnt2sh ); - printf("partiton_reqs_in_parallel = %lld\n", partiton_reqs_in_parallel); - printf("partiton_reqs_in_parallel_total = %lld\n", partiton_reqs_in_parallel_total ); + //printf("partiton_reqs_in_parallel = %lld\n", partiton_reqs_in_parallel); + //printf("partiton_reqs_in_parallel_total = %lld\n", partiton_reqs_in_parallel_total ); printf("partiton_level_parallism = %12.4f\n", (float)partiton_reqs_in_parallel / gpu_sim_cycle); printf("partiton_level_parallism_total = %12.4f\n", (float)(partiton_reqs_in_parallel+partiton_reqs_in_parallel_total) / (gpu_tot_sim_cycle+gpu_sim_cycle) ); - printf("partiton_reqs_in_parallel_util = %lld\n", partiton_reqs_in_parallel_util); - printf("partiton_reqs_in_parallel_util_total = %lld\n", partiton_reqs_in_parallel_util_total ); - printf("gpu_sim_cycle_parition_util = %lld\n", gpu_sim_cycle_parition_util); - printf("gpu_tot_sim_cycle_parition_util = %lld\n", gpu_tot_sim_cycle_parition_util ); + //printf("partiton_reqs_in_parallel_util = %lld\n", partiton_reqs_in_parallel_util); + //printf("partiton_reqs_in_parallel_util_total = %lld\n", partiton_reqs_in_parallel_util_total ); + //printf("gpu_sim_cycle_parition_util = %lld\n", gpu_sim_cycle_parition_util); + // printf("gpu_tot_sim_cycle_parition_util = %lld\n", gpu_tot_sim_cycle_parition_util ); printf("partiton_level_parallism_util = %12.4f\n", (float)partiton_reqs_in_parallel_util / gpu_sim_cycle_parition_util); printf("partiton_level_parallism_util_total = %12.4f\n", (float)(partiton_reqs_in_parallel_util+partiton_reqs_in_parallel_util_total) / (gpu_sim_cycle_parition_util+gpu_tot_sim_cycle_parition_util) ); - printf("partiton_replys_in_parallel = %lld\n", partiton_replys_in_parallel); - printf("partiton_replys_in_parallel_total = %lld\n", partiton_replys_in_parallel_total ); + //printf("partiton_replys_in_parallel = %lld\n", partiton_replys_in_parallel); + //printf("partiton_replys_in_parallel_total = %lld\n", partiton_replys_in_parallel_total ); printf("L2_BW = %12.4f GB/Sec\n", ((float)(partiton_replys_in_parallel * 32) / (gpu_sim_cycle * m_config.icnt_period)) / 1000000000); printf("L2_BW_total = %12.4f GB/Sec\n", ((float)((partiton_replys_in_parallel+partiton_replys_in_parallel_total) * 32) / ((gpu_tot_sim_cycle+gpu_sim_cycle) * m_config.icnt_period)) / 1000000000 ); -- cgit v1.3 From f799cd5485a36de48abce286b2f69cee75d2be38 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 5 Nov 2018 20:01:42 -0500 Subject: adding Volta sub_core model and double L1 BW --- configs/tested-cfgs/SM7_TITANV/gpgpusim.config | 29 ++--- src/abstract_hardware_model.h | 20 ++- src/gpgpu-sim/gpu-sim.cc | 11 +- src/gpgpu-sim/shader.cc | 161 +++++++++++++++---------- src/gpgpu-sim/shader.h | 36 ++++-- 5 files changed, 168 insertions(+), 89 deletions(-) (limited to 'src') diff --git a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config index 03ef5b9..2093cc0 100644 --- a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config +++ b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config @@ -42,9 +42,9 @@ # Pipeline widths and number of FUs # ID_OC_SP,ID_OC_DP,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_SFU,OC_EX_MEM,EX_WB -## Volta GV100 has 2 SP SIMD units, 2 SFU units, 2 DP units per core +## Volta GV100 has 4 SP SIMD units, 4SFU units, 4 DP units per core ## we need to scale the number of pipeline registers to be equal to the number of SP units --gpgpu_pipeline_widths 4,4,4,4,4,4,4,4,12 +-gpgpu_pipeline_widths 4,4,4,4,4,4,4,4,8 -gpgpu_num_sp_units 4 -gpgpu_num_sfu_units 4 -gpgpu_num_dp_units 4 @@ -72,6 +72,8 @@ # For more info, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x # disable this mode in case of multi kernels/apps execution -adpative_volta_cache_config 1 +# Volta unified cache has four ports +-mem_unit_ports 4 -gpgpu_cache:dl1 S:4:128:64,L:L:s:N:L,A:256:8,16:0,32 -gpgpu_shmem_size 98304 -gmem_skip_L1D 0 @@ -96,20 +98,15 @@ # 64 KB Const -gpgpu_const_cache:l1 N:128:64:8,L:R:f:N:L,S:2:64,4 -# enable operand collector --gpgpu_operand_collector_num_units_sp 12 --gpgpu_operand_collector_num_units_sfu 6 --gpgpu_operand_collector_num_units_mem 8 --gpgpu_operand_collector_num_units_dp 6 --gpgpu_operand_collector_num_in_ports_sp 4 --gpgpu_operand_collector_num_out_ports_sp 4 --gpgpu_operand_collector_num_in_ports_sfu 1 --gpgpu_operand_collector_num_out_ports_sfu 1 --gpgpu_operand_collector_num_in_ports_mem 1 --gpgpu_operand_collector_num_out_ports_mem 1 --gpgpu_operand_collector_num_in_ports_dp 1 --gpgpu_operand_collector_num_out_ports_dp 1 -# two banks per scheduler +# Volta has sub core model, in which each scheduler has its own reisiter file and EUs +# i.e. schedulers are isolated +-sub_core_model 1 +# disable specialized operand collectors and use generic operand collectors instead +-enable_specialized_operand_collector 0 +-gpgpu_operand_collector_num_units_gen 8 +-gpgpu_operand_collector_num_in_ports_gen 8 +-gpgpu_operand_collector_num_out_ports_gen 8 +# volta has 8 banks, 4 schedulers, two banks per scheduler -gpgpu_num_reg_banks 8 # shared memory bankconflict detection diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 8333247..d0f7066 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -336,6 +336,7 @@ struct core_config { unsigned gpgpu_shmem_sizeDefault; unsigned gpgpu_shmem_sizePrefL1; unsigned gpgpu_shmem_sizePrefShared; + unsigned mem_unit_ports; // texture and constant cache line sizes (used to determine number of memory accesses) unsigned gpgpu_cache_texl1_linesize; @@ -908,7 +909,7 @@ public: { m_empty=true; } - void issue( const active_mask_t &mask, unsigned warp_id, unsigned long long cycle, int dynamic_warp_id ) + void issue( const active_mask_t &mask, unsigned warp_id, unsigned long long cycle, int dynamic_warp_id, int sch_id ) { m_warp_active_mask = mask; m_warp_issued_mask = mask; @@ -919,6 +920,7 @@ public: cycles = initiation_interval; m_cache_hit=false; m_empty=false; + m_scheduler_id=sch_id; } const active_mask_t & get_active_mask() const { @@ -1037,6 +1039,7 @@ public: void print( FILE *fout ) const; unsigned get_uid() const { return m_uid; } + unsigned get_schd_id() const { return m_scheduler_id; } protected: @@ -1069,6 +1072,8 @@ protected: static unsigned sm_next_uid; + unsigned m_scheduler_id; //the scheduler that issues this inst + //Jin: cdp support public: int m_is_cdp; @@ -1161,6 +1166,10 @@ public: } return false; } + bool has_free(unsigned reg_id){ + assert(reg_id < regs.size()); + return regs[reg_id]->empty(); + } bool has_ready(){ for( unsigned i = 0; i < regs.size(); i++ ) { if( not regs[i]->empty() ) { @@ -1216,6 +1225,15 @@ public: return NULL; } + warp_inst_t ** get_free(unsigned reg_id){ + assert(reg_id < regs.size()); + if( regs[reg_id]->empty() ) { + return ®s[reg_id]; + } + assert(0 && "No free register found"); + return NULL; + } + private: std::vector regs; const char* m_name; diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 8bbadf5..f318f7d 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -329,6 +329,9 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_shmem_warp_parts", OPT_INT32, &mem_warp_parts, "Number of portions a warp is divided into for shared memory bank conflict check ", "2"); + option_parser_register(opp, "-mem_unit_ports", OPT_INT32, &mem_unit_ports, + "The number of memory transactions allowed per core cycle", + "1"); option_parser_register(opp, "-gpgpu_shmem_warp_parts", OPT_INT32, &mem_warp_parts, "Number of portions a warp is divided into for shared memory bank conflict check ", "2"); @@ -347,8 +350,14 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_reg_bank_use_warp_id", OPT_BOOL, &gpgpu_reg_bank_use_warp_id, "Use warp ID in mapping registers to banks (default = off)", "0"); + option_parser_register(opp, "-sub_core_model", OPT_BOOL, &sub_core_model, + "Sub Core Volta/Pascal model (default = off)", + "0"); + option_parser_register(opp, "-enable_specialized_operand_collector", OPT_BOOL, &enable_specialized_operand_collector, + "enable_specialized_operand_collector", + "1"); option_parser_register(opp, "-gpgpu_operand_collector_num_units_sp", OPT_INT32, &gpgpu_operand_collector_num_units_sp, - "number of collector units (default = 4)", + "number of collector units (default = 4)", "4"); option_parser_register(opp, "-gpgpu_operand_collector_num_units_dp", OPT_INT32, &gpgpu_operand_collector_num_units_dp, "number of collector units (default = 0)", diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 8a84970..300871e 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -234,52 +234,12 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, //op collector configuration enum { SP_CUS, DP_CUS, SFU_CUS, MEM_CUS, GEN_CUS }; - m_operand_collector.add_cu_set(SP_CUS, m_config->gpgpu_operand_collector_num_units_sp, m_config->gpgpu_operand_collector_num_out_ports_sp); - m_operand_collector.add_cu_set(DP_CUS, m_config->gpgpu_operand_collector_num_units_dp, m_config->gpgpu_operand_collector_num_out_ports_dp); - m_operand_collector.add_cu_set(SFU_CUS, m_config->gpgpu_operand_collector_num_units_sfu, m_config->gpgpu_operand_collector_num_out_ports_sfu); - m_operand_collector.add_cu_set(MEM_CUS, m_config->gpgpu_operand_collector_num_units_mem, m_config->gpgpu_operand_collector_num_out_ports_mem); - m_operand_collector.add_cu_set(GEN_CUS, m_config->gpgpu_operand_collector_num_units_gen, m_config->gpgpu_operand_collector_num_out_ports_gen); - opndcoll_rfu_t::port_vector_t in_ports; opndcoll_rfu_t::port_vector_t out_ports; opndcoll_rfu_t::uint_vector_t cu_sets; - for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_sp; i++) { - in_ports.push_back(&m_pipeline_reg[ID_OC_SP]); - out_ports.push_back(&m_pipeline_reg[OC_EX_SP]); - cu_sets.push_back((unsigned)SP_CUS); - cu_sets.push_back((unsigned)GEN_CUS); - m_operand_collector.add_port(in_ports,out_ports,cu_sets); - in_ports.clear(),out_ports.clear(),cu_sets.clear(); - } - - for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_dp; i++) { - in_ports.push_back(&m_pipeline_reg[ID_OC_DP]); - out_ports.push_back(&m_pipeline_reg[OC_EX_DP]); - cu_sets.push_back((unsigned)DP_CUS); - cu_sets.push_back((unsigned)GEN_CUS); - m_operand_collector.add_port(in_ports,out_ports,cu_sets); - in_ports.clear(),out_ports.clear(),cu_sets.clear(); - } - for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_sfu; i++) { - in_ports.push_back(&m_pipeline_reg[ID_OC_SFU]); - out_ports.push_back(&m_pipeline_reg[OC_EX_SFU]); - cu_sets.push_back((unsigned)SFU_CUS); - cu_sets.push_back((unsigned)GEN_CUS); - m_operand_collector.add_port(in_ports,out_ports,cu_sets); - in_ports.clear(),out_ports.clear(),cu_sets.clear(); - } - - for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_mem; i++) { - in_ports.push_back(&m_pipeline_reg[ID_OC_MEM]); - out_ports.push_back(&m_pipeline_reg[OC_EX_MEM]); - cu_sets.push_back((unsigned)MEM_CUS); - cu_sets.push_back((unsigned)GEN_CUS); - m_operand_collector.add_port(in_ports,out_ports,cu_sets); - in_ports.clear(),out_ports.clear(),cu_sets.clear(); - } - - + //configure generic collectors + m_operand_collector.add_cu_set(GEN_CUS, m_config->gpgpu_operand_collector_num_units_gen, m_config->gpgpu_operand_collector_num_out_ports_gen); for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_gen; i++) { in_ports.push_back(&m_pipeline_reg[ID_OC_SP]); in_ports.push_back(&m_pipeline_reg[ID_OC_SFU]); @@ -287,10 +247,57 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, out_ports.push_back(&m_pipeline_reg[OC_EX_SP]); out_ports.push_back(&m_pipeline_reg[OC_EX_SFU]); out_ports.push_back(&m_pipeline_reg[OC_EX_MEM]); - cu_sets.push_back((unsigned)GEN_CUS); + if(m_config->gpgpu_num_dp_units > 0) { + in_ports.push_back(&m_pipeline_reg[ID_OC_DP]); + out_ports.push_back(&m_pipeline_reg[OC_EX_DP]); + } + cu_sets.push_back((unsigned)GEN_CUS); m_operand_collector.add_port(in_ports,out_ports,cu_sets); in_ports.clear(),out_ports.clear(),cu_sets.clear(); } + + if(m_config->enable_specialized_operand_collector) { + m_operand_collector.add_cu_set(SP_CUS, m_config->gpgpu_operand_collector_num_units_sp, m_config->gpgpu_operand_collector_num_out_ports_sp); + m_operand_collector.add_cu_set(DP_CUS, m_config->gpgpu_operand_collector_num_units_dp, m_config->gpgpu_operand_collector_num_out_ports_dp); + m_operand_collector.add_cu_set(SFU_CUS, m_config->gpgpu_operand_collector_num_units_sfu, m_config->gpgpu_operand_collector_num_out_ports_sfu); + m_operand_collector.add_cu_set(MEM_CUS, m_config->gpgpu_operand_collector_num_units_mem, m_config->gpgpu_operand_collector_num_out_ports_mem); + + for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_sp; i++) { + in_ports.push_back(&m_pipeline_reg[ID_OC_SP]); + out_ports.push_back(&m_pipeline_reg[OC_EX_SP]); + cu_sets.push_back((unsigned)SP_CUS); + cu_sets.push_back((unsigned)GEN_CUS); + m_operand_collector.add_port(in_ports,out_ports,cu_sets); + in_ports.clear(),out_ports.clear(),cu_sets.clear(); + } + + for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_dp; i++) { + in_ports.push_back(&m_pipeline_reg[ID_OC_DP]); + out_ports.push_back(&m_pipeline_reg[OC_EX_DP]); + cu_sets.push_back((unsigned)DP_CUS); + cu_sets.push_back((unsigned)GEN_CUS); + m_operand_collector.add_port(in_ports,out_ports,cu_sets); + in_ports.clear(),out_ports.clear(),cu_sets.clear(); + } + + for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_sfu; i++) { + in_ports.push_back(&m_pipeline_reg[ID_OC_SFU]); + out_ports.push_back(&m_pipeline_reg[OC_EX_SFU]); + cu_sets.push_back((unsigned)SFU_CUS); + cu_sets.push_back((unsigned)GEN_CUS); + m_operand_collector.add_port(in_ports,out_ports,cu_sets); + in_ports.clear(),out_ports.clear(),cu_sets.clear(); + } + + for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_mem; i++) { + in_ports.push_back(&m_pipeline_reg[ID_OC_MEM]); + out_ports.push_back(&m_pipeline_reg[OC_EX_MEM]); + cu_sets.push_back((unsigned)MEM_CUS); + cu_sets.push_back((unsigned)GEN_CUS); + m_operand_collector.add_port(in_ports,out_ports,cu_sets); + in_ports.clear(),out_ports.clear(),cu_sets.clear(); + } + } m_operand_collector.init( m_config->gpgpu_num_reg_banks, this ); @@ -761,15 +768,19 @@ void shader_core_ctx::func_exec_inst( warp_inst_t &inst ) inst.generate_mem_accesses(); } -void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t* next_inst, const active_mask_t &active_mask, unsigned warp_id ) +void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t* next_inst, const active_mask_t &active_mask, unsigned warp_id, unsigned sch_id ) { - warp_inst_t** pipe_reg = pipe_reg_set.get_free(); + warp_inst_t** pipe_reg; + if(m_config->sub_core_model) + pipe_reg = pipe_reg_set.get_free(sch_id); + else + pipe_reg = pipe_reg_set.get_free(); assert(pipe_reg); m_warp[warp_id].ibuffer_free(); assert(next_inst->valid()); **pipe_reg = *next_inst; // static instruction information - (*pipe_reg)->issue( active_mask, warp_id, gpu_tot_sim_cycle + gpu_sim_cycle, m_warp[warp_id].get_dynamic_warp_id() ); // dynamic instruction information + (*pipe_reg)->issue( active_mask, warp_id, gpu_tot_sim_cycle + gpu_sim_cycle, m_warp[warp_id].get_dynamic_warp_id(), sch_id ); // dynamic instruction information m_stats->shader_cycle_distro[2+(*pipe_reg)->active_count()]++; func_exec_inst( **pipe_reg ); if( next_inst->op == BARRIER_OP ){ @@ -950,8 +961,8 @@ void scheduler_unit::cycle() const active_mask_t &active_mask = m_simt_stack[warp_id]->get_active_mask(); assert( warp(warp_id).inst_in_pipeline() ); if ( (pI->op == LOAD_OP) || (pI->op == STORE_OP) || (pI->op == MEMORY_BARRIER_OP) ) { - if( m_mem_out->has_free() && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::MEM)) { - m_shader->issue_warp(*m_mem_out,pI,active_mask,warp_id); + if( m_mem_out->has_free(m_id) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::MEM)) { + m_shader->issue_warp(*m_mem_out,pI,active_mask,warp_id,m_id); issued++; issued_inst=true; warp_inst_issued = true; @@ -959,9 +970,9 @@ void scheduler_unit::cycle() } } else { - bool sp_pipe_avail = m_sp_out->has_free(); - bool sfu_pipe_avail = m_sfu_out->has_free(); - bool dp_pipe_avail = m_dp_out->has_free(); + bool sp_pipe_avail = m_sp_out->has_free(m_id); + bool sfu_pipe_avail = m_sfu_out->has_free(m_id); + bool dp_pipe_avail = m_dp_out->has_free(m_id); if( sp_pipe_avail && (pI->op != SFU_OP && pI->op != DP_OP) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::SP)) { //Jin: special for CDP api @@ -983,14 +994,14 @@ void scheduler_unit::cycle() } // always prefer SP pipe for operations that can use both SP and SFU pipelines - m_shader->issue_warp(*m_sp_out,pI,active_mask,warp_id); + m_shader->issue_warp(*m_sp_out,pI,active_mask,warp_id,m_id); issued++; issued_inst=true; warp_inst_issued = true; previous_issued_inst_exec_type = exec_unit_type_t::SP; } else if ( (m_shader->m_config->gpgpu_num_dp_units != 0) && (pI->op == DP_OP) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::DP)) { if( dp_pipe_avail ) { - m_shader->issue_warp(*m_dp_out,pI,active_mask,warp_id); + m_shader->issue_warp(*m_dp_out,pI,active_mask,warp_id,m_id); issued++; issued_inst=true; warp_inst_issued = true; @@ -999,7 +1010,7 @@ void scheduler_unit::cycle() } //If the DP units = 0 (like in Fermi archi), then change DP inst to SFU inst else if ( ((m_shader->m_config->gpgpu_num_dp_units == 0 && pI->op == DP_OP) || (pI->op == SFU_OP) || (pI->op == ALU_SFU_OP)) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::SFU)) { if( sfu_pipe_avail ) { - m_shader->issue_warp(*m_sfu_out,pI,active_mask,warp_id); + m_shader->issue_warp(*m_sfu_out,pI,active_mask,warp_id,m_id); issued++; issued_inst=true; warp_inst_issued = true; @@ -2068,7 +2079,11 @@ void ldst_unit::writeback() unsigned ldst_unit::clock_multiplier() const { - return m_config->mem_warp_parts; + //to model multiple read port, we give multiple cycles for the memory units + if(m_config->mem_unit_ports) + return m_config->mem_unit_ports; + else + return m_config->mem_warp_parts; } /* void ldst_unit::issue( register_set ®_set ) @@ -3305,18 +3320,34 @@ void opndcoll_rfu_t::init( unsigned num_banks, shader_core_ctx *shader ) m_bank_warp_shift = (unsigned)(int) (log(m_warp_size+0.5) / log(2.0)); assert( (m_bank_warp_shift == 5) || (m_warp_size != 32) ); + sub_core_model = shader->get_config()->sub_core_model; + m_num_warp_sceds = shader->get_config()->gpgpu_num_sched_per_core; + if(sub_core_model) + assert(num_banks % shader->get_config()->gpgpu_num_sched_per_core == 0); + m_num_banks_per_sched = num_banks / shader->get_config()->gpgpu_num_sched_per_core; + for( unsigned j=0; jinit(j,num_banks,m_bank_warp_shift,shader->get_config(),this); + m_cu[j]->init(j,num_banks,m_bank_warp_shift,shader->get_config(),this, sub_core_model, m_num_banks_per_sched ); } m_initialized=true; + + + + } -int register_bank(int regnum, int wid, unsigned num_banks, unsigned bank_warp_shift) +int register_bank(int regnum, int wid, unsigned num_banks, unsigned bank_warp_shift, bool sub_core_model, unsigned banks_per_sched, unsigned sched_id) { int bank = regnum; if (bank_warp_shift) bank += wid; - return bank % num_banks; + if(sub_core_model) { + unsigned bank_num = (bank % banks_per_sched) + (sched_id * banks_per_sched); + assert(bank_num < num_banks); + return bank_num; + } + else + return bank % num_banks; } bool opndcoll_rfu_t::writeback( const warp_inst_t &inst ) @@ -3327,9 +3358,9 @@ bool opndcoll_rfu_t::writeback( const warp_inst_t &inst ) unsigned n=0; for( r=regs.begin(); r!=regs.end();r++,n++ ) { unsigned reg = *r; - unsigned bank = register_bank(reg,inst.warp_id(),m_num_banks,m_bank_warp_shift); + unsigned bank = register_bank(reg,inst.warp_id(),m_num_banks,m_bank_warp_shift, sub_core_model, m_num_banks_per_sched, inst.get_schd_id()); if( m_arbiter.bank_idle(bank) ) { - m_arbiter.allocate_bank_for_write(bank,op_t(&inst,reg,m_num_banks,m_bank_warp_shift)); + m_arbiter.allocate_bank_for_write(bank,op_t(&inst,reg,m_num_banks,m_bank_warp_shift, sub_core_model, m_num_banks_per_sched, inst.get_schd_id())); } else { return false; } @@ -3413,7 +3444,7 @@ void opndcoll_rfu_t::allocate_reads() const op_t &rr = *r; unsigned reg = rr.get_reg(); unsigned wid = rr.get_wid(); - unsigned bank = register_bank(reg,wid,m_num_banks,m_bank_warp_shift); + unsigned bank = register_bank(reg,wid,m_num_banks,m_bank_warp_shift,sub_core_model, m_num_banks_per_sched, rr.get_sid()); m_arbiter.allocate_for_read(bank,rr); read_ops[bank] = rr; } @@ -3464,7 +3495,9 @@ void opndcoll_rfu_t::collector_unit_t::init( unsigned n, unsigned num_banks, unsigned log2_warp_size, const core_config *config, - opndcoll_rfu_t *rfu ) + opndcoll_rfu_t *rfu, + bool sub_core_model, + unsigned banks_per_sched) { m_rfu=rfu; m_cuid=n; @@ -3472,6 +3505,8 @@ void opndcoll_rfu_t::collector_unit_t::init( unsigned n, assert(m_warp==NULL); m_warp = new warp_inst_t(config); m_bank_warp_shift=log2_warp_size; + m_sub_core_model = sub_core_model; + m_num_banks_per_sched = banks_per_sched; } bool opndcoll_rfu_t::collector_unit_t::allocate( register_set* pipeline_reg_set, register_set* output_reg_set ) @@ -3486,7 +3521,7 @@ bool opndcoll_rfu_t::collector_unit_t::allocate( register_set* pipeline_reg_set, for( unsigned op=0; op < MAX_REG_OPERANDS; op++ ) { int reg_num = (*pipeline_reg)->arch_reg.src[op]; // this math needs to match that used in function_info::ptx_decode_inst if( reg_num >= 0 ) { // valid register - m_src_op[op] = op_t( this, op, reg_num, m_num_banks, m_bank_warp_shift ); + m_src_op[op] = op_t( this, op, reg_num, m_num_banks, m_bank_warp_shift, m_sub_core_model, m_num_banks_per_sched, (*pipeline_reg)->get_schd_id() ); m_not_ready.set(op); } else m_src_op[op] = op_t(); diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 4a87126..e6132f5 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -291,7 +291,7 @@ inline unsigned wid_from_hw_tid(unsigned tid, unsigned warp_size){return tid/war const unsigned WARP_PER_CTA_MAX = 64; typedef std::bitset warp_set_t; -int register_bank(int regnum, int wid, unsigned num_banks, unsigned bank_warp_shift); +int register_bank(int regnum, int wid, unsigned num_banks, unsigned bank_warp_shift, bool sub_core_model, unsigned banks_per_sched, unsigned sched_id ); class shader_core_ctx; struct shader_core_config; @@ -378,6 +378,8 @@ public: // m_supervised_warps with their scheduling policies virtual void order_warps() = 0; + int get_schd_id() const {return m_id;} + protected: virtual void do_on_warp_issued( unsigned warp_id, unsigned num_issued, @@ -601,23 +603,25 @@ private: public: op_t() { m_valid = false; } - op_t( collector_unit_t *cu, unsigned op, unsigned reg, unsigned num_banks, unsigned bank_warp_shift ) + op_t( collector_unit_t *cu, unsigned op, unsigned reg, unsigned num_banks, unsigned bank_warp_shift, bool sub_core_model, unsigned banks_per_sched, unsigned sched_id ) { m_valid = true; m_warp=NULL; m_cu = cu; m_operand = op; m_register = reg; - m_bank = register_bank(reg,cu->get_warp_id(),num_banks,bank_warp_shift); + m_shced_id = sched_id; + m_bank = register_bank(reg,cu->get_warp_id(),num_banks,bank_warp_shift, sub_core_model, banks_per_sched, sched_id); } - op_t( const warp_inst_t *warp, unsigned reg, unsigned num_banks, unsigned bank_warp_shift ) + op_t( const warp_inst_t *warp, unsigned reg, unsigned num_banks, unsigned bank_warp_shift, bool sub_core_model, unsigned banks_per_sched, unsigned sched_id ) { m_valid=true; m_warp=warp; m_register=reg; m_cu=NULL; m_operand = -1; - m_bank = register_bank(reg,warp->warp_id(),num_banks,bank_warp_shift); + m_shced_id = sched_id; + m_bank = register_bank(reg,warp->warp_id(),num_banks,bank_warp_shift, sub_core_model, banks_per_sched, sched_id); } // accessors @@ -633,6 +637,10 @@ private: else if( m_cu ) return m_cu->get_warp_id(); else abort(); } + unsigned get_sid() const + { + return m_shced_id; + } unsigned get_active_count() const { if( m_warp ) return m_warp->active_count(); @@ -677,6 +685,7 @@ private: unsigned m_operand; // operand offset in instruction. e.g., add r1,r2,r3; r2 is oprd 0, r3 is 1 (r1 is dst) unsigned m_register; unsigned m_bank; + unsigned m_shced_id; //scheduler id that has issued this inst }; enum alloc_t { @@ -697,7 +706,7 @@ private: else if( m_allocation == WRITE_ALLOC ) { fprintf(fp,"wr: "); m_op.dump(fp); } fprintf(fp,"\n"); } - void alloc_read( const op_t &op ) { assert(is_free()); m_allocation=READ_ALLOC; m_op=op; } + void alloc_read( const op_t &op ) { assert(is_free()); m_allocation=READ_ALLOC; m_op=op; } void alloc_write( const op_t &op ) { assert(is_free()); m_allocation=WRITE_ALLOC; m_op=op; } void reset() { m_allocation = NO_ALLOC; } private: @@ -851,7 +860,9 @@ private: unsigned num_banks, unsigned log2_warp_size, const core_config *config, - opndcoll_rfu_t *rfu ); + opndcoll_rfu_t *rfu, + bool m_sub_core_model, + unsigned num_banks_per_sched); bool allocate( register_set* pipeline_reg, register_set* output_reg ); void collect_operand( unsigned op ) @@ -879,6 +890,9 @@ private: unsigned m_bank_warp_shift; opndcoll_rfu_t *m_rfu; + unsigned m_num_banks_per_sched; + bool m_sub_core_model; + }; class dispatch_unit_t { @@ -921,6 +935,10 @@ private: std::vector m_cu; arbiter_t m_arbiter; + unsigned m_num_banks_per_sched; + unsigned m_num_warp_sceds; + bool sub_core_model; + //unsigned m_num_ports; //std::vector m_input; //std::vector m_output; @@ -1361,6 +1379,7 @@ struct shader_core_config : public core_config bool gpgpu_dual_issue_diff_exec_units; //op collector + bool enable_specialized_operand_collector; int gpgpu_operand_collector_num_units_sp; int gpgpu_operand_collector_num_units_dp; int gpgpu_operand_collector_num_units_sfu; @@ -1392,6 +1411,7 @@ struct shader_core_config : public core_config bool gpgpu_reg_bank_use_warp_id; bool gpgpu_local_mem_map; bool gpgpu_ignore_resources_limitation; + bool sub_core_model; unsigned max_sp_latency; unsigned max_sfu_latency; @@ -1848,7 +1868,7 @@ public: friend class scheduler_unit; //this is needed to use private issue warp. friend class TwoLevelScheduler; friend class LooseRoundRobbinScheduler; - void issue_warp( register_set& warp, const warp_inst_t *pI, const active_mask_t &active_mask, unsigned warp_id ); + void issue_warp( register_set& warp, const warp_inst_t *pI, const active_mask_t &active_mask, unsigned warp_id, unsigned sch_id ); void func_exec_inst( warp_inst_t &inst ); // Returns numbers of addresses in translated_addrs -- cgit v1.3 From 2823b21ea0b84555c0f0c9b8a6e02614bf80f941 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 5 Nov 2018 20:11:21 -0500 Subject: fixing subcore model bug --- src/abstract_hardware_model.h | 12 ++++++++++-- src/gpgpu-sim/shader.cc | 14 +++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index d0f7066..d123131 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -1166,7 +1166,11 @@ public: } return false; } - bool has_free(unsigned reg_id){ + bool has_free(bool sub_core_model, unsigned reg_id){ + //in subcore model, each sched has a one specific reg to use (based on sched id) + if(!sub_core_model) + return has_free(); + assert(reg_id < regs.size()); return regs[reg_id]->empty(); } @@ -1225,7 +1229,11 @@ public: return NULL; } - warp_inst_t ** get_free(unsigned reg_id){ + warp_inst_t ** get_free(bool sub_core_model, unsigned reg_id){ + //in subcore model, each sched has a one specific reg to use (based on sched id) + if(!sub_core_model) + return get_free(); + assert(reg_id < regs.size()); if( regs[reg_id]->empty() ) { return ®s[reg_id]; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 300871e..c610d49 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -770,11 +770,7 @@ void shader_core_ctx::func_exec_inst( warp_inst_t &inst ) void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t* next_inst, const active_mask_t &active_mask, unsigned warp_id, unsigned sch_id ) { - warp_inst_t** pipe_reg; - if(m_config->sub_core_model) - pipe_reg = pipe_reg_set.get_free(sch_id); - else - pipe_reg = pipe_reg_set.get_free(); + warp_inst_t** pipe_reg = pipe_reg = pipe_reg_set.get_free(m_config->sub_core_model, sch_id); assert(pipe_reg); m_warp[warp_id].ibuffer_free(); @@ -961,7 +957,7 @@ void scheduler_unit::cycle() const active_mask_t &active_mask = m_simt_stack[warp_id]->get_active_mask(); assert( warp(warp_id).inst_in_pipeline() ); if ( (pI->op == LOAD_OP) || (pI->op == STORE_OP) || (pI->op == MEMORY_BARRIER_OP) ) { - if( m_mem_out->has_free(m_id) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::MEM)) { + if( m_mem_out->has_free(m_shader->m_config->sub_core_model, m_id) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::MEM)) { m_shader->issue_warp(*m_mem_out,pI,active_mask,warp_id,m_id); issued++; issued_inst=true; @@ -970,9 +966,9 @@ void scheduler_unit::cycle() } } else { - bool sp_pipe_avail = m_sp_out->has_free(m_id); - bool sfu_pipe_avail = m_sfu_out->has_free(m_id); - bool dp_pipe_avail = m_dp_out->has_free(m_id); + bool sp_pipe_avail = m_sp_out->has_free(m_shader->m_config->sub_core_model, m_id); + bool sfu_pipe_avail = m_sfu_out->has_free(m_shader->m_config->sub_core_model, m_id); + bool dp_pipe_avail = m_dp_out->has_free(m_shader->m_config->sub_core_model, m_id); if( sp_pipe_avail && (pI->op != SFU_OP && pI->op != DP_OP) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::SP)) { //Jin: special for CDP api -- cgit v1.3 From ffee4550d7452af93d3dcd05fc9a105a56b5b077 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Tue, 6 Nov 2018 18:34:36 -0500 Subject: fixing sector atomics --- src/abstract_hardware_model.cc | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index 39ed81c..40f4d00 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -314,7 +314,7 @@ void warp_inst_t::generate_mem_accesses() break; case global_space: case local_space: case param_space_local: - if( m_config->gpgpu_coalesce_arch >= 13 && m_config->gpgpu_coalesce_arch <= 62) { + if( m_config->gpgpu_coalesce_arch >= 13) { if(isatomic()) memory_coalescing_arch_atomic(is_write, access_type); else @@ -369,7 +369,7 @@ void warp_inst_t::memory_coalescing_arch( bool is_write, mem_access_type access_ } else if(m_config->gpgpu_coalesce_arch >= 40) { - //Maxwell and Pascal, L1 and L2 are sectors + //Maxwell, Pascal and Volta, L1 and L2 are sectors //all requests should be 32 bytes sector_segment_size = true; } @@ -440,11 +440,28 @@ void warp_inst_t::memory_coalescing_arch_atomic( bool is_write, mem_access_type // see the CUDA manual where it discusses coalescing rules before reading this unsigned segment_size = 0; - unsigned warp_parts = 2; + unsigned warp_parts = m_config->mem_warp_parts; + bool sector_segment_size = false; + + if(m_config->gpgpu_coalesce_arch >= 20 && m_config->gpgpu_coalesce_arch < 39) + { + //Fermi and Kepler, L1 is normal and L2 is sector + if(m_config->gmem_skip_L1D || cache_op == CACHE_GLOBAL) + sector_segment_size = true; + else + sector_segment_size = false; + } + else if(m_config->gpgpu_coalesce_arch >= 40) + { + //Maxwell, Pascal and Volta, L1 and L2 are sectors + //all requests should be 32 bytes + sector_segment_size = true; + } + switch( data_size ) { case 1: segment_size = 32; break; - case 2: segment_size = 64; break; - case 4: case 8: case 16: segment_size = 128; break; + case 2: segment_size = sector_segment_size? 32 : 64; break; + case 4: case 8: case 16: segment_size = sector_segment_size? 32 : 128; break; } unsigned subwarp_size = m_config->warp_size / warp_parts; -- cgit v1.3 From 7d42f5849aa1abb4f081803843ea78009d5b20ce Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Tue, 6 Nov 2018 19:48:52 -0500 Subject: adding tensor cores config --- configs/tested-cfgs/SM7_TITANV/gpgpusim.config | 5 +++-- src/abstract_hardware_model.h | 4 ++++ src/gpgpu-sim/shader.cc | 11 ++++++++++- src/gpgpu-sim/shader.h | 4 ---- 4 files changed, 17 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config index 5ac734d..7b0369a 100644 --- a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config +++ b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config @@ -12,7 +12,6 @@ -gpgpu_ptx_instruction_classification 0 -gpgpu_ptx_sim_mode 0 -gpgpu_ptx_force_max_capability 70 --gpgpu_tensor_core_avail 1 # SASS execution (only supported with CUDA >= 4.0) -gpgpu_ptx_convert_to_ptxplus 0 @@ -45,10 +44,12 @@ # ID_OC_SP,ID_OC_DP,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_SFU,OC_EX_MEM,EX_WB,ID_OC_TENSOR_CORE,OC_EX_TENSOR_CORE ## Volta GV100 has 4 SP SIMD units, 4 SFU units, 4 DP units per core ## we need to scale the number of pipeline registers to be equal to the number of SP units --gpgpu_pipeline_widths 4,4,4,4,4,4,4,4,8,1,1 +-gpgpu_pipeline_widths 4,4,4,4,4,4,4,4,8,4,4 -gpgpu_num_sp_units 4 -gpgpu_num_sfu_units 4 -gpgpu_num_dp_units 4 +-gpgpu_tensor_core_avail 1 +-gpgpu_num_tensor_core_units 4 # Instruction latencies and initiation intervals # "ADD,MAX,MUL,MAD,DIV" diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 5543a71..edd48a1 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -1269,6 +1269,10 @@ public: return NULL; } + unsigned get_size(){ + return regs.size(); + } + private: std::vector regs; const char* m_name; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 78facbd..c52ba35 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -90,6 +90,15 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, for (int j = 0; jpipe_widths[j],pipeline_stage_name_decode[j])); } + if(m_config->sub_core_model) { + //in subcore model, each scheduler should has its own issue register, so num scheduler = reg width + assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_SP].get_size() ); + if(m_config->gpgpu_num_dp_units > 0) + assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_DP].get_size() ); + assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_SFU].get_size() ); + assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_MEM].get_size() ); + assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_TENSOR_CORE].get_size() ); + } m_threadState = (thread_ctx_t*) calloc(sizeof(thread_ctx_t), config->n_thread_per_shader); @@ -1045,7 +1054,7 @@ void scheduler_unit::cycle() } else if ( (pI->op == TENSOR_CORE_OP) ) { if( tensor_core_pipe_avail ) { - m_shader->issue_warp(*m_tensor_core_out,pI,active_mask,warp_id); + m_shader->issue_warp(*m_tensor_core_out,pI,active_mask,warp_id,m_id); issued++; issued_inst=true; warp_inst_issued = true; diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index fcd134d..7b33c14 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1378,10 +1378,6 @@ struct shader_core_config : public core_config max_sp_latency = 32; max_tensor_core_latency = 64; - gpgpu_num_tensor_core_units=4;//It will be (#TENSORCORE INSIDE SM)/2 (One warp is allocated to 2 Tensor Core) - gpgpu_operand_collector_num_units_tensor_core=24; - gpgpu_operand_collector_num_in_ports_tensor_core=8; - gpgpu_operand_collector_num_out_ports_tensor_core=8; m_L1I_config.init(m_L1I_config.m_config_string,FuncCachePreferNone); m_L1T_config.init(m_L1T_config.m_config_string,FuncCachePreferNone); -- cgit v1.3 From 111cca2a061fe4f247be930cb44fdcdaec2b59f5 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 7 Nov 2018 20:30:02 -0500 Subject: Adding INT unit, fixing tensor core latency, updating config files --- configs/tested-cfgs/SM2_GTX480/gpgpusim.config | 7 +- configs/tested-cfgs/SM6_TITANX/gpgpusim.config | 7 +- configs/tested-cfgs/SM7_TITANV/gpgpusim.config | 8 +- src/abstract_hardware_model.h | 3 + src/cuda-sim/cuda-sim.cc | 35 ++++-- src/gpgpu-sim/gpu-sim.cc | 16 ++- src/gpgpu-sim/shader.cc | 165 +++++++++++++++++++------ src/gpgpu-sim/shader.h | 57 +++++++-- 8 files changed, 232 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/configs/tested-cfgs/SM2_GTX480/gpgpusim.config b/configs/tested-cfgs/SM2_GTX480/gpgpusim.config index 4096b09..d71b2fd 100644 --- a/configs/tested-cfgs/SM2_GTX480/gpgpusim.config +++ b/configs/tested-cfgs/SM2_GTX480/gpgpusim.config @@ -30,9 +30,10 @@ -gpgpu_simd_model 1 # Pipeline widths and number of FUs -# ID_OC_SP,ID_OC_DP,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_SFU,OC_EX_MEM,EX_WB -#For Fermi, DP unit =0, DP inst is executed on SFU --gpgpu_pipeline_widths 2,0,1,1,2,0,1,1,2 +# ID_OC_SP,ID_OC_DP,ID_OC_INT,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_INT,OC_EX_SFU,OC_EX_MEM,EX_WB +# For Fermi, DP unit =0, DP inst is executed on SFU +# For Fermi, INT unit =0, INT inst is executed on SP +-gpgpu_pipeline_widths 2,0,0,1,1,2,0,0,1,1,2 -gpgpu_num_sp_units 2 -gpgpu_num_sfu_units 1 -gpgpu_num_dp_units 0 diff --git a/configs/tested-cfgs/SM6_TITANX/gpgpusim.config b/configs/tested-cfgs/SM6_TITANX/gpgpusim.config index ed35531..cb23ab3 100644 --- a/configs/tested-cfgs/SM6_TITANX/gpgpusim.config +++ b/configs/tested-cfgs/SM6_TITANX/gpgpusim.config @@ -35,10 +35,11 @@ -gpgpu_simd_model 1 # Pipeline widths and number of FUs -# ID_OC_SP,ID_OC_DP,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_SFU,OC_EX_MEM,EX_WB -## Pascal GP102 has 4 SP SIMD units and 4 SFU units +# ID_OC_SP,ID_OC_DP,ID_OC_INT,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_INT,OC_EX_SFU,OC_EX_MEM,EX_WB +## Pascal GP102 has 4 SP SIMD units and 4 SFU units per SM. In this config, we split SM into two shader cores, each has 2 SPs and 2 SFUs +# There is no int unit in Pascal ## we need to scale the number of pipeline registers to be equal to the number of SP units --gpgpu_pipeline_widths 2,1,2,1,2,1,2,1,5 +-gpgpu_pipeline_widths 2,1,0,2,1,2,1,0,2,1,5 -gpgpu_num_sp_units 2 -gpgpu_num_sfu_units 2 -gpgpu_num_dp_units 1 diff --git a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config index 7b0369a..e143f31 100644 --- a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config +++ b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config @@ -41,13 +41,14 @@ -gpgpu_simd_model 1 # Pipeline widths and number of FUs -# ID_OC_SP,ID_OC_DP,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_SFU,OC_EX_MEM,EX_WB,ID_OC_TENSOR_CORE,OC_EX_TENSOR_CORE +# ID_OC_SP,ID_OC_DP,ID_OC_INT,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_INT,OC_EX_SFU,OC_EX_MEM,EX_WB,ID_OC_TENSOR_CORE,OC_EX_TENSOR_CORE ## Volta GV100 has 4 SP SIMD units, 4 SFU units, 4 DP units per core ## we need to scale the number of pipeline registers to be equal to the number of SP units --gpgpu_pipeline_widths 4,4,4,4,4,4,4,4,8,4,4 +-gpgpu_pipeline_widths 4,4,4,4,4,4,4,4,4,4,8,4,4 -gpgpu_num_sp_units 4 -gpgpu_num_sfu_units 4 -gpgpu_num_dp_units 4 +-gpgpu_num_int_units 4 -gpgpu_tensor_core_avail 1 -gpgpu_num_tensor_core_units 4 @@ -64,7 +65,8 @@ -ptx_opcode_initiation_dp 4,4,4,4,130 -ptx_opcode_latency_sfu 100 -ptx_opcode_initiation_sfu 8 - +-ptx_opcode_latency_tesnor 64 +-ptx_opcode_initiation_tensor 64 # ::,::::,::,:** # ** Optional parameter - Required when mshr_type==Texture Fifo diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index edd48a1..b65df81 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -83,6 +83,8 @@ enum uarch_op_t { SFU_OP, TENSOR_CORE_OP, DP_OP, + SP_OP, + INTP_OP, ALU_SFU_OP, LOAD_OP, TENSOR_CORE_LOAD_OP, @@ -141,6 +143,7 @@ enum operation_pipeline_t { UNKOWN_OP, SP__OP, DP__OP, + INTP__OP, SFU__OP, TENSOR_CORE__OP, MEM__OP diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index c9ac8cb..7dc20cd 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -62,8 +62,8 @@ addr_t g_debug_pc = 0xBEEF1518; unsigned g_ptx_sim_num_insn = 0; unsigned gpgpu_param_num_shaders = 0; -char *opcode_latency_int, *opcode_latency_fp, *opcode_latency_dp,*opcode_latency_sfu; -char *opcode_initiation_int, *opcode_initiation_fp, *opcode_initiation_dp,*opcode_initiation_sfu; +char *opcode_latency_int, *opcode_latency_fp, *opcode_latency_dp,*opcode_latency_sfu,*opcode_latency_tensor; +char *opcode_initiation_int, *opcode_initiation_fp, *opcode_initiation_dp,*opcode_initiation_sfu,*opcode_initiation_tensor; char *cdp_latency_str; unsigned cdp_latency[5]; @@ -84,6 +84,10 @@ void ptx_opcocde_latency_options (option_parser_t opp) { "Opcode latencies for SFU instructions" "Default 8", "8"); + option_parser_register(opp, "-ptx_opcode_latency_tesnor", OPT_CSTR, &opcode_latency_tensor, + "Opcode latencies for Tensor instructions" + "Default 64", + "64"); option_parser_register(opp, "-ptx_opcode_initiation_int", OPT_CSTR, &opcode_initiation_int, "Opcode initiation intervals for integers " "Default 1,1,4,4,32", @@ -100,6 +104,10 @@ void ptx_opcocde_latency_options (option_parser_t opp) { "Opcode initiation intervals for sfu instructions" "Default 8", "8"); + option_parser_register(opp, "-ptx_opcode_initiation_tensor", OPT_CSTR, &opcode_initiation_tensor, + "Opcode initiation intervals for tensor instructions" + "Default 64", + "64"); option_parser_register(opp, "-cdp_latency", OPT_CSTR, &cdp_latency_str, "CDP API latency sub_core_model) { //in subcore model, each scheduler should has its own issue register, so num scheduler = reg width assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_SP].get_size() ); - if(m_config->gpgpu_num_dp_units > 0) - assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_DP].get_size() ); assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_SFU].get_size() ); assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_MEM].get_size() ); - assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_TENSOR_CORE].get_size() ); + if(m_config->gpgpu_tensor_core_avail) + assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_TENSOR_CORE].get_size() ); + if(m_config->gpgpu_num_dp_units > 0) + assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_DP].get_size() ); + if(m_config->gpgpu_num_int_units > 0) + assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_INT].get_size() ); } m_threadState = (thread_ctx_t*) calloc(sizeof(thread_ctx_t), config->n_thread_per_shader); @@ -161,6 +164,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_DP], &m_pipeline_reg[ID_OC_SFU], + &m_pipeline_reg[ID_OC_INT], &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i @@ -177,6 +181,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_DP], &m_pipeline_reg[ID_OC_SFU], + &m_pipeline_reg[ID_OC_INT], &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i, @@ -194,6 +199,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_DP], &m_pipeline_reg[ID_OC_SFU], + &m_pipeline_reg[ID_OC_INT], &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i @@ -210,7 +216,8 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_DP], &m_pipeline_reg[ID_OC_SFU], - &m_pipeline_reg[ID_OC_TENSOR_CORE], + &m_pipeline_reg[ID_OC_INT], + &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i ) @@ -226,6 +233,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_DP], &m_pipeline_reg[ID_OC_SFU], + &m_pipeline_reg[ID_OC_INT], &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i, @@ -248,7 +256,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, //op collector configuration - enum { SP_CUS, DP_CUS, SFU_CUS, TENSOR_CORE_CUS, MEM_CUS, GEN_CUS }; + enum { SP_CUS, DP_CUS, SFU_CUS, TENSOR_CORE_CUS, INT_CUS, MEM_CUS, GEN_CUS }; opndcoll_rfu_t::port_vector_t in_ports; opndcoll_rfu_t::port_vector_t out_ports; @@ -260,16 +268,22 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_gen; i++) { in_ports.push_back(&m_pipeline_reg[ID_OC_SP]); in_ports.push_back(&m_pipeline_reg[ID_OC_SFU]); - in_ports.push_back(&m_pipeline_reg[ID_OC_TENSOR_CORE]); in_ports.push_back(&m_pipeline_reg[ID_OC_MEM]); out_ports.push_back(&m_pipeline_reg[OC_EX_SP]); out_ports.push_back(&m_pipeline_reg[OC_EX_SFU]); - out_ports.push_back(&m_pipeline_reg[OC_EX_TENSOR_CORE]); out_ports.push_back(&m_pipeline_reg[OC_EX_MEM]); + if(m_config->gpgpu_tensor_core_avail) { + in_ports.push_back(&m_pipeline_reg[ID_OC_TENSOR_CORE]); + out_ports.push_back(&m_pipeline_reg[OC_EX_TENSOR_CORE]); + } if(m_config->gpgpu_num_dp_units > 0) { in_ports.push_back(&m_pipeline_reg[ID_OC_DP]); out_ports.push_back(&m_pipeline_reg[OC_EX_DP]); } + if(m_config->gpgpu_num_int_units > 0) { + in_ports.push_back(&m_pipeline_reg[ID_OC_INT]); + out_ports.push_back(&m_pipeline_reg[OC_EX_INT]); + } cu_sets.push_back((unsigned)GEN_CUS); m_operand_collector.add_port(in_ports,out_ports,cu_sets); in_ports.clear(),out_ports.clear(),cu_sets.clear(); @@ -281,6 +295,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_operand_collector.add_cu_set(TENSOR_CORE_CUS, config->gpgpu_operand_collector_num_units_tensor_core, config->gpgpu_operand_collector_num_out_ports_tensor_core); m_operand_collector.add_cu_set(SFU_CUS, m_config->gpgpu_operand_collector_num_units_sfu, m_config->gpgpu_operand_collector_num_out_ports_sfu); m_operand_collector.add_cu_set(MEM_CUS, m_config->gpgpu_operand_collector_num_units_mem, m_config->gpgpu_operand_collector_num_out_ports_mem); + m_operand_collector.add_cu_set(INT_CUS, m_config->gpgpu_operand_collector_num_units_int, m_config->gpgpu_operand_collector_num_out_ports_int); for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_sp; i++) { in_ports.push_back(&m_pipeline_reg[ID_OC_SP]); @@ -326,11 +341,20 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_operand_collector.add_port(in_ports,out_ports,cu_sets); in_ports.clear(),out_ports.clear(),cu_sets.clear(); } + + for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_int; i++) { + in_ports.push_back(&m_pipeline_reg[ID_OC_INT]); + out_ports.push_back(&m_pipeline_reg[OC_EX_INT]); + cu_sets.push_back((unsigned)INT_CUS); + cu_sets.push_back((unsigned)GEN_CUS); + m_operand_collector.add_port(in_ports,out_ports,cu_sets); + in_ports.clear(),out_ports.clear(),cu_sets.clear(); + } } m_operand_collector.init( m_config->gpgpu_num_reg_banks, this ); - m_num_function_units = m_config->gpgpu_num_sp_units + m_config->gpgpu_num_dp_units + m_config->gpgpu_num_sfu_units + m_config->gpgpu_num_tensor_core_units + 1; // sp_unit, sfu, ldst_unit + m_num_function_units = m_config->gpgpu_num_sp_units + m_config->gpgpu_num_dp_units + m_config->gpgpu_num_sfu_units + m_config->gpgpu_num_tensor_core_units + m_config->gpgpu_num_int_units + 1; // sp_unit, sfu, dp, tensor, int, ldst_unit //m_dispatch_port = new enum pipeline_stage_name_t[ m_num_function_units ]; //m_issue_port = new enum pipeline_stage_name_t[ m_num_function_units ]; @@ -347,6 +371,11 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_dispatch_port.push_back(ID_OC_DP); m_issue_port.push_back(OC_EX_DP); } + for (int k = 0; k < m_config->gpgpu_num_int_units; k++) { + m_fu.push_back(new int_unit( &m_pipeline_reg[EX_WB], m_config, this )); + m_dispatch_port.push_back(ID_OC_INT); + m_issue_port.push_back(OC_EX_INT); + } for (int k = 0; k < m_config->gpgpu_num_sfu_units; k++) { m_fu.push_back(new sfu( &m_pipeline_reg[EX_WB], m_config, this )); @@ -359,6 +388,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_dispatch_port.push_back(ID_OC_TENSOR_CORE); m_issue_port.push_back(OC_EX_TENSOR_CORE); } + m_ldst_unit = new ldst_unit( m_icnt, m_mem_fetch_allocator, this, &m_operand_collector, m_scoreboard, config, mem_config, stats, shader_id, tpc_id ); m_fu.push_back(m_ldst_unit); m_dispatch_port.push_back(ID_OC_MEM); @@ -958,8 +988,8 @@ void scheduler_unit::cycle() unsigned checked=0; unsigned issued=0; exec_unit_type_t previous_issued_inst_exec_type = exec_unit_type_t::NONE; - unsigned max_issue = m_shader->m_config->gpgpu_max_insn_issue_per_warp; - bool diff_exec_units = m_shader->m_config->gpgpu_dual_issue_diff_exec_units; + unsigned max_issue = m_shader->m_config->gpgpu_max_insn_issue_per_warp; + bool diff_exec_units = m_shader->m_config->gpgpu_dual_issue_diff_exec_units; //In tis mode, we only allow dual issue to diff execution units (as in Maxwell and Pascal) while( !warp(warp_id).waiting() && !warp(warp_id).ibuffer_empty() && (checked < max_issue) && (checked <= issued) && (issued < max_issue) ) { const warp_inst_t *pI = warp(warp_id).ibuffer_next_inst(); @@ -1008,33 +1038,62 @@ void scheduler_unit::cycle() bool sfu_pipe_avail = m_sfu_out->has_free(m_shader->m_config->sub_core_model, m_id); bool tensor_core_pipe_avail = m_tensor_core_out->has_free(m_shader->m_config->sub_core_model, m_id); bool dp_pipe_avail = m_dp_out->has_free(m_shader->m_config->sub_core_model, m_id); - if( sp_pipe_avail && (pI->op != TENSOR_CORE_OP) && (pI->op != SFU_OP && pI->op != DP_OP) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::SP)) { - - //Jin: special for CDP api - if(pI->m_is_cdp && !warp(warp_id).m_cdp_dummy) { - assert(warp(warp_id).m_cdp_latency == 0); - - extern unsigned cdp_latency[5]; - if(pI->m_is_cdp == 1) - warp(warp_id).m_cdp_latency = cdp_latency[pI->m_is_cdp - 1]; - else //cudaLaunchDeviceV2 and cudaGetParameterBufferV2 - warp(warp_id).m_cdp_latency = cdp_latency[pI->m_is_cdp - 1] - + cdp_latency[pI->m_is_cdp] * active_mask.count(); - warp(warp_id).m_cdp_dummy = true; - break; - } - else if(pI->m_is_cdp && warp(warp_id).m_cdp_dummy) { - assert(warp(warp_id).m_cdp_latency == 0); - warp(warp_id).m_cdp_dummy = false; - } + bool int_pipe_avail = m_int_out->has_free(m_shader->m_config->sub_core_model, m_id); - // always prefer SP pipe for operations that can use both SP and SFU pipelines - m_shader->issue_warp(*m_sp_out,pI,active_mask,warp_id,m_id); - issued++; - issued_inst=true; - warp_inst_issued = true; - previous_issued_inst_exec_type = exec_unit_type_t::SP; - } else if ( (m_shader->m_config->gpgpu_num_dp_units != 0) && (pI->op == DP_OP) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::DP)) { + //This code need to be refactored + if(pI->op != TENSOR_CORE_OP && pI->op != SFU_OP && pI->op != DP_OP) { + + bool execute_on_SP = false; + bool execute_on_INT = false; + + //if INT unit pipline exist, then execute ALU and INT operations on INT unit and SP-FPU on SP unit (like in Volta) + //if INT unit pipline does not exist, then execute all ALU, INT and SP operations on SP unit (as in Fermi, Pascal GPUs) + if(m_shader->m_config->gpgpu_num_int_units > 0 && + int_pipe_avail && + pI->op != SP_OP && + !(diff_exec_units && previous_issued_inst_exec_type == exec_unit_type_t::INT)) + execute_on_INT = true; + else if (sp_pipe_avail && + (m_shader->m_config->gpgpu_num_int_units == 0 || + (m_shader->m_config->gpgpu_num_int_units > 0 && pI->op == SP_OP)) && + !(diff_exec_units && previous_issued_inst_exec_type == exec_unit_type_t::SP) ) + execute_on_SP = true; + + + if(execute_on_INT || execute_on_SP) { + //Jin: special for CDP api + if(pI->m_is_cdp && !warp(warp_id).m_cdp_dummy) { + assert(warp(warp_id).m_cdp_latency == 0); + + extern unsigned cdp_latency[5]; + if(pI->m_is_cdp == 1) + warp(warp_id).m_cdp_latency = cdp_latency[pI->m_is_cdp - 1]; + else //cudaLaunchDeviceV2 and cudaGetParameterBufferV2 + warp(warp_id).m_cdp_latency = cdp_latency[pI->m_is_cdp - 1] + + cdp_latency[pI->m_is_cdp] * active_mask.count(); + warp(warp_id).m_cdp_dummy = true; + break; + } + else if(pI->m_is_cdp && warp(warp_id).m_cdp_dummy) { + assert(warp(warp_id).m_cdp_latency == 0); + warp(warp_id).m_cdp_dummy = false; + } + } + + if(execute_on_SP) { + m_shader->issue_warp(*m_sp_out,pI,active_mask,warp_id,m_id); + issued++; + issued_inst=true; + warp_inst_issued = true; + previous_issued_inst_exec_type = exec_unit_type_t::SP; + } else if (execute_on_INT) { + m_shader->issue_warp(*m_int_out,pI,active_mask,warp_id,m_id); + issued++; + issued_inst=true; + warp_inst_issued = true; + previous_issued_inst_exec_type = exec_unit_type_t::INT; + } + } else if ( (m_shader->m_config->gpgpu_num_dp_units > 0) && (pI->op == DP_OP) && !(diff_exec_units && previous_issued_inst_exec_type == exec_unit_type_t::DP)) { if( dp_pipe_avail ) { m_shader->issue_warp(*m_dp_out,pI,active_mask,warp_id,m_id); issued++; @@ -1042,8 +1101,8 @@ void scheduler_unit::cycle() warp_inst_issued = true; previous_issued_inst_exec_type = exec_unit_type_t::DP; } - } //If the DP units = 0 (like in Fermi archi), then change DP inst to SFU inst - else if ( ((m_shader->m_config->gpgpu_num_dp_units == 0 && pI->op == DP_OP) || (pI->op == SFU_OP) || (pI->op == ALU_SFU_OP)) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::SFU)) { + } //If the DP units = 0 (like in Fermi archi), then execute DP inst on SFU unit + else if ( ((m_shader->m_config->gpgpu_num_dp_units == 0 && pI->op == DP_OP) || (pI->op == SFU_OP) || (pI->op == ALU_SFU_OP)) && !(diff_exec_units && previous_issued_inst_exec_type == exec_unit_type_t::SFU)) { if( sfu_pipe_avail ) { m_shader->issue_warp(*m_sfu_out,pI,active_mask,warp_id,m_id); issued++; @@ -1052,12 +1111,13 @@ void scheduler_unit::cycle() previous_issued_inst_exec_type = exec_unit_type_t::SFU; } } - else if ( (pI->op == TENSOR_CORE_OP) ) { + else if ( (pI->op == TENSOR_CORE_OP) && !(diff_exec_units && previous_issued_inst_exec_type == exec_unit_type_t::SP) ) { if( tensor_core_pipe_avail ) { m_shader->issue_warp(*m_tensor_core_out,pI,active_mask,warp_id,m_id); issued++; issued_inst=true; warp_inst_issued = true; + previous_issued_inst_exec_type = exec_unit_type_t::TENSOR; } } }//end of else @@ -1245,11 +1305,12 @@ swl_scheduler::swl_scheduler ( shader_core_stats* stats, shader_core_ctx* shader register_set* sp_out, register_set* dp_out, register_set* sfu_out, + register_set* int_out, register_set* tensor_core_out, register_set* mem_out, int id, char* config_string ) - : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, dp_out, sfu_out,tensor_core_out, mem_out, id ) + : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, dp_out, sfu_out, int_out, tensor_core_out, mem_out, id ) { unsigned m_prioritization_readin; int ret = sscanf( config_string, @@ -1822,6 +1883,7 @@ void ldst_unit::active_lanes_in_pipeline(){ assert(active_count<=m_core->get_config()->warp_size); m_core->incfumemactivelanes_stat(active_count); } + void sp_unit::active_lanes_in_pipeline(){ unsigned active_count=pipelined_simd_unit::get_active_lanes_in_pipeline(); assert(active_count<=m_core->get_config()->warp_size); @@ -1837,6 +1899,13 @@ void dp_unit::active_lanes_in_pipeline(){ m_core->incfumemactivelanes_stat(active_count); } +void int_unit::active_lanes_in_pipeline(){ + unsigned active_count=pipelined_simd_unit::get_active_lanes_in_pipeline(); + assert(active_count<=m_core->get_config()->warp_size); + m_core->incspactivelanes_stat(active_count); + m_core->incfuactivelanes_stat(active_count); + m_core->incfumemactivelanes_stat(active_count); +} void sfu::active_lanes_in_pipeline(){ unsigned active_count=pipelined_simd_unit::get_active_lanes_in_pipeline(); assert(active_count<=m_core->get_config()->warp_size); @@ -1866,6 +1935,12 @@ dp_unit::dp_unit( register_set* result_port, const shader_core_config *config,sh m_name = "DP "; } +int_unit::int_unit( register_set* result_port, const shader_core_config *config,shader_core_ctx *core) + : pipelined_simd_unit(result_port,config,config->max_sp_latency,core) +{ + m_name = "INT "; +} + void sp_unit :: issue(register_set& source_reg) { warp_inst_t** ready_reg = source_reg.get_ready(); @@ -1884,6 +1959,15 @@ void dp_unit :: issue(register_set& source_reg) pipelined_simd_unit::issue(source_reg); } +void int_unit :: issue(register_set& source_reg) +{ + warp_inst_t** ready_reg = source_reg.get_ready(); + //m_core->incexecstat((*ready_reg)); + (*ready_reg)->op_pipe=INTP__OP; + m_core->incsp_stat(m_core->get_config()->warp_size,(*ready_reg)->latency); + pipelined_simd_unit::issue(source_reg); +} + pipelined_simd_unit::pipelined_simd_unit( register_set* result_port, const shader_core_config *config, unsigned max_latency,shader_core_ctx *core ) : simd_function_unit(config) { @@ -2006,6 +2090,7 @@ ldst_unit::ldst_unit( mem_fetch_interface *icnt, l1_latency_queue.push_back((mem_fetch*)NULL); } } + m_name = "MEM "; } ldst_unit::ldst_unit( mem_fetch_interface *icnt, diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 7b33c14..45cf8e4 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -76,7 +76,9 @@ enum exec_unit_type_t SP = 1, SFU = 2, MEM = 3, - DP = 4 + DP = 4, + INT = 5, + TENSOR = 6 }; class thread_ctx_t { @@ -328,12 +330,13 @@ public: register_set* sp_out, register_set* dp_out, register_set* sfu_out, + register_set* int_out, register_set* tensor_core_out, register_set* mem_out, int id) : m_supervised_warps(), m_stats(stats), m_shader(shader), m_scoreboard(scoreboard), m_simt_stack(simt), /*m_pipeline_reg(pipe_regs),*/ m_warp(warp), - m_sp_out(sp_out),m_dp_out(dp_out),m_sfu_out(sfu_out),m_tensor_core_out(tensor_core_out),m_mem_out(mem_out), m_id(id){} + m_sp_out(sp_out),m_dp_out(dp_out),m_sfu_out(sfu_out),m_int_out(int_out),m_tensor_core_out(tensor_core_out),m_mem_out(mem_out), m_id(id){} virtual ~scheduler_unit(){} virtual void add_supervised_warp_id(int i) { m_supervised_warps.push_back(&warp(i)); @@ -409,6 +412,7 @@ protected: register_set* m_sp_out; register_set* m_dp_out; register_set* m_sfu_out; + register_set* m_int_out; register_set* m_tensor_core_out; register_set* m_mem_out; @@ -423,10 +427,11 @@ public: register_set* sp_out, register_set* dp_out, register_set* sfu_out, + register_set* int_out, register_set* tensor_core_out, register_set* mem_out, int id ) - : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, dp_out, sfu_out,tensor_core_out, mem_out, id ){} + : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, dp_out, sfu_out, int_out, tensor_core_out, mem_out, id ){} virtual ~lrr_scheduler () {} virtual void order_warps (); virtual void done_adding_supervised_warps() { @@ -442,10 +447,11 @@ public: register_set* sp_out, register_set* dp_out, register_set* sfu_out, + register_set* int_out, register_set* tensor_core_out, register_set* mem_out, int id ) - : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, dp_out, sfu_out,tensor_core_out, mem_out, id ){} + : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, dp_out, sfu_out, int_out, tensor_core_out, mem_out, id ){} virtual ~gto_scheduler () {} virtual void order_warps (); virtual void done_adding_supervised_warps() { @@ -462,10 +468,11 @@ public: register_set* sp_out, register_set* dp_out, register_set* sfu_out, - register_set* tensor_core_out, + register_set* int_out, + register_set* tensor_core_out, register_set* mem_out, int id ) - : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, dp_out, sfu_out,tensor_core_out, mem_out, id ){} + : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, dp_out, sfu_out, int_out, tensor_core_out, mem_out, id ){} virtual ~oldest_scheduler () {} virtual void order_warps (); virtual void done_adding_supervised_warps() { @@ -482,11 +489,12 @@ public: register_set* sp_out, register_set* dp_out, register_set* sfu_out, + register_set* int_out, register_set* tensor_core_out, register_set* mem_out, int id, char* config_str ) - : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, dp_out, sfu_out,tensor_core_out, mem_out, id ), + : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, dp_out, sfu_out, int_out, tensor_core_out, mem_out, id ), m_pending_warps() { unsigned inner_level_readin; @@ -534,6 +542,7 @@ public: register_set* sp_out, register_set* dp_out, register_set* sfu_out, + register_set* int_out, register_set* tensor_core_out, register_set* mem_out, int id, @@ -1046,6 +1055,9 @@ public: fprintf(fp,"%s dispatch= ", m_name.c_str() ); m_dispatch_reg->print(fp); } + const char* get_name() { + return m_name.c_str(); + } protected: std::string m_name; const shader_core_config *m_config; @@ -1154,6 +1166,29 @@ public: }; +class int_unit : public pipelined_simd_unit +{ +public: + int_unit( register_set* result_port, const shader_core_config *config, shader_core_ctx *core ); + virtual bool can_issue( const warp_inst_t &inst ) const + { + switch(inst.op) { + case SFU_OP: return false; + case LOAD_OP: return false; + case TENSOR_CORE_LOAD_OP: return false; + case STORE_OP: return false; + case TENSOR_CORE_STORE_OP: return false; + case MEMORY_BARRIER_OP: return false; + case SP_OP: return false; + case DP_OP: return false; + default: break; + } + return pipelined_simd_unit::can_issue(inst); + } + virtual void active_lanes_in_pipeline(); + virtual void issue( register_set& source_reg ); +}; + class sp_unit : public pipelined_simd_unit { public: @@ -1303,10 +1338,12 @@ protected: enum pipeline_stage_name_t { ID_OC_SP=0, ID_OC_DP, + ID_OC_INT, ID_OC_SFU, ID_OC_MEM, OC_EX_SP, OC_EX_DP, + OC_EX_INT, OC_EX_SFU, OC_EX_MEM, EX_WB, @@ -1318,10 +1355,12 @@ enum pipeline_stage_name_t { const char* const pipeline_stage_name_decode[] = { "ID_OC_SP", "ID_OC_DP", + "ID_OC_INT", "ID_OC_SFU", "ID_OC_MEM", "OC_EX_SP", "OC_EX_DP", + "OC_EX_INT", "OC_EX_SFU", "OC_EX_MEM", "EX_WB", @@ -1429,6 +1468,7 @@ struct shader_core_config : public core_config int gpgpu_operand_collector_num_units_tensor_core; int gpgpu_operand_collector_num_units_mem; int gpgpu_operand_collector_num_units_gen; + int gpgpu_operand_collector_num_units_int; unsigned int gpgpu_operand_collector_num_in_ports_sp; unsigned int gpgpu_operand_collector_num_in_ports_dp; @@ -1436,6 +1476,7 @@ struct shader_core_config : public core_config unsigned int gpgpu_operand_collector_num_in_ports_tensor_core; unsigned int gpgpu_operand_collector_num_in_ports_mem; unsigned int gpgpu_operand_collector_num_in_ports_gen; + unsigned int gpgpu_operand_collector_num_in_ports_int; unsigned int gpgpu_operand_collector_num_out_ports_sp; unsigned int gpgpu_operand_collector_num_out_ports_dp; @@ -1443,6 +1484,7 @@ struct shader_core_config : public core_config unsigned int gpgpu_operand_collector_num_out_ports_tensor_core; unsigned int gpgpu_operand_collector_num_out_ports_mem; unsigned int gpgpu_operand_collector_num_out_ports_gen; + unsigned int gpgpu_operand_collector_num_out_ports_int; int gpgpu_num_sp_units; int gpgpu_tensor_core_avail; @@ -1450,6 +1492,7 @@ struct shader_core_config : public core_config int gpgpu_num_sfu_units; int gpgpu_num_tensor_core_units; int gpgpu_num_mem_units; + int gpgpu_num_int_units; //Shader core resources unsigned gpgpu_shader_registers; -- cgit v1.3