diff options
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 26 | ||||
| -rw-r--r-- | src/gpgpu-sim/l2cache.cc | 1 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 152 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 31 | ||||
| -rw-r--r-- | src/trace-driven/ISA_Def/trace_opcode.h | 1 | ||||
| -rw-r--r-- | src/trace-driven/trace_driven.cc | 46 | ||||
| -rw-r--r-- | src/trace-driven/trace_driven.h | 26 |
7 files changed, 148 insertions, 135 deletions
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 5d75e50..05a19f0 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -60,7 +60,6 @@ #include "../debug.h" #include "../gpgpusim_entrypoint.h" #include "../statwrapper.h" -#include "../trace-driven/trace_driven.h" #include "../trace.h" #include "mem_latency_stat.h" #include "power_stat.h" @@ -1584,6 +1583,20 @@ void shader_core_ctx::release_shader_resource_1block(unsigned hw_ctaid, * object that tells us which kernel to ask for a CTA from */ +unsigned shader_core_ctx::sim_inc_thread(kernel_info_t &kernel) { + if (kernel.no_more_ctas_to_run()) { + return 0; // finished! + } + + if (kernel.more_threads_in_cta()) { + kernel.increment_thread_id(); + } + + if (!kernel.more_threads_in_cta()) kernel.increment_cta_id(); + + return 1; +} + void shader_core_ctx::issue_block2core(kernel_info_t &kernel) { if (!m_config->gpgpu_concurrent_kernel_sm) set_max_cta(kernel); @@ -1649,10 +1662,10 @@ void shader_core_ctx::issue_block2core(kernel_info_t &kernel) { for (unsigned i = start_thread; i < end_thread; i++) { m_threadState[i].m_cta_id = free_cta_hw_id; unsigned warp_id = i / m_config->warp_size; + // in trace-driven mode, bypass the functional model initialization, no need + // for this if (m_gpu->get_config().is_trace_driven_mode()) { - trace_shader_core_ctx *trace_core = - static_cast<trace_shader_core_ctx *>(this); - nthreads_in_block += trace_core->trace_sim_inc_thread(kernel); + nthreads_in_block += sim_inc_thread(kernel); } else nthreads_in_block += ptx_sim_init_thread( kernel, &m_thread[i], m_sid, i, cta_size - (i - start_thread), @@ -1992,13 +2005,14 @@ void shader_core_ctx::dump_warp_state(FILE *fout) const { fprintf(fout, "\n"); fprintf(fout, "per warp functional simulation status:\n"); for (unsigned w = 0; w < m_config->max_warps_per_shader; w++) - m_warp[w].print(fout); + m_warp[w]->print(fout); } void gpgpu_sim::perf_memcpy_to_gpu(size_t dst_start_addr, size_t count) { if (m_memory_config->m_perf_sim_memcpy) { // if(!m_config.trace_driven_mode) //in trace-driven mode, CUDA runtime - // can start nre data structure at any position assert (dst_start_addr % 32 + // can start nre data structure at any position assert (dst_start_addr % + // 32 //== 0); for (unsigned counter = 0; counter < count; counter += 32) { diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index b7b5745..7fed99b 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -793,6 +793,7 @@ void memory_sub_partition::push(mem_fetch *m_req, unsigned long long cycle) { mem_fetch *memory_sub_partition::pop() { mem_fetch *mf = m_L2_icnt_queue->pop(); m_request_tracker.erase(mf); + // in trace-driven mode, we bypass the atomic functional model if (mf && mf->isatomic() && !m_gpu->get_config().is_trace_driven_mode()) { mf->do_atomic(); } diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index ebb6878..ee8076d 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -153,7 +153,14 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, get_shader_instruction_cache_id(), m_icnt, IN_L1I_MISS_QUEUE); - m_warp.resize(m_config->max_warps_per_shader, shd_warp_t(this, warp_size)); + m_warp.resize(m_config->max_warps_per_shader); + for (unsigned k = 0; k < m_config->max_warps_per_shader; ++k) { + if (m_gpu->get_config().is_trace_driven_mode()) + m_warp[k] = new trace_shd_warp_t(this, warp_size); + else + m_warp[k] = new shd_warp_t(this, warp_size); + } + // m_warp.resize(m_config->max_warps_per_shader, shd_warp_t(this, warp_size)); m_scoreboard = new Scoreboard(m_sid, m_config->max_warps_per_shader, gpu); // scedulers @@ -437,7 +444,7 @@ 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_warp[i]->reset(); m_simt_stack[i]->reset(); } } @@ -484,17 +491,11 @@ 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); + m_warp[i]->init(start_pc, cta_id, i, active_threads, m_dynamic_warp_id); ++m_dynamic_warp_id; m_not_completed += n_active; ++m_active_warps; } - - if (m_gpu->get_config().is_trace_driven_mode()) { - trace_shader_core_ctx *trace_core = - static_cast<trace_shader_core_ctx *>(this); - trace_core->init_traces(start_warp, end_warp, kernel); - } } } @@ -789,14 +790,14 @@ void shader_core_ctx::decode() { address_type pc = m_inst_fetch_buffer.m_pc; const warp_inst_t *pI1; if (m_gpu->get_config().is_trace_driven_mode()) { - trace_shader_core_ctx *trace_core = - static_cast<trace_shader_core_ctx *>(this); - pI1 = trace_core->m_trace_warp[m_inst_fetch_buffer.m_warp_id] - .get_next_inst(); - } else + // read the inst from the traces + pI1 = m_warp[m_inst_fetch_buffer.m_warp_id]->get_next_trace_inst(); + } else { + // read the inst from the functional model pI1 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc); - m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(0, pI1); - m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline(); + } + m_warp[m_inst_fetch_buffer.m_warp_id]->ibuffer_fill(0, pI1); + m_warp[m_inst_fetch_buffer.m_warp_id]->inc_inst_in_pipeline(); if (pI1) { m_stats->m_num_decoded_insn[m_sid]++; if (pI1->oprnd_type == INT_OP) { @@ -806,15 +807,15 @@ void shader_core_ctx::decode() { } const warp_inst_t *pI2; if (m_gpu->get_config().is_trace_driven_mode()) { - trace_shader_core_ctx *trace_core = - static_cast<trace_shader_core_ctx *>(this); - pI2 = trace_core->m_trace_warp[m_inst_fetch_buffer.m_warp_id] - .get_next_inst(); - } else + // read the inst from the traces + pI2 = m_warp[m_inst_fetch_buffer.m_warp_id]->get_next_trace_inst(); + } else { + // read the inst from the functional model pI2 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc + pI1->isize); + } if (pI2) { - m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(1, pI2); - m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline(); + m_warp[m_inst_fetch_buffer.m_warp_id]->ibuffer_fill(1, pI2); + m_warp[m_inst_fetch_buffer.m_warp_id]->inc_inst_in_pipeline(); m_stats->m_num_decoded_insn[m_sid]++; if (pI2->oprnd_type == INT_OP) { m_stats->m_num_INTdecoded_insn[m_sid]++; @@ -831,21 +832,16 @@ void shader_core_ctx::fetch() { if (!m_inst_fetch_buffer.m_valid) { if (m_L1I->access_ready()) { mem_fetch *mf = m_L1I->next_access(); - m_warp[mf->get_wid()].clear_imiss_pending(); - m_inst_fetch_buffer = ifetch_buffer_t( - m_warp[mf->get_wid()].get_pc(), mf->get_access_size(), mf->get_wid()); - if (m_gpu->get_config().is_trace_driven_mode()) { - trace_shader_core_ctx *trace_core = - static_cast<trace_shader_core_ctx *>(this); - assert(trace_core->m_trace_warp[mf->get_wid()].get_pc() == - (address_type)(mf->get_addr() - PROGRAM_MEM_START)); - } else - assert(m_warp[mf->get_wid()].get_pc() == - (mf->get_addr() - - PROGRAM_MEM_START)); // Verify that we got the instruction we - // were expecting. + m_warp[mf->get_wid()]->clear_imiss_pending(); + m_inst_fetch_buffer = + ifetch_buffer_t(m_warp[mf->get_wid()]->get_pc(), + mf->get_access_size(), mf->get_wid()); + assert(m_warp[mf->get_wid()]->get_pc() == + (mf->get_addr() - + PROGRAM_MEM_START)); // Verify that we got the instruction we + // were expecting. m_inst_fetch_buffer.m_valid = true; - m_warp[mf->get_wid()].set_last_fetch(m_gpu->gpu_sim_cycle); + m_warp[mf->get_wid()]->set_last_fetch(m_gpu->gpu_sim_cycle); delete mf; } else { // find an active warp with space in instruction buffer that is not @@ -857,46 +853,38 @@ void shader_core_ctx::fetch() { // this code checks if this warp has finished executing and can be // reclaimed - if (m_warp[warp_id].hardware_done() && + if (m_warp[warp_id]->hardware_done() && !m_scoreboard->pendingWrites(warp_id) && - !m_warp[warp_id].done_exit()) { + !m_warp[warp_id]->done_exit()) { bool did_exit = false; for (unsigned t = 0; t < m_config->warp_size; t++) { unsigned tid = warp_id * m_config->warp_size + t; if (m_threadState[tid].m_active == true) { m_threadState[tid].m_active = false; - unsigned cta_id = m_warp[warp_id].get_cta_id(); - if (m_gpu->get_config().is_trace_driven_mode()) { + unsigned cta_id = m_warp[warp_id]->get_cta_id(); + if (m_thread[tid] == NULL) { register_cta_thread_exit(cta_id, m_kernel); } else register_cta_thread_exit(cta_id, &(m_thread[tid]->get_kernel())); m_not_completed -= 1; m_active_threads.reset(tid); - if (!m_gpu->get_config().is_trace_driven_mode()) - assert(m_thread[tid] != NULL); did_exit = true; } } - if (did_exit) m_warp[warp_id].set_done_exit(); + if (did_exit) m_warp[warp_id]->set_done_exit(); --m_active_warps; assert(m_active_warps >= 0); } // this code fetches instructions from the i-cache or generates memory - if (!m_warp[warp_id].functional_done() && - !m_warp[warp_id].imiss_pending() && - m_warp[warp_id].ibuffer_empty()) { + if (!m_warp[warp_id]->functional_done() && + !m_warp[warp_id]->imiss_pending() && + m_warp[warp_id]->ibuffer_empty()) { address_type pc; - if (m_gpu->get_config().is_trace_driven_mode()) { - trace_shader_core_ctx *trace_core = - static_cast<trace_shader_core_ctx *>(this); - pc = trace_core->m_trace_warp[warp_id].get_pc(); - } else - pc = m_warp[warp_id].get_pc(); + pc = m_warp[warp_id]->get_pc(); address_type ppc = pc + PROGRAM_MEM_START; - unsigned nbytes = - m_gpu->get_config().is_trace_driven_mode() ? 32 : 16; + unsigned nbytes = 16; unsigned offset_in_block = pc & (m_config->m_L1I_config.get_line_sz() - 1); if ((offset_in_block + nbytes) > m_config->m_L1I_config.get_line_sz()) @@ -920,12 +908,12 @@ void shader_core_ctx::fetch() { if (status == MISS) { m_last_warp_fetched = warp_id; - m_warp[warp_id].set_imiss_pending(); - m_warp[warp_id].set_last_fetch(m_gpu->gpu_sim_cycle); + m_warp[warp_id]->set_imiss_pending(); + m_warp[warp_id]->set_last_fetch(m_gpu->gpu_sim_cycle); } else if (status == HIT) { m_last_warp_fetched = warp_id; m_inst_fetch_buffer = ifetch_buffer_t(pc, nbytes, warp_id); - m_warp[warp_id].set_last_fetch(m_gpu->gpu_sim_cycle); + m_warp[warp_id]->set_last_fetch(m_gpu->gpu_sim_cycle); delete mf; } else { m_last_warp_fetched = warp_id; @@ -957,23 +945,23 @@ void shader_core_ctx::issue_warp(register_set &pipe_reg_set, pipe_reg_set.get_free(m_config->sub_core_model, sch_id); assert(pipe_reg); - m_warp[warp_id].ibuffer_free(); + m_warp[warp_id]->ibuffer_free(); assert(next_inst->valid()); **pipe_reg = *next_inst; // static instruction information (*pipe_reg)->issue(active_mask, warp_id, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, - m_warp[warp_id].get_dynamic_warp_id(), + 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) { - 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, + 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)); } else if (next_inst->op == MEMORY_BARRIER_OP) { - m_warp[warp_id].set_membar(); + m_warp[warp_id]->set_membar(); } if (!m_gpu->get_config() @@ -981,7 +969,7 @@ void shader_core_ctx::issue_warp(register_set &pipe_reg_set, updateSIMTStack(warp_id, *pipe_reg); m_scoreboard->reserveRegisters(*pipe_reg); - m_warp[warp_id].set_next_pc(next_inst->pc + next_inst->isize); + m_warp[warp_id]->set_next_pc(next_inst->pc + next_inst->isize); } void shader_core_ctx::issue() { @@ -999,7 +987,7 @@ void shader_core_ctx::issue() { //} } -shd_warp_t &scheduler_unit::warp(int i) { return (*m_warp)[i]; } +shd_warp_t &scheduler_unit::warp(int i) { return *((*m_warp)[i]); } /** * A general function to order things in a Loose Round Robin way. The simplist @@ -1144,8 +1132,7 @@ void scheduler_unit::cycle() { bool warp_inst_issued = false; unsigned pc, rpc; if (m_shader->m_gpu->get_config().is_trace_driven_mode()) - pc = pI->pc; // assume no control hazard in trace mode. TO DO: to be - // fixed + pc = pI->pc; // assume no control hazard in trace-driven mode. else m_simt_stack[warp_id]->get_pdom_stack_top_info(&pc, &rpc); SCHED_DPRINTF( @@ -1171,7 +1158,7 @@ void scheduler_unit::cycle() { (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id()); ready_inst = true; - // For Trace-driven, the active mask already set in from traces, so + // For Trace-driven, the active mask already set in traces, so // just read it from the inst const active_mask_t &active_mask = m_shader->m_gpu->get_config().is_trace_driven_mode() @@ -1482,7 +1469,7 @@ void two_level_active_scheduler::order_warps() { swl_scheduler::swl_scheduler(shader_core_stats *stats, shader_core_ctx *shader, Scoreboard *scoreboard, simt_stack **simt, - std::vector<shd_warp_t> *warp, + std::vector<shd_warp_t *> *warp, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, @@ -1712,7 +1699,7 @@ void shader_core_ctx::writeback() { m_operand_collector.writeback(*pipe_reg); unsigned warp_id = pipe_reg->warp_id(); m_scoreboard->releaseRegisters(pipe_reg); - m_warp[warp_id].dec_inst_in_pipeline(); + m_warp[warp_id]->dec_inst_in_pipeline(); warp_inst_complete(*pipe_reg); m_gpu->gpu_sim_insn_last_update_sid = m_sid; m_gpu->gpu_sim_insn_last_update = m_gpu->gpu_sim_cycle; @@ -2380,6 +2367,7 @@ void ldst_unit::writeback() { if (!m_pipeline_reg[0]->empty()) { m_next_wb = *m_pipeline_reg[0]; if (m_next_wb.isatomic()) { + // it trace driven mode, we bypass the atomic functional model if (!m_core->get_gpu()->get_config().is_trace_driven_mode()) m_next_wb.do_atomic(); m_core->decrement_atomic_count(m_next_wb.warp_id(), @@ -3049,7 +3037,7 @@ void shader_core_ctx::display_pipeline(FILE *fout, int print_mem, } fprintf(fout, "\nibuffer status:\n"); for (unsigned i = 0; i < m_config->max_warps_per_shader; i++) { - if (!m_warp[i].ibuffer_empty()) m_warp[i].print_ibuffer(fout); + if (!m_warp[i]->ibuffer_empty()) m_warp[i]->print_ibuffer(fout); } fprintf(fout, "\n"); display_simt_state(fout, mask); @@ -3342,7 +3330,7 @@ std::list<opndcoll_rfu_t::op_t> opndcoll_rfu_t::arbiter_t::allocate_reads() { assert(output < _outputs); if ((output < _outputs) && (_inmatch[input] == -1) && //( _outmatch[output] == -1 ) && //allow OC to read multiple reg - //banks at the same cycle + // banks at the same cycle (_request[input][output] /*.label != -1*/)) { // Grant! _inmatch[input] = output; @@ -3569,7 +3557,7 @@ bool shader_core_ctx::check_if_non_released_reduction_barrier( bool non_released_barrier_reduction = false; bool warp_stucked_at_barrier = warp_waiting_at_barrier(warp_id); bool single_inst_in_pipeline = - (m_warp[warp_id].num_issued_inst_in_pipeline() == 1); + (m_warp[warp_id]->num_issued_inst_in_pipeline() == 1); non_released_barrier_reduction = single_inst_in_pipeline and warp_stucked_at_barrier and bar_red_op; printf("non_released_barrier_reduction=%u\n", non_released_barrier_reduction); @@ -3581,9 +3569,9 @@ bool shader_core_ctx::warp_waiting_at_barrier(unsigned warp_id) const { } bool shader_core_ctx::warp_waiting_at_mem_barrier(unsigned warp_id) { - if (!m_warp[warp_id].get_membar()) return false; + if (!m_warp[warp_id]->get_membar()) return false; if (!m_scoreboard->pendingWrites(warp_id)) { - m_warp[warp_id].clear_membar(); + m_warp[warp_id]->clear_membar(); if (m_gpu->get_config().flush_l1()) { // Mahmoud fixed this on Nov 2019 // Invalidate L1 cache @@ -3609,8 +3597,8 @@ void shader_core_ctx::set_max_cta(const kernel_info_t &kernel) { } void shader_core_ctx::decrement_atomic_count(unsigned wid, unsigned n) { - assert(m_warp[wid].get_n_atomic() >= n); - m_warp[wid].dec_n_atomic(n); + assert(m_warp[wid]->get_n_atomic() >= n); + m_warp[wid]->dec_n_atomic(n); } void shader_core_ctx::broadcast_barrier_reduction(unsigned cta_id, @@ -3619,7 +3607,7 @@ void shader_core_ctx::broadcast_barrier_reduction(unsigned cta_id, for (unsigned i = 0; i < m_config->max_warps_per_shader; i++) { if (warps.test(i)) { const warp_inst_t *inst = - m_warp[i].restore_info_of_last_inst_at_barrier(); + m_warp[i]->restore_info_of_last_inst_at_barrier(); const_cast<warp_inst_t *>(inst)->broadcast_barrier_reduction( inst->get_active_mask()); } @@ -3646,7 +3634,7 @@ void shader_core_ctx::store_ack(class mem_fetch *mf) { assert(mf->get_type() == WRITE_ACK || (m_config->gpgpu_perfect_mem && mf->get_is_write())); unsigned warp_id = mf->get_wid(); - m_warp[warp_id].dec_store_req(); + m_warp[warp_id]->dec_store_req(); } void shader_core_ctx::print_cache_stats(FILE *fp, unsigned &dl1_accesses, @@ -4358,7 +4346,7 @@ void simt_core_cluster::get_L1T_sub_stats(struct cache_sub_stats &css) const { void shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid) { - if (inst.isatomic()) m_warp[inst.warp_id()].inc_n_atomic(); + if (inst.isatomic()) m_warp[inst.warp_id()]->inc_n_atomic(); if (inst.space.is_local() && (inst.is_load() || inst.is_store())) { new_addr_type localaddrs[MAX_ACCESSES_PER_INSN_PER_THREAD]; unsigned num_addrs; @@ -4369,8 +4357,8 @@ void shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, inst.set_addr(t, (new_addr_type *)localaddrs, num_addrs); } if (ptx_thread_done(tid)) { - m_warp[inst.warp_id()].set_completed(t); - m_warp[inst.warp_id()].ibuffer_flush(); + m_warp[inst.warp_id()]->set_completed(t); + m_warp[inst.warp_id()]->ibuffer_flush(); } // PC-Histogram Update diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index bd08794..8e29a78 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -167,7 +167,7 @@ class shd_warp_t { void set_membar() { m_membar = true; } void clear_membar() { m_membar = false; } bool get_membar() const { return m_membar; } - address_type get_pc() const { return m_next_pc; } + virtual address_type get_pc() const { return m_next_pc; } void set_next_pc(address_type pc) { m_next_pc = pc; } void store_info_of_last_inst_at_barrier(const warp_inst_t *pI) { @@ -237,6 +237,9 @@ class shd_warp_t { unsigned get_dynamic_warp_id() const { return m_dynamic_warp_id; } unsigned get_warp_id() const { return m_warp_id; } + // this fuction is used for trace_driven mode + virtual const warp_inst_t *get_next_trace_inst() { return NULL; } + private: static const unsigned IBUFFER_SIZE = 2; class shader_core_ctx *m_shader; @@ -326,7 +329,7 @@ class scheduler_unit { // this can be copied freely, so can be used in std public: scheduler_unit(shader_core_stats *stats, shader_core_ctx *shader, Scoreboard *scoreboard, simt_stack **simt, - std::vector<shd_warp_t> *warp, register_set *sp_out, + std::vector<shd_warp_t *> *warp, 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) @@ -415,7 +418,7 @@ class scheduler_unit { // this can be copied freely, so can be used in std Scoreboard *m_scoreboard; simt_stack **m_simt_stack; // warp_inst_t** m_pipeline_reg; - std::vector<shd_warp_t> *m_warp; + std::vector<shd_warp_t *> *m_warp; register_set *m_sp_out; register_set *m_dp_out; register_set *m_sfu_out; @@ -430,7 +433,7 @@ class lrr_scheduler : public scheduler_unit { public: lrr_scheduler(shader_core_stats *stats, shader_core_ctx *shader, Scoreboard *scoreboard, simt_stack **simt, - std::vector<shd_warp_t> *warp, register_set *sp_out, + std::vector<shd_warp_t *> *warp, 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) @@ -447,7 +450,7 @@ class gto_scheduler : public scheduler_unit { public: gto_scheduler(shader_core_stats *stats, shader_core_ctx *shader, Scoreboard *scoreboard, simt_stack **simt, - std::vector<shd_warp_t> *warp, register_set *sp_out, + std::vector<shd_warp_t *> *warp, 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) @@ -464,7 +467,7 @@ class oldest_scheduler : public scheduler_unit { public: oldest_scheduler(shader_core_stats *stats, shader_core_ctx *shader, Scoreboard *scoreboard, simt_stack **simt, - std::vector<shd_warp_t> *warp, register_set *sp_out, + std::vector<shd_warp_t *> *warp, 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) @@ -481,7 +484,7 @@ class two_level_active_scheduler : public scheduler_unit { public: two_level_active_scheduler(shader_core_stats *stats, shader_core_ctx *shader, Scoreboard *scoreboard, simt_stack **simt, - std::vector<shd_warp_t> *warp, + std::vector<shd_warp_t *> *warp, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, @@ -530,7 +533,7 @@ class swl_scheduler : public scheduler_unit { public: swl_scheduler(shader_core_stats *stats, shader_core_ctx *shader, Scoreboard *scoreboard, simt_stack **simt, - std::vector<shd_warp_t> *warp, register_set *sp_out, + std::vector<shd_warp_t *> *warp, 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); @@ -1868,9 +1871,9 @@ class shader_core_ctx : public core_t { // modifiers void mem_instruction_stats(const warp_inst_t &inst); void decrement_atomic_count(unsigned wid, unsigned n); - void inc_store_req(unsigned warp_id) { m_warp[warp_id].inc_store_req(); } + void inc_store_req(unsigned warp_id) { m_warp[warp_id]->inc_store_req(); } void dec_inst_in_pipeline(unsigned warp_id) { - m_warp[warp_id].dec_inst_in_pipeline(); + m_warp[warp_id]->dec_inst_in_pipeline(); } // also used in writeback() void store_ack(class mem_fetch *mf); bool warp_waiting_at_mem_barrier(unsigned warp_id); @@ -2061,8 +2064,9 @@ class shader_core_ctx : public core_t { } int test_res_bus(int latency); - void init_warps(unsigned cta_id, unsigned start_thread, unsigned end_thread, - unsigned ctaid, int cta_size, kernel_info_t &kernel); + virtual void init_warps(unsigned cta_id, unsigned start_thread, + unsigned end_thread, unsigned ctaid, int cta_size, + kernel_info_t &kernel); virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid); address_type next_pc(int tid) const; @@ -2128,7 +2132,7 @@ class shader_core_ctx : public core_t { int m_last_warp_fetched; // decode/dispatch - std::vector<shd_warp_t> m_warp; // per warp information array + std::vector<shd_warp_t *> m_warp; // per warp information array barrier_set_t m_barriers; ifetch_buffer_t m_inst_fetch_buffer; std::vector<register_set> m_pipeline_reg; @@ -2178,6 +2182,7 @@ class shader_core_ctx : public core_t { std::map<unsigned int, unsigned int> m_occupied_cta_to_hwtid; friend class trace_shader_core_ctx; + unsigned sim_inc_thread(kernel_info_t &kernel); }; class simt_core_cluster { diff --git a/src/trace-driven/ISA_Def/trace_opcode.h b/src/trace-driven/ISA_Def/trace_opcode.h index e68be45..5675957 100644 --- a/src/trace-driven/ISA_Def/trace_opcode.h +++ b/src/trace-driven/ISA_Def/trace_opcode.h @@ -218,7 +218,6 @@ enum TraceInstrOpcode { }; typedef enum TraceInstrOpcode sass_op_type; - struct OpcodeChar { OpcodeChar(unsigned m_opcode, unsigned m_opcode_category) { opcode = m_opcode; diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 44468b1..8fa63b4 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -173,7 +173,7 @@ void trace_parser::kernel_finalizer(trace_kernel_info_t* kernel_info) { delete kernel_info; } -const trace_warp_inst_t* trace_shd_warp_t::get_next_inst() { +const trace_warp_inst_t* trace_shd_warp_t::get_next_trace_inst() { if (trace_pc < warp_traces.size()) { return &warp_traces[trace_pc++]; } else @@ -188,7 +188,7 @@ void trace_shd_warp_t::clear() { // functional_done bool trace_shd_warp_t::trace_done() { return trace_pc == (warp_traces.size()); } -address_type trace_shd_warp_t::get_start_pc() { +address_type trace_shd_warp_t::get_start_trace_pc() { assert(warp_traces.size() > 0); return warp_traces[0].pc; } @@ -629,43 +629,46 @@ void trace_config::set_latency(unsigned category, unsigned& latency, } } -unsigned trace_shader_core_ctx::trace_sim_inc_thread(kernel_info_t& kernel) { - if (kernel.no_more_ctas_to_run()) { - return 0; // finished! - } - - if (kernel.more_threads_in_cta()) { - kernel.increment_thread_id(); - } +void trace_shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread, + unsigned end_thread, unsigned ctaid, + int cta_size, kernel_info_t& kernel) { + // call base class + shader_core_ctx::init_warps(cta_id, start_thread, end_thread, ctaid, cta_size, + kernel); - if (!kernel.more_threads_in_cta()) kernel.increment_cta_id(); + // then init traces + unsigned start_warp = start_thread / m_config->warp_size; + unsigned end_warp = end_thread / m_config->warp_size + + ((end_thread % m_config->warp_size) ? 1 : 0); - return 1; + init_traces(start_warp, end_warp, kernel); } void trace_shader_core_ctx::init_traces(unsigned start_warp, unsigned end_warp, kernel_info_t& kernel) { std::vector<std::vector<trace_warp_inst_t>*> threadblock_traces; for (unsigned i = start_warp; i < end_warp; ++i) { - m_trace_warp[i].clear(); - threadblock_traces.push_back(&(m_trace_warp[i].warp_traces)); + trace_shd_warp_t* m_trace_warp = static_cast<trace_shd_warp_t*>(m_warp[i]); + m_trace_warp->clear(); + threadblock_traces.push_back(&(m_trace_warp->warp_traces)); } trace_kernel_info_t& trace_kernel = static_cast<trace_kernel_info_t&>(kernel); trace_kernel.get_next_threadblock_traces(threadblock_traces); - // set pc + // set the pc from the traces and ignore the functional model for (unsigned i = start_warp; i < end_warp; ++i) { - m_warp[i].set_next_pc(m_trace_warp[i].get_start_pc()); + trace_shd_warp_t* m_trace_warp = static_cast<trace_shd_warp_t*>(m_warp[i]); + m_trace_warp->set_next_pc(m_trace_warp->get_start_trace_pc()); } } void trace_shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t& inst, unsigned t, unsigned tid) { - if (inst.isatomic()) m_warp[inst.warp_id()].inc_n_atomic(); + if (inst.isatomic()) m_warp[inst.warp_id()]->inc_n_atomic(); if (inst.op == EXIT_OPS) { - m_warp[inst.warp_id()].set_completed(t); + m_warp[inst.warp_id()]->set_completed(t); } } @@ -683,9 +686,10 @@ void trace_shader_core_ctx::func_exec_inst(warp_inst_t& inst) { checkExecutionStatusAndUpdate(inst, t, tid); } } - if (m_trace_warp[inst.warp_id()].trace_done() && - m_warp[inst.warp_id()].functional_done()) { - m_warp[inst.warp_id()].ibuffer_flush(); + trace_shd_warp_t* m_trace_warp = + static_cast<trace_shd_warp_t*>(m_warp[inst.warp_id()]); + if (m_trace_warp->trace_done() && m_trace_warp->functional_done()) { + m_trace_warp->ibuffer_flush(); m_barriers.warp_exit(inst.warp_id()); } } diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index 09a2527..a35cd83 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -112,16 +112,19 @@ class trace_parser { gpgpu_context* m_gpgpu_context; }; -class trace_shd_warp_t { +class trace_shd_warp_t : public shd_warp_t { public: - trace_shd_warp_t() { trace_pc = 0; } + trace_shd_warp_t(class shader_core_ctx* shader, unsigned warp_size) + : shd_warp_t(shader, warp_size) { + trace_pc = 0; + } std::vector<trace_warp_inst_t> warp_traces; - const trace_warp_inst_t* get_next_inst(); + const trace_warp_inst_t* get_next_trace_inst(); void clear(); bool trace_done(); - address_type get_start_pc(); - address_type get_pc(); + address_type get_start_trace_pc(); + virtual address_type get_pc(); private: unsigned trace_pc; @@ -135,20 +138,19 @@ class trace_shader_core_ctx : public shader_core_ctx { const memory_config* mem_config, shader_core_stats* stats) : shader_core_ctx(gpu, cluster, shader_id, tpc_id, config, mem_config, - stats) { - m_trace_warp.resize(get_config()->max_warps_per_shader); - } + stats) {} virtual void checkExecutionStatusAndUpdate(warp_inst_t& inst, unsigned t, unsigned tid); - void init_traces(unsigned start_warp, unsigned end_warp, - kernel_info_t& kernel); - unsigned trace_sim_inc_thread(kernel_info_t& kernel); + virtual void init_warps(unsigned cta_id, unsigned start_thread, + unsigned end_thread, unsigned ctaid, int cta_size, + kernel_info_t& kernel); virtual void func_exec_inst(warp_inst_t& inst); friend class shader_core_ctx; private: - std::vector<trace_shd_warp_t> m_trace_warp; + void init_traces(unsigned start_warp, unsigned end_warp, + kernel_info_t& kernel); }; #endif |
