diff options
Diffstat (limited to 'src/gpgpu-sim/shader.cc')
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 260 |
1 files changed, 223 insertions, 37 deletions
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 7a4ff37..bcf38d3 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -465,6 +465,9 @@ void shader_core_ctx::create_exec_pipeline() { for (unsigned i = 0; i < num_result_bus; i++) { this->m_result_bus.push_back(new std::bitset<MAX_ALU_LATENCY>()); } + + if (m_config->model == AWARE_RECONVERGENCE) + updateSIMTDivergenceStructuresInitialization(); } shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, @@ -526,7 +529,11 @@ void shader_core_ctx::reinit(unsigned start_thread, unsigned end_thread, for (unsigned i = start_thread / m_config->warp_size; i < end_thread / m_config->warp_size; ++i) { m_warp[i]->reset(); - m_simt_stack[i]->reset(); + if (m_config->model == POST_DOMINATOR) { + m_simt_stack[i]->reset(); + } else { + m_simt_tables[i]->reset(); + } } } @@ -535,23 +542,24 @@ void shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread, int cta_size, kernel_info_t &kernel) { address_type start_pc = next_pc(start_thread); unsigned kernel_id = kernel.get_uid(); - if (m_config->model == POST_DOMINATOR) { - unsigned start_warp = start_thread / m_config->warp_size; - unsigned warp_per_cta = cta_size / m_config->warp_size; - unsigned end_warp = end_thread / m_config->warp_size + - ((end_thread % m_config->warp_size) ? 1 : 0); - for (unsigned i = start_warp; i < end_warp; ++i) { - unsigned n_active = 0; - simt_mask_t active_threads; - for (unsigned t = 0; t < m_config->warp_size; t++) { - unsigned hwtid = i * m_config->warp_size + t; - if (hwtid < end_thread) { - n_active++; - assert(!m_active_threads.test(hwtid)); - m_active_threads.set(hwtid); - active_threads.set(t); - } + unsigned start_warp = start_thread / m_config->warp_size; + unsigned warp_per_cta = cta_size / m_config->warp_size; + unsigned end_warp = end_thread / m_config->warp_size + + ((end_thread % m_config->warp_size) ? 1 : 0); + for (unsigned i = start_warp; i < end_warp; ++i) { + unsigned n_active = 0; + simt_mask_t active_threads; + for (unsigned t = 0; t < m_config->warp_size; t++) { + unsigned hwtid = i * m_config->warp_size + t; + if (hwtid < end_thread) { + n_active++; + assert(!m_active_threads.test(hwtid)); + m_active_threads.set(hwtid); + active_threads.set(t); } + } + + if (m_config->model == POST_DOMINATOR) { m_simt_stack[i]->launch(start_pc, active_threads); if (m_gpu->resume_option == 1 && kernel_id == m_gpu->resume_kernel && @@ -570,13 +578,15 @@ void shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread, } start_pc = pc; } - - m_warp[i]->init(start_pc, cta_id, i, active_threads, m_dynamic_warp_id, - kernel.get_streamID()); - ++m_dynamic_warp_id; - m_not_completed += n_active; - ++m_active_warps; + } else { + m_simt_tables[i]->launch(start_pc, active_threads); } + + m_warp[i]->init(start_pc, cta_id, i, active_threads, m_dynamic_warp_id, + kernel.get_streamID()); + ++m_dynamic_warp_id; + m_not_completed += n_active; + ++m_active_warps; } } @@ -599,7 +609,11 @@ void gpgpu_sim::get_pdom_stack_top_info(unsigned sid, unsigned tid, void shader_core_ctx::get_pdom_stack_top_info(unsigned tid, unsigned *pc, unsigned *rpc) const { unsigned warp_id = tid / m_config->warp_size; - m_simt_stack[warp_id]->get_pdom_stack_top_info(pc, rpc); + if (m_config->model == POST_DOMINATOR) { + m_simt_stack[warp_id]->get_pdom_stack_top_info(pc, rpc); + } else { + m_simt_tables[warp_id]->get_pdom_active_split_info(pc, rpc); + } } float shader_core_ctx::get_current_occupancy(unsigned long long &active, @@ -879,12 +893,20 @@ void exec_shader_core_ctx::get_pdom_stack_top_info(unsigned warp_id, const warp_inst_t *pI, unsigned *pc, unsigned *rpc) { - m_simt_stack[warp_id]->get_pdom_stack_top_info(pc, rpc); + if (m_config->model == POST_DOMINATOR) { + m_simt_stack[warp_id]->get_pdom_stack_top_info(pc, rpc); + } else { + m_simt_tables[warp_id]->get_pdom_active_split_info(pc, rpc); + } } const active_mask_t &exec_shader_core_ctx::get_active_mask( unsigned warp_id, const warp_inst_t *pI) { - return m_simt_stack[warp_id]->get_active_mask(); + if (m_config->model == POST_DOMINATOR) { + return m_simt_stack[warp_id]->get_active_mask(); + } else { + return m_simt_tables[warp_id]->get_active_mask(); + } } void shader_core_ctx::decode() { @@ -974,7 +996,11 @@ void shader_core_ctx::fetch() { } // this code fetches instructions from the i-cache or generates memory - if (!m_warp[warp_id]->functional_done() && + bool simt_conditions = true; + if (m_config->model == AWARE_RECONVERGENCE) + simt_conditions = !is_virtualized(warp_id); + + if (simt_conditions && !m_warp[warp_id]->functional_done() && !m_warp[warp_id]->imiss_pending() && m_warp[warp_id]->ibuffer_empty()) { address_type pc; @@ -1070,11 +1096,31 @@ void shader_core_ctx::issue_warp(register_set &pipe_reg_set, } } + bool split_reaches_barrier = false; if (next_inst->op == BARRIER_OP) { m_warp[warp_id]->store_info_of_last_inst_at_barrier(*pipe_reg); - m_barriers.warp_reaches_barrier(m_warp[warp_id]->get_cta_id(), warp_id, - const_cast<warp_inst_t *>(next_inst)); - + if (m_config->model == POST_DOMINATOR) { + m_barriers.warp_reaches_barrier(m_warp[warp_id]->get_cta_id(), warp_id, + const_cast<warp_inst_t *>(next_inst)); + } else { + // AWARE_RECONVERGENCE: warp reaches barrier only when all its splits do + split_reaches_barrier = true; + bool warp_reaches_barrier = + m_simt_tables[warp_id]->split_reaches_barrier(next_inst->pc); + if (warp_reaches_barrier) { + split_reaches_barrier = false; + m_barriers.warp_reaches_barrier(m_warp[warp_id]->get_cta_id(), warp_id, + const_cast<warp_inst_t *>(next_inst)); + if (m_barriers.warps_count_at_barrier(m_warp[warp_id]->get_cta_id()) == + 0) { + unsigned n = m_config->n_thread_per_shader / m_config->warp_size; + for (unsigned i = 0; i < n; i++) { + if (m_warp[i]->get_cta_id() == m_warp[warp_id]->get_cta_id()) + m_simt_tables[i]->release_barrier(); + } + } + } + } } else if (next_inst->op == MEMORY_BARRIER_OP) { m_warp[warp_id]->set_membar(); } else if (next_inst->m_is_ldgdepbar) { // Add for LDGDEPBAR @@ -1120,10 +1166,11 @@ void shader_core_ctx::issue_warp(register_set &pipe_reg_set, } } - updateSIMTStack(warp_id, *pipe_reg); + updateSIMTDivergenceStructures(warp_id, *pipe_reg); m_scoreboard->reserveRegisters(*pipe_reg); m_warp[warp_id]->set_next_pc(next_inst->pc + next_inst->isize); + if (split_reaches_barrier) m_simt_tables[warp_id]->push_back(); } void shader_core_ctx::issue() { @@ -1299,9 +1346,17 @@ void scheduler_unit::cycle() { "barrier\n", (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id()); - while (!warp(warp_id).waiting() && !warp(warp_id).ibuffer_empty() && - (checked < max_issue) && (checked <= issued) && - (issued < max_issue)) { + bool simt_conditions = true; + if (m_shader->m_config->model == AWARE_RECONVERGENCE) { + simt_conditions = warp(warp_id).valid() && + !warp(warp_id).blocked() && + !warp(warp_id).pending_reconvergence() && + !warp(warp_id).virtualized(); + } + + while (simt_conditions && !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(); // Jin: handle cdp latency; if (pI && pI->m_is_cdp && warp(warp_id).m_cdp_latency > 0) { @@ -1415,12 +1470,18 @@ void scheduler_unit::cycle() { } if (execute_on_SP) { + bool bru_avail = true; + if (m_shader->m_config->model == AWARE_RECONVERGENCE && + pI->op == BRANCH_OP) + bru_avail = m_shader->branch_unit_avail(warp_id); + if (bru_avail) { 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); @@ -1836,6 +1897,14 @@ void shader_core_ctx::execute() { } } } + + // ITS: advance spill/fill state machines for all warps + if (m_config->model == AWARE_RECONVERGENCE) { + for (unsigned i = 0; i < m_warp_count; ++i) { + AWARE_DPRINTF("Cycling SIMT tables for Shader %d: Warp %d...\n", m_sid, i); + m_simt_tables[i]->cycle(); + } + } } void ldst_unit::print_cache_stats(FILE *fp, unsigned &dl1_accesses, @@ -2013,7 +2082,9 @@ mem_stage_stall_type ldst_unit::process_cache_access( if (status == HIT) { assert(!read_sent); inst.accessq_pop_back(); - if (inst.is_load()) { + if (inst.is_bru_st_fill_request() || inst.is_bru_rt_fill_request()) { + release_virtual_entries(inst); + } else if (inst.is_load()) { for (unsigned r = 0; r < MAX_OUTPUT_VALUES; r++) if (inst.out[r] > 0) m_pending_writes[inst.warp_id()][inst.out[r]]--; @@ -2698,10 +2769,41 @@ void ldst_unit::issue(register_set ®_set) { pipelined_simd_unit::issue(reg_set); } +void ldst_unit::release_virtual_entries(warp_inst_t &inst) { + if (inst.is_bru_st_fill_request()) { + unsigned wid = inst.warp_id(); + address_type addr = inst.pc; + unsigned entry = (addr - BRU_VIR_START - + (wid * m_config->warp_size) * MAX_BRU_VIR_PER_SPLIT) / + MAX_BRU_VIR_PER_SPLIT; + bool done = m_core->push_to_st_response_fifo(wid, entry); + if (done) { + inst.clear(); + inst.clear_pending_mem_requests(); + } + } else { + assert(inst.is_bru_rt_fill_request()); + unsigned wid = inst.warp_id(); + address_type addr = inst.pc; + unsigned entry = (addr - BRU_VIR_START - + (wid * m_config->warp_size) * MAX_BRU_VIR_PER_SPLIT - + MAX_BRU_VIR_PER_SPLIT / 2) / + MAX_BRU_VIR_PER_SPLIT; + bool done = m_core->push_to_rt_response_fifo(wid, entry); + if (done) { + inst.clear(); + inst.clear_pending_mem_requests(); + } + } +} + void ldst_unit::writeback() { // process next instruction that is going to writeback if (!m_next_wb.empty()) { - if (m_operand_collector->writeback(m_next_wb)) { + if (m_next_wb.is_bru_st_fill_request() || + m_next_wb.is_bru_rt_fill_request()) { + release_virtual_entries(m_next_wb); + } else if (m_operand_collector->writeback(m_next_wb)) { bool insn_completed = false; for (unsigned r = 0; r < MAX_OUTPUT_VALUES; r++) { if (m_next_wb.out[r] > 0) { @@ -3357,7 +3459,10 @@ void shader_core_ctx::display_simt_state(FILE *fout, int mask) const { if (nactive == 0) { continue; } - m_simt_stack[i]->print(fout); + if (m_config->model == POST_DOMINATOR) + m_simt_stack[i]->print(fout); + else + m_simt_tables[i]->print(fout); } fprintf(fout, "\n"); } @@ -3673,6 +3778,12 @@ void shader_core_config::set_pipeline_latency() { void shader_core_ctx::cycle() { if (!isactive() && get_not_completed() == 0) return; + if (m_config->model == AWARE_RECONVERGENCE && m_config->rec_time_out > 0) { + unsigned long long total_cycles = + m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle; + if (total_cycles % 10000 == 0) check_time_out(); + } + m_stats->shader_cycles[m_sid]++; writeback(); execute(); @@ -4114,6 +4225,81 @@ bool shd_warp_t::waiting() { return false; } +// ITS (AWARE Reconvergence) warp eligibility helpers +bool shd_warp_t::virtualized() { + return m_shader->is_virtualized(m_warp_id); +} + +bool shd_warp_t::pending_reconvergence() { + return m_shader->pending_reconvergence(m_warp_id); +} + +bool shd_warp_t::blocked() { + return m_shader->warp_blocked(m_warp_id); +} + +bool shd_warp_t::valid() { + return m_shader->warp_valid(m_warp_id); +} + +// ITS (AWARE Reconvergence) shader_core_ctx methods +void shader_core_ctx::updateSIMTDivergenceStructuresInitialization() { + unsigned n = m_config->n_thread_per_shader / m_config->warp_size; + for (unsigned i = 0; i < n; i++) { + m_simt_tables[i]->set_shader(this); + } +} + +bool shader_core_ctx::push_to_st_response_fifo(unsigned wid, unsigned entry) { + return m_simt_tables[wid]->push_to_st_response_fifo(entry); +} + +bool shader_core_ctx::push_to_rt_response_fifo(unsigned wid, unsigned entry) { + return m_simt_tables[wid]->push_to_rt_response_fifo(entry); +} + +bool shader_core_ctx::is_virtualized(unsigned wid) { + return m_simt_tables[wid]->is_virtualized(); +} + +bool shader_core_ctx::pending_reconvergence(unsigned wid) { + return m_simt_tables[wid]->is_pending_reconvergence(); +} + +bool shader_core_ctx::warp_blocked(unsigned wid) { + return m_simt_tables[wid]->blocked(); +} + +bool shader_core_ctx::warp_valid(unsigned wid) { + return m_simt_tables[wid]->valid(); +} + +void shader_core_ctx::update_st_size(unsigned n) { + // Stats not tracked in gpgpu-sim base; no-op. + (void)n; +} + +void shader_core_ctx::update_rt_size(unsigned n) { + // Stats not tracked in gpgpu-sim base; no-op. + (void)n; +} + +bool shader_core_ctx::branch_unit_avail(unsigned wid) { + return m_simt_tables[wid]->branch_unit_avail(); +} + +void shader_core_ctx::check_time_out() { + for (unsigned w = 0; w < m_config->max_warps_per_shader; w++) { + m_simt_tables[w]->check_time_out(); + } +} + +bool shader_core_ctx::memory_cycle(warp_inst_t &inst, + mem_stage_stall_type &rc_fail, + mem_stage_access_type &fail_type) { + return m_ldst_unit->memory_cycle(inst, rc_fail, fail_type); +} + void shd_warp_t::print(FILE *fout) const { if (!done_exit()) { fprintf(fout, |
