From 9e11b2c619e1c55a680f933be2be39ff1a5b381c Mon Sep 17 00:00:00 2001 From: aturner Date: Tue, 1 Feb 2011 17:46:10 -0800 Subject: Added configurable schedulers! [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 8472] --- src/gpgpu-sim/gpu-sim.cc | 3 +++ src/gpgpu-sim/shader.cc | 63 +++++++++++++++++++++++++++++++++--------------- src/gpgpu-sim/shader.h | 49 +++++++++++++++++++++++++++++++++++-- 3 files changed, 93 insertions(+), 22 deletions(-) diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index d90d174..da8f508 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -267,6 +267,9 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_coalesce_arch", OPT_INT32, &gpgpu_coalesce_arch, "Coalescing arch (default = 13, anything else is off for now)", "13"); + option_parser_register(opp, "-gpgpu_num_sched_per_core", OPT_INT32, &gpgpu_num_sched_per_core, + "Number of warp schedulers per core", + "1"); } void gpgpu_sim_config::reg_options(option_parser_t opp) diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 1f7ecb6..608b29c 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -143,7 +143,6 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, // fetch m_last_warp_fetched = 0; - m_last_warp_issued = 0; #define STRSIZE 1024 char name[STRSIZE]; @@ -156,6 +155,18 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_simt_stack[i] = new simt_stack(i,this); m_scoreboard = new Scoreboard(m_sid, m_config->max_warps_per_shader); + //scedulers + //must currently occur after all inputs have been initialized. + for (int i = 0; i < m_config->gpgpu_num_sched_per_core; i++) { + schedulers.push_back(scheduler_unit(m_stats,this,m_scoreboard,m_simt_stack,&m_warp, + &m_pipeline_reg[ID_OC_SP], + &m_pipeline_reg[ID_OC_SFU], + &m_pipeline_reg[ID_OC_MEM])); + } + for (unsigned i = 0; i < m_warp.size(); i++) { + //distribute i's evenly though schedulers; + schedulers[i%m_config->gpgpu_num_sched_per_core].add_supervised_warp_id(i); + } //op collector configuration enum { SP_CUS, SFU_CUS, MEM_CUS, GEN_CUS }; @@ -683,50 +694,62 @@ void shader_core_ctx::issue_warp( warp_inst_t *&pipe_reg, const warp_inst_t *nex m_warp[warp_id].set_next_pc(next_inst->pc + next_inst->isize); } -void shader_core_ctx::decode() +void shader_core_ctx::decode(){ + //really is issue; + for (unsigned i = 0; i < schedulers.size(); i++) { + schedulers[i].cycle(); + } +} + +shd_warp_t& scheduler_unit::warp(int i){ + return (*m_warp)[i]; +} + +void scheduler_unit::cycle() { bool valid_inst = false; // there was one warp with a valid instruction to issue (didn't require flush due to control hazard) bool ready_inst = false; // of the valid instructions, there was one not waiting for pending register writes bool issued_inst = false; // of these we issued one - for ( unsigned i=0; i < m_config->max_warps_per_shader; i++ ) { - unsigned warp_id = (m_last_warp_issued+1+i) % m_config->max_warps_per_shader; + for ( unsigned i=0; i < supervised_warps.size(); i++ ) { + unsigned supervised_id = (m_last_sup_id_issued+1+i) % supervised_warps.size(); + unsigned warp_id = supervised_warps[supervised_id]; unsigned checked=0; unsigned issued=0; - while( !m_warp[warp_id].waiting() && !m_warp[warp_id].ibuffer_empty() && (checked < 2) && (issued < 2) ) { - const warp_inst_t *pI = m_warp[warp_id].ibuffer_next_inst(); - bool valid = m_warp[warp_id].ibuffer_next_valid(); + while( !warp(warp_id).waiting() && !warp(warp_id).ibuffer_empty() && (checked < 2) && (issued < 2) ) { + const warp_inst_t *pI = warp(warp_id).ibuffer_next_inst(); + bool valid = warp(warp_id).ibuffer_next_valid(); unsigned pc,rpc; m_simt_stack[warp_id]->get_pdom_stack_top_info(&pc,&rpc); if( pI ) { assert(valid); if( pc != pI->pc ) { // control hazard - m_warp[warp_id].set_next_pc(pc); - m_warp[warp_id].ibuffer_flush(); + warp(warp_id).set_next_pc(pc); + warp(warp_id).ibuffer_flush(); } else { valid_inst = true; if ( !m_scoreboard->checkCollision(warp_id, pI) ) { ready_inst = true; const active_mask_t &active_mask = m_simt_stack[warp_id]->get_active_mask(); - assert( m_warp[warp_id].inst_in_pipeline() ); + assert( warp(warp_id).inst_in_pipeline() ); if ( (pI->op == LOAD_OP) || (pI->op == STORE_OP) || (pI->op == MEMORY_BARRIER_OP) ) { - if( m_pipeline_reg[ID_OC_MEM]->empty() ) { - issue_warp(m_pipeline_reg[ID_OC_MEM],pI,active_mask,warp_id); + if( (*m_mem_out)->empty() ) { + m_shader->issue_warp(*m_mem_out,pI,active_mask,warp_id); issued++; issued_inst=true; } } else { - bool sp_pipe_avail = m_pipeline_reg[ID_OC_SP]->empty(); - bool sfu_pipe_avail = m_pipeline_reg[ID_OC_SFU]->empty(); + bool sp_pipe_avail = (*m_sp_out)->empty(); + bool sfu_pipe_avail = (*m_sfu_out)->empty(); if( sp_pipe_avail && (pI->op != SFU_OP) ) { // always prefer SP pipe for operations that can use both SP and SFU pipelines - issue_warp(m_pipeline_reg[ID_OC_SP],pI,active_mask,warp_id); + m_shader->issue_warp(*m_sp_out,pI,active_mask,warp_id); issued++; issued_inst=true; } else if ( (pI->op == SFU_OP) || (pI->op == ALU_SFU_OP) ) { if( sfu_pipe_avail ) { - issue_warp(m_pipeline_reg[ID_OC_SFU],pI,active_mask,warp_id); + m_shader->issue_warp(*m_sfu_out,pI,active_mask,warp_id); issued++; issued_inst=true; } @@ -736,14 +759,14 @@ void shader_core_ctx::decode() } } else if( valid ) { // this case can happen after a return instruction in diverged warp - m_warp[warp_id].set_next_pc(pc); - m_warp[warp_id].ibuffer_flush(); + warp(warp_id).set_next_pc(pc); + warp(warp_id).ibuffer_flush(); } - m_warp[warp_id].ibuffer_step(); + warp(warp_id).ibuffer_step(); checked++; } if ( issued ) { - m_last_warp_issued=warp_id; + m_last_sup_id_issued=supervised_id; break; } } diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 3f3a688..e3a4c62 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -319,6 +319,44 @@ typedef std::bitset warp_set_t; int register_bank(int regnum, int wid, unsigned num_banks, unsigned bank_warp_shift); class shader_core_ctx; +class shader_core_config; +class shader_core_stats; + +class scheduler_unit { //this can be copied freely, so can be used in std containers. +public: + scheduler_unit(shader_core_stats* stats, shader_core_ctx* shader, + Scoreboard* scoreboard, simt_stack** simt, + std::vector* warp, + warp_inst_t** sp_out, + warp_inst_t** sfu_out, + warp_inst_t** mem_out) + : supervised_warps(), m_last_sup_id_issued(0), 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_sfu_out(sfu_out),m_mem_out(mem_out){} + void add_supervised_warp_id(int i) { + supervised_warps.push_back(i); + } + void cycle(); +private: + shd_warp_t& warp(int i); + + std::vector supervised_warps; + int m_last_sup_id_issued; + shader_core_stats *m_stats; + shader_core_ctx* m_shader; + // these things should become accessors: but would need a bigger rearchitect of how shader_core_ctx interacts with its parts. + Scoreboard* m_scoreboard; + simt_stack** m_simt_stack; + //warp_inst_t** m_pipeline_reg; + std::vector* m_warp; + warp_inst_t** m_sp_out; + warp_inst_t** m_sfu_out; + warp_inst_t** m_mem_out; +}; + + + + class opndcoll_rfu_t { // operand collector based register file unit public: @@ -985,6 +1023,9 @@ struct shader_core_config : public core_config cache_config m_L1D_config; bool gpgpu_dwf_reg_bankconflict; + + int gpgpu_num_sched_per_core; + //op collector int gpgpu_operand_collector_num_units_sp; int gpgpu_operand_collector_num_units_sfu; @@ -1079,6 +1120,7 @@ private: friend class shader_core_ctx; friend class ldst_unit; friend class simt_core_cluster; + friend class scheduler_unit; }; class shader_core_mem_fetch_allocator : public mem_fetch_allocator { @@ -1195,6 +1237,7 @@ private: void register_cta_thread_exit( unsigned cta_num ); void decode(); + friend class scheduler_unit; //this is needed to use private issue warp. void issue_warp( warp_inst_t *&warp, const warp_inst_t *pI, const active_mask_t &active_mask, unsigned warp_id ); void func_exec_inst( warp_inst_t &inst ); address_type translate_local_memaddr(address_type localaddr, unsigned tid, unsigned num_shader ); @@ -1241,7 +1284,6 @@ private: int m_last_warp_fetched; // decode/dispatch - int m_last_warp_issued; std::vector m_warp; // per warp information array barrier_set_t m_barriers; ifetch_buffer_t m_inst_fetch_buffer; @@ -1249,7 +1291,10 @@ private: warp_inst_t **m_pipeline_reg; Scoreboard *m_scoreboard; opndcoll_rfu_t m_operand_collector; - + + //schedule + std::vector schedulers; + // execute unsigned m_num_function_units; enum pipeline_stage_name_t *m_dispatch_port; -- cgit v1.3