diff options
| -rw-r--r-- | libcuda/gpgpu_context.h | 1 | ||||
| -rw-r--r-- | src/abstract_hardware_model.cc | 1 | ||||
| -rw-r--r-- | src/abstract_hardware_model.h | 4 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 82 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.h | 23 | ||||
| -rw-r--r-- | src/gpgpu-sim/l2cache.cc | 5 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 187 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 98 | ||||
| -rw-r--r-- | src/gpgpusim_entrypoint.cc | 37 | ||||
| -rw-r--r-- | src/trace-driven/gpgpusim_trace_driven_main.cc | 62 | ||||
| -rw-r--r-- | src/trace-driven/trace_driven.cc | 126 | ||||
| -rw-r--r-- | src/trace-driven/trace_driven.h | 59 |
12 files changed, 427 insertions, 258 deletions
diff --git a/libcuda/gpgpu_context.h b/libcuda/gpgpu_context.h index f02e365..d0cd7c4 100644 --- a/libcuda/gpgpu_context.h +++ b/libcuda/gpgpu_context.h @@ -77,7 +77,6 @@ class gpgpu_context { const ptx_instruction *pc_to_instruction(unsigned pc); const warp_inst_t *ptx_fetch_inst(address_type pc); unsigned translate_pc_to_ptxlineno(unsigned pc); - class gpgpu_sim *gpgpu_trace_sim_init_perf(int argc, const char *argv[]); }; gpgpu_context *GPGPU_Context(); diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index 1247235..5ad6f10 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -257,6 +257,7 @@ void warp_inst_t::do_atomic(bool forceDo) { void warp_inst_t::do_atomic(const active_mask_t &access_mask, bool forceDo) { assert(m_isatomic && (!m_empty || forceDo)); + if (!should_do_atomic) return; for (unsigned i = 0; i < m_config->warp_size; i++) { if (access_mask.test(i)) { dram_callback_t &cb = m_per_scalar_thread[i].callback; diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index ef457a7..c58d39c 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -997,6 +997,7 @@ class warp_inst_t : public inst_t { m_cache_hit = false; m_is_printf = false; m_is_cdp = 0; + should_do_atomic = true; } virtual ~warp_inst_t() {} @@ -1144,6 +1145,7 @@ class warp_inst_t : public inst_t { unsigned long long issue_cycle; unsigned cycles; // used for implementing initiation interval delay bool m_isatomic; + bool should_do_atomic; bool m_is_printf; unsigned m_warp_id; unsigned m_dynamic_warp_id; @@ -1232,7 +1234,7 @@ class core_t { } void execute_warp_inst_t(warp_inst_t &inst, unsigned warpId = (unsigned)-1); bool ptx_thread_done(unsigned hw_thread_id) const; - void updateSIMTStack(unsigned warpId, warp_inst_t *inst); + virtual void updateSIMTStack(unsigned warpId, warp_inst_t *inst); void initilizeSIMTStack(unsigned warp_count, unsigned warps_size); void deleteSIMTStack(); warp_inst_t getExecuteWarp(unsigned warpId); diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 05a19f0..b62524e 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -529,32 +529,6 @@ void shader_core_config::reg_options(class OptionParser *opp) { option_parser_register(opp, "-gpgpu_reg_file_port_throughput", OPT_INT32, ®_file_port_throughput, "the number ports of the register file", "1"); - // used for trace-driven mode - option_parser_register(opp, "-trace_opcode_latency_initiation_int", OPT_CSTR, - &trace_opcode_latency_initiation_int, - "Opcode latencies and initiation for integers in " - "trace driven mode <latency,initiation>", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_sp", OPT_CSTR, - &trace_opcode_latency_initiation_sp, - "Opcode latencies and initiation for sp in trace " - "driven mode <latency,initiation>", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_dp", OPT_CSTR, - &trace_opcode_latency_initiation_dp, - "Opcode latencies and initiation for dp in trace " - "driven mode <latency,initiation>", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_sfu", OPT_CSTR, - &trace_opcode_latency_initiation_sfu, - "Opcode latencies and initiation for sfu in trace " - "driven mode <latency,initiation>", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_tensor", - OPT_CSTR, &trace_opcode_latency_initiation_tensor, - "Opcode latencies and initiation for tensor in trace " - "driven mode <latency,initiation>", - "4,1"); } void gpgpu_sim_config::reg_options(option_parser_t opp) { @@ -665,17 +639,6 @@ void gpgpu_sim_config::reg_options(option_parser_t opp) { &(gpgpu_ctx->device_runtime->g_TB_launch_latency), "thread block launch latency in cycles. Default: 0", "0"); - - // Trace driven mode parameters - option_parser_register(opp, "-trace_driven_mode", OPT_BOOL, - &trace_driven_mode, "Turn on trace_driven_mode", "0"); - option_parser_register(opp, "-trace_skip_first_kernel", OPT_BOOL, - &trace_skip_first_kernel, - "skip first intiliztion kernel in trace mode", "0"); - option_parser_register(opp, "-trace", OPT_CSTR, &g_traces_filename, - "traces kernel file" - "traces kernel file directory", - "./traces/kernelslist.g"); } ///////////////////////////////////////////////////////////////////////////// @@ -828,6 +791,14 @@ void gpgpu_sim::stop_all_running_kernels() { } } +void exec_gpgpu_sim::createSIMTCluster() { + m_cluster = new simt_core_cluster *[m_shader_config->n_simt_clusters]; + for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++) + m_cluster[i] = + new exec_simt_core_cluster(this, i, m_shader_config, m_memory_config, + m_shader_stats, m_memory_stats); +} + gpgpu_sim::gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx) : gpgpu_t(config, ctx), m_config(config) { gpgpu_ctx = ctx; @@ -868,12 +839,6 @@ gpgpu_sim::gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx) partiton_replys_in_parallel = 0; partiton_replys_in_parallel_total = 0; - m_cluster = new simt_core_cluster *[m_shader_config->n_simt_clusters]; - for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++) - m_cluster[i] = - new simt_core_cluster(this, i, m_shader_config, m_memory_config, - m_shader_stats, m_memory_stats); - m_memory_partition_unit = new memory_partition_unit *[m_memory_config->m_n_mem]; m_memory_sub_partition = @@ -1583,18 +1548,12 @@ 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; +unsigned exec_shader_core_ctx::sim_init_thread( + kernel_info_t &kernel, ptx_thread_info **thread_info, int sid, unsigned tid, + unsigned threads_left, unsigned num_threads, core_t *core, + unsigned hw_cta_id, unsigned hw_warp_id, gpgpu_t *gpu) { + return ptx_sim_init_thread(kernel, thread_info, sid, tid, threads_left, + num_threads, core, hw_cta_id, hw_warp_id, gpu); } void shader_core_ctx::issue_block2core(kernel_info_t &kernel) { @@ -1662,15 +1621,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()) { - 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), - m_config->n_thread_per_shader, this, free_cta_hw_id, warp_id, - m_cluster->get_gpu()); + nthreads_in_block += sim_init_thread( + kernel, &m_thread[i], m_sid, i, cta_size - (i - start_thread), + m_config->n_thread_per_shader, this, free_cta_hw_id, warp_id, + m_cluster->get_gpu()); m_threadState[i].m_active = true; // load thread local memory and register file if (m_gpu->resume_option == 1 && kernel.get_uid() == m_gpu->resume_kernel && diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 53f6ead..e083d33 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -370,9 +370,6 @@ class gpgpu_sim_config : public power_config, return runtime_pending_launch_count_limit; } - bool is_trace_driven_mode() const { return trace_driven_mode; } - bool is_skip_first_kernel() const { return trace_skip_first_kernel; } - char *get_traces_filename() const { return g_traces_filename; } bool flush_l1() const { return gpgpu_flush_l1_cache; } private: @@ -427,11 +424,6 @@ class gpgpu_sim_config : public power_config, unsigned int gpgpu_compute_capability_minor; unsigned long long liveness_message_freq; - // trace driven mode options - bool trace_driven_mode; - bool trace_skip_first_kernel; - char *g_traces_filename; - friend class gpgpu_sim; }; @@ -588,8 +580,8 @@ class gpgpu_sim : public gpgpu_t { void gpgpu_debug(); + protected: ///// data ///// - class simt_core_cluster **m_cluster; class memory_partition_unit **m_memory_partition_unit; class memory_sub_partition **m_memory_sub_partition; @@ -645,6 +637,9 @@ class gpgpu_sim : public gpgpu_t { void clear_executed_kernel_info(); //< clear the kernel information after // stat printout + virtual void createSIMTCluster() = 0; + void callCreateSIMTCluster(); + public: unsigned long long gpu_sim_insn; unsigned long long gpu_tot_sim_insn; @@ -692,4 +687,14 @@ class gpgpu_sim : public gpgpu_t { } }; +class exec_gpgpu_sim : public gpgpu_sim { + public: + exec_gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx) + : gpgpu_sim(config, ctx) { + createSIMTCluster(); + } + + virtual void createSIMTCluster(); +}; + #endif diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index 7fed99b..ab6e5c2 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -793,10 +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(); - } + if (mf && mf->isatomic()) mf->do_atomic(); if (mf && (mf->get_access_type() == L2_WRBK_ACC || mf->get_access_type() == L1_WRBK_ACC)) { delete mf; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index ee8076d..8efb88b 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -36,7 +36,6 @@ #include "../cuda-sim/ptx-stats.h" #include "../cuda-sim/ptx_sim.h" #include "../statwrapper.h" -#include "../trace-driven/trace_driven.h" #include "addrdec.h" #include "dram.h" #include "gpu-misc.h" @@ -75,27 +74,14 @@ std::list<unsigned> shader_core_ctx::get_regs_written(const inst_t &fvt) const { return result; } -shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, - class simt_core_cluster *cluster, - unsigned shader_id, unsigned tpc_id, - const shader_core_config *config, - const memory_config *mem_config, - shader_core_stats *stats) - : core_t(gpu, NULL, config->warp_size, config->n_thread_per_shader), - m_barriers(this, config->max_warps_per_shader, config->max_cta_per_core, - config->max_barriers_per_cta, config->warp_size), - m_active_warps(0), - m_dynamic_warp_id(0) { - m_cluster = cluster; - m_config = config; - m_memory_config = mem_config; - m_stats = stats; - unsigned warp_size = config->warp_size; - Issue_Prio = 0; - - m_sid = shader_id; - m_tpc = tpc_id; +void exec_shader_core_ctx::create_shd_warp() { + m_warp.resize(m_config->max_warps_per_shader); + for (unsigned k = 0; k < m_config->max_warps_per_shader; ++k) { + m_warp[k] = new shd_warp_t(this, m_config->warp_size); + } +} +void shader_core_ctx::create_front_pipeline() { m_pipeline_reg.reserve(N_PIPELINE_STAGES); for (int j = 0; j < N_PIPELINE_STAGES; j++) { m_pipeline_reg.push_back( @@ -121,14 +107,14 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, m_pipeline_reg[ID_OC_INT].get_size()); } - m_threadState = - (thread_ctx_t *)calloc(sizeof(thread_ctx_t), config->n_thread_per_shader); + m_threadState = (thread_ctx_t *)calloc(sizeof(thread_ctx_t), + m_config->n_thread_per_shader); m_not_completed = 0; m_active_threads.reset(); m_n_active_cta = 0; for (unsigned i = 0; i < MAX_CTA_PER_SHADER; i++) m_cta_status[i] = 0; - for (unsigned i = 0; i < config->n_thread_per_shader; i++) { + for (unsigned i = 0; i < m_config->n_thread_per_shader; i++) { m_thread[i] = NULL; m_threadState[i].m_cta_id = -1; m_threadState[i].m_active = false; @@ -136,12 +122,12 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, // m_icnt = new shader_memory_interface(this,cluster); if (m_config->gpgpu_perfect_mem) { - m_icnt = new perfect_memory_interface(this, cluster); + m_icnt = new perfect_memory_interface(this, m_cluster); } else { - m_icnt = new shader_memory_interface(this, cluster); + m_icnt = new shader_memory_interface(this, m_cluster); } m_mem_fetch_allocator = - new shader_core_mem_fetch_allocator(shader_id, tpc_id, mem_config); + new shader_core_mem_fetch_allocator(m_sid, m_tpc, m_memory_config); // fetch m_last_warp_fetched = 0; @@ -152,16 +138,10 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, m_L1I = new read_only_cache(name, m_config->m_L1I_config, m_sid, get_shader_instruction_cache_id(), m_icnt, IN_L1I_MISS_QUEUE); +} - 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); +void shader_core_ctx::create_schedulers() { + m_scoreboard = new Scoreboard(m_sid, m_config->max_warps_per_shader, m_gpu); // scedulers // must currently occur after all inputs have been initialized. @@ -196,7 +176,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, - config->gpgpu_scheduler_string)); + m_config->gpgpu_scheduler_string)); break; case CONCRETE_SCHEDULER_GTO: schedulers.push_back(new gto_scheduler( @@ -218,7 +198,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, - config->gpgpu_scheduler_string)); + m_config->gpgpu_scheduler_string)); break; default: abort(); @@ -233,9 +213,10 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, for (unsigned i = 0; i < m_config->gpgpu_num_sched_per_core; ++i) { schedulers[i]->done_adding_supervised_warps(); } +} +void shader_core_ctx::create_exec_pipeline() { // op collector configuration - enum { SP_CUS, DP_CUS, SFU_CUS, TENSOR_CORE_CUS, INT_CUS, MEM_CUS, GEN_CUS }; opndcoll_rfu_t::port_vector_t in_ports; @@ -280,8 +261,9 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, 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( - TENSOR_CORE_CUS, config->gpgpu_operand_collector_num_units_tensor_core, - config->gpgpu_operand_collector_num_out_ports_tensor_core); + TENSOR_CORE_CUS, + m_config->gpgpu_operand_collector_num_units_tensor_core, + m_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); @@ -323,7 +305,7 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, } for (unsigned i = 0; - i < config->gpgpu_operand_collector_num_in_ports_tensor_core; i++) { + i < m_config->gpgpu_operand_collector_num_in_ports_tensor_core; i++) { in_ports.push_back(&m_pipeline_reg[ID_OC_TENSOR_CORE]); out_ports.push_back(&m_pipeline_reg[OC_EX_TENSOR_CORE]); cu_sets.push_back((unsigned)TENSOR_CORE_CUS); @@ -388,15 +370,15 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, m_issue_port.push_back(OC_EX_SFU); } - for (int k = 0; k < config->gpgpu_num_tensor_core_units; k++) { + for (int k = 0; k < m_config->gpgpu_num_tensor_core_units; k++) { m_fu.push_back(new tensor_core(&m_pipeline_reg[EX_WB], m_config, this)); 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_ldst_unit = new ldst_unit(m_icnt, m_mem_fetch_allocator, this, + &m_operand_collector, m_scoreboard, m_config, + m_memory_config, m_stats, m_sid, m_tpc); m_fu.push_back(m_ldst_unit); m_dispatch_port.push_back(ID_OC_MEM); m_issue_port.push_back(OC_EX_MEM); @@ -406,10 +388,32 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, m_fu.size() == m_issue_port.size()); // there are as many result buses as the width of the EX_WB stage - num_result_bus = config->pipe_widths[EX_WB]; + num_result_bus = m_config->pipe_widths[EX_WB]; for (unsigned i = 0; i < num_result_bus; i++) { this->m_result_bus.push_back(new std::bitset<MAX_ALU_LATENCY>()); } +} + +shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, + class simt_core_cluster *cluster, + unsigned shader_id, unsigned tpc_id, + const shader_core_config *config, + const memory_config *mem_config, + shader_core_stats *stats) + : core_t(gpu, NULL, config->warp_size, config->n_thread_per_shader), + m_barriers(this, config->max_warps_per_shader, config->max_cta_per_core, + config->max_barriers_per_cta, config->warp_size), + m_active_warps(0), + m_dynamic_warp_id(0) { + m_cluster = cluster; + m_config = config; + m_memory_config = mem_config; + m_stats = stats; + unsigned warp_size = config->warp_size; + Issue_Prio = 0; + + m_sid = shader_id; + m_tpc = tpc_id; m_last_inst_gpu_sim_cycle = 0; m_last_inst_gpu_tot_sim_cycle = 0; @@ -784,18 +788,30 @@ void shader_core_stats::visualizer_print(gzFile visualizer_file) { 0xF0000000 /* should be distinct from other memory spaces... \ check ptx_ir.h to verify this does not overlap \ other memory spaces */ + +const warp_inst_t *exec_shader_core_ctx::get_next_inst(unsigned warp_id, + address_type pc) { + // read the inst from the functional model + return m_gpu->gpgpu_ctx->ptx_fetch_inst(pc); +} + +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); +} + +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(); +} + void shader_core_ctx::decode() { if (m_inst_fetch_buffer.m_valid) { // decode 1 or 2 instructions and place them into ibuffer address_type pc = m_inst_fetch_buffer.m_pc; - const warp_inst_t *pI1; - if (m_gpu->get_config().is_trace_driven_mode()) { - // 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); - } + const warp_inst_t *pI1 = get_next_inst(m_inst_fetch_buffer.m_warp_id, 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(); if (pI1) { @@ -805,14 +821,8 @@ void shader_core_ctx::decode() { } else if (pI1->oprnd_type == FP_OP) { m_stats->m_num_FPdecoded_insn[m_sid]++; } - const warp_inst_t *pI2; - if (m_gpu->get_config().is_trace_driven_mode()) { - // 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); - } + const warp_inst_t *pI2 = + get_next_inst(m_inst_fetch_buffer.m_warp_id, 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(); @@ -864,9 +874,10 @@ void shader_core_ctx::fetch() { unsigned cta_id = m_warp[warp_id]->get_cta_id(); if (m_thread[tid] == NULL) { register_cta_thread_exit(cta_id, m_kernel); - } else + } else { register_cta_thread_exit(cta_id, &(m_thread[tid]->get_kernel())); + } m_not_completed -= 1; m_active_threads.reset(tid); did_exit = true; @@ -929,7 +940,7 @@ void shader_core_ctx::fetch() { m_L1I->cycle(); } -void shader_core_ctx::func_exec_inst(warp_inst_t &inst) { +void exec_shader_core_ctx::func_exec_inst(warp_inst_t &inst) { execute_warp_inst_t(inst); if (inst.is_load() || inst.is_store()) { inst.generate_mem_accesses(); @@ -964,9 +975,7 @@ void shader_core_ctx::issue_warp(register_set &pipe_reg_set, m_warp[warp_id]->set_membar(); } - if (!m_gpu->get_config() - .is_trace_driven_mode()) // No SIMT-stack in trace-driven mode - updateSIMTStack(warp_id, *pipe_reg); + updateSIMTStack(warp_id, *pipe_reg); m_scoreboard->reserveRegisters(*pipe_reg); m_warp[warp_id]->set_next_pc(next_inst->pc + next_inst->isize); @@ -1131,10 +1140,7 @@ void scheduler_unit::cycle() { bool valid = warp(warp_id).ibuffer_next_valid(); 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-driven mode. - else - m_simt_stack[warp_id]->get_pdom_stack_top_info(&pc, &rpc); + m_shader->get_pdom_stack_top_info(warp_id, pI, &pc, &rpc); SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) has valid instruction (%s)\n", (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id(), @@ -1158,12 +1164,8 @@ 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 traces, so - // just read it from the inst const active_mask_t &active_mask = - m_shader->m_gpu->get_config().is_trace_driven_mode() - ? pI->get_active_mask() - : m_simt_stack[warp_id]->get_active_mask(); + m_shader->get_active_mask(warp_id, pI); assert(warp(warp_id).inst_in_pipeline()); @@ -2367,9 +2369,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_next_wb.do_atomic(); m_core->decrement_atomic_count(m_next_wb.warp_id(), m_next_wb.active_count()); } @@ -4010,6 +4010,16 @@ void opndcoll_rfu_t::collector_unit_t::dispatch() { for (unsigned i = 0; i < MAX_REG_OPERANDS * 2; i++) m_src_op[i].reset(); } +void exec_simt_core_cluster::create_shader_core_ctx() { + m_core = new shader_core_ctx *[m_config->n_simt_cores_per_cluster]; + for (unsigned i = 0; i < m_config->n_simt_cores_per_cluster; i++) { + unsigned sid = m_config->cid_to_sid(i, m_cluster_id); + m_core[i] = new exec_shader_core_ctx(m_gpu, this, sid, m_cluster_id, + m_config, m_mem_config, m_stats); + m_core_sim_order.push_back(i); + } +} + simt_core_cluster::simt_core_cluster(class gpgpu_sim *gpu, unsigned cluster_id, const shader_core_config *config, const memory_config *mem_config, @@ -4022,17 +4032,7 @@ simt_core_cluster::simt_core_cluster(class gpgpu_sim *gpu, unsigned cluster_id, m_gpu = gpu; m_stats = stats; m_memory_stats = mstats; - m_core = new shader_core_ctx *[config->n_simt_cores_per_cluster]; - for (unsigned i = 0; i < config->n_simt_cores_per_cluster; i++) { - unsigned sid = m_config->cid_to_sid(i, m_cluster_id); - if (gpu->get_config().is_trace_driven_mode()) - m_core[i] = new trace_shader_core_ctx(gpu, this, sid, m_cluster_id, - config, mem_config, stats); - else - m_core[i] = new shader_core_ctx(gpu, this, sid, m_cluster_id, config, - mem_config, stats); - m_core_sim_order.push_back(i); - } + m_mem_config = mem_config; } void simt_core_cluster::core_cycle() { @@ -4344,8 +4344,9 @@ void simt_core_cluster::get_L1T_sub_stats(struct cache_sub_stats &css) const { css = total_css; } -void shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, - unsigned t, unsigned tid) { +void exec_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.space.is_local() && (inst.is_load() || inst.is_store())) { new_addr_type localaddrs[MAX_ACCESSES_PER_INSN_PER_THREAD]; diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 8e29a78..d77207d 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -237,9 +237,6 @@ 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; @@ -1537,12 +1534,6 @@ class shader_core_config : public core_config { bool perfect_inst_const_cache; unsigned inst_fetch_throughput; unsigned reg_file_port_throughput; - - char *trace_opcode_latency_initiation_int; - char *trace_opcode_latency_initiation_sp; - char *trace_opcode_latency_initiation_dp; - char *trace_opcode_latency_initiation_sfu; - char *trace_opcode_latency_initiation_tensor; }; struct shader_core_stats_pod { @@ -2052,7 +2043,7 @@ class shader_core_ctx : public core_t { } bool check_if_non_released_reduction_barrier(warp_inst_t &inst); - private: + protected: unsigned inactive_lanes_accesses_sfu(unsigned active_count, double latency) { return (((32 - active_count) >> 1) * latency) + (((32 - active_count) >> 3) * latency) + @@ -2064,11 +2055,6 @@ class shader_core_ctx : public core_t { } int test_res_bus(int latency); - 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; void fetch(); void register_cta_thread_exit(unsigned cta_num, kernel_info_t *kernel); @@ -2082,7 +2068,35 @@ class shader_core_ctx : public core_t { void issue_warp(register_set &warp, const warp_inst_t *pI, const active_mask_t &active_mask, unsigned warp_id, unsigned sch_id); - virtual void func_exec_inst(warp_inst_t &inst); + + void create_front_pipeline(); + void create_schedulers(); + void create_exec_pipeline(); + + // pure virtual methods implemented based on the current execution mode + // (execution-driven vs trace-driven) + 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) = 0; + virtual void func_exec_inst(warp_inst_t &inst) = 0; + + virtual unsigned sim_init_thread(kernel_info_t &kernel, + ptx_thread_info **thread_info, int sid, + unsigned tid, unsigned threads_left, + unsigned num_threads, core_t *core, + unsigned hw_cta_id, unsigned hw_warp_id, + gpgpu_t *gpu) = 0; + + virtual void create_shd_warp() = 0; + + virtual const warp_inst_t *get_next_inst(unsigned warp_id, + address_type pc) = 0; + virtual void get_pdom_stack_top_info(unsigned warp_id, const warp_inst_t *pI, + unsigned *pc, unsigned *rpc) = 0; + virtual const active_mask_t &get_active_mask(unsigned warp_id, + const warp_inst_t *pI) = 0; // Returns numbers of addresses in translated_addrs unsigned translate_local_memaddr(address_type localaddr, unsigned tid, @@ -2098,6 +2112,7 @@ class shader_core_ctx : public core_t { // used in display_pipeline(): void dump_warp_state(FILE *fout) const; void print_stage(unsigned int stage, FILE *fout) const; + unsigned long long m_last_inst_gpu_sim_cycle; unsigned long long m_last_inst_gpu_tot_sim_cycle; @@ -2180,9 +2195,38 @@ class shader_core_ctx : public core_t { unsigned int m_occupied_ctas; std::bitset<MAX_THREAD_PER_SM> m_occupied_hwtid; 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 exec_shader_core_ctx : public shader_core_ctx { + public: + exec_shader_core_ctx(class gpgpu_sim *gpu, class simt_core_cluster *cluster, + unsigned shader_id, unsigned tpc_id, + const shader_core_config *config, + const memory_config *mem_config, + shader_core_stats *stats) + : shader_core_ctx(gpu, cluster, shader_id, tpc_id, config, mem_config, + stats) { + create_front_pipeline(); + create_shd_warp(); + create_schedulers(); + create_exec_pipeline(); + } + + virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, + unsigned tid); + virtual void func_exec_inst(warp_inst_t &inst); + virtual unsigned sim_init_thread(kernel_info_t &kernel, + ptx_thread_info **thread_info, int sid, + unsigned tid, unsigned threads_left, + unsigned num_threads, core_t *core, + unsigned hw_cta_id, unsigned hw_warp_id, + gpgpu_t *gpu); + virtual void create_shd_warp(); + virtual const warp_inst_t *get_next_inst(unsigned warp_id, address_type pc); + virtual void get_pdom_stack_top_info(unsigned warp_id, const warp_inst_t *pI, + unsigned *pc, unsigned *rpc); + virtual const active_mask_t &get_active_mask(unsigned warp_id, + const warp_inst_t *pI); }; class simt_core_cluster { @@ -2232,20 +2276,36 @@ class simt_core_cluster { void get_icnt_stats(long &n_simt_to_mem, long &n_mem_to_simt) const; float get_current_occupancy(unsigned long long &active, unsigned long long &total) const; + virtual void create_shader_core_ctx() = 0; - private: + protected: unsigned m_cluster_id; gpgpu_sim *m_gpu; const shader_core_config *m_config; shader_core_stats *m_stats; memory_stats_t *m_memory_stats; shader_core_ctx **m_core; + const memory_config *m_mem_config; unsigned m_cta_issue_next_core; std::list<unsigned> m_core_sim_order; std::list<mem_fetch *> m_response_fifo; }; +class exec_simt_core_cluster : public simt_core_cluster { + public: + exec_simt_core_cluster(class gpgpu_sim *gpu, unsigned cluster_id, + const shader_core_config *config, + const memory_config *mem_config, + class shader_core_stats *stats, + class memory_stats_t *mstats) + : simt_core_cluster(gpu, cluster_id, config, mem_config, stats, mstats) { + create_shader_core_ctx(); + } + + virtual void create_shader_core_ctx(); +}; + class shader_memory_interface : public mem_fetch_interface { public: shader_memory_interface(shader_core_ctx *core, simt_core_cluster *cluster) { diff --git a/src/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc index 6ec3867..f4287d8 100644 --- a/src/gpgpusim_entrypoint.cc +++ b/src/gpgpusim_entrypoint.cc @@ -219,7 +219,7 @@ gpgpu_sim *gpgpu_context::gpgpu_ptx_sim_init_perf() { the_gpgpusim->g_the_gpu_config->init(); the_gpgpusim->g_the_gpu = - new gpgpu_sim(*(the_gpgpusim->g_the_gpu_config), this); + new exec_gpgpu_sim(*(the_gpgpusim->g_the_gpu_config), this); the_gpgpusim->g_stream_manager = new stream_manager( (the_gpgpusim->g_the_gpu), func_sim->g_cuda_launch_blocking); @@ -232,41 +232,6 @@ gpgpu_sim *gpgpu_context::gpgpu_ptx_sim_init_perf() { return the_gpgpusim->g_the_gpu; } -gpgpu_sim *gpgpu_context::gpgpu_trace_sim_init_perf(int argc, - const char *argv[]) { - srand(1); - print_splash(); - func_sim->read_sim_environment_variables(); - ptx_parser->read_parser_environment_variables(); - option_parser_t opp = option_parser_create(); - - ptx_reg_options(opp); - func_sim->ptx_opcocde_latency_options(opp); - - icnt_reg_options(opp); - the_gpgpusim->g_the_gpu_config = new gpgpu_sim_config(this); - the_gpgpusim->g_the_gpu_config->reg_options( - opp); // register GPU microrachitecture options - - option_parser_cmdline(opp, argc, argv); // parse configuration options - fprintf(stdout, "GPGPU-Sim: Configuration options:\n\n"); - option_parser_print(opp, stdout); - // Set the Numeric locale to a standard locale where a decimal point is a - // "dot" not a "comma" so it does the parsing correctly independent of the - // system environment variables - assert(setlocale(LC_NUMERIC, "C")); - the_gpgpusim->g_the_gpu_config->init(); - - the_gpgpusim->g_the_gpu = - new gpgpu_sim(*(the_gpgpusim->g_the_gpu_config), this); - the_gpgpusim->g_stream_manager = new stream_manager( - (the_gpgpusim->g_the_gpu), func_sim->g_cuda_launch_blocking); - - the_gpgpusim->g_simulation_starttime = time((time_t *)NULL); - - return the_gpgpusim->g_the_gpu; -} - void gpgpu_context::start_sim_thread(int api) { if (the_gpgpusim->g_sim_done) { the_gpgpusim->g_sim_done = false; diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 4a5f14a..f12d39a 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -14,6 +14,7 @@ #include "../abstract_hardware_model.h" #include "../cuda-sim/cuda-sim.h" #include "../gpgpu-sim/gpu-sim.h" +#include "../gpgpu-sim/icnt_wrapper.h" #include "../gpgpusim_entrypoint.h" #include "../option_parser.h" #include "ISA_Def/trace_opcode.h" @@ -32,11 +33,16 @@ * index info in the traces header) 5- Get rid off traces intermediate files - * change the tracer */ +gpgpu_sim* gpgpu_trace_sim_init_perf_model(int argc, const char* argv[], + gpgpu_context* m_gpgpu_context, + class trace_config* m_config); int main(int argc, const char** argv) { gpgpu_context* m_gpgpu_context = new gpgpu_context(); + trace_config tconfig; + gpgpu_sim* m_gpgpu_sim = - m_gpgpu_context->gpgpu_trace_sim_init_perf(argc, argv); + gpgpu_trace_sim_init_perf_model(argc, argv, m_gpgpu_context, &tconfig); m_gpgpu_sim->init(); // for each kernel @@ -46,12 +52,11 @@ int main(int argc, const char** argv) { // while loop till the end of the end kernel execution // prints stats - trace_parser tracer(m_gpgpu_sim->get_config().get_traces_filename(), - m_gpgpu_sim, m_gpgpu_context); - trace_config config(m_gpgpu_sim); + trace_parser tracer(tconfig.get_traces_filename(), m_gpgpu_sim, + m_gpgpu_context); + tconfig.parse_config(); std::vector<std::string> commandlist = tracer.parse_kernellist_file(); - bool first_kernel = true; for (unsigned i = 0; i < commandlist.size(); ++i) { trace_kernel_info_t* kernel_info = NULL; @@ -62,12 +67,7 @@ int main(int argc, const char** argv) { m_gpgpu_sim->perf_memcpy_to_gpu(addre, Bcount); continue; } else { - // skip the first unimportant initialization kernel - if (m_gpgpu_sim->get_config().is_skip_first_kernel() && first_kernel) { - first_kernel = false; - continue; - } - kernel_info = tracer.parse_kernel_info(commandlist[i], &config); + kernel_info = tracer.parse_kernel_info(commandlist[i], &tconfig); m_gpgpu_sim->launch(kernel_info); } @@ -121,3 +121,43 @@ int main(int argc, const char** argv) { return 1; } + +gpgpu_sim* gpgpu_trace_sim_init_perf_model(int argc, const char* argv[], + gpgpu_context* m_gpgpu_context, + trace_config* m_config) { + srand(1); + print_splash(); + + option_parser_t opp = option_parser_create(); + + m_gpgpu_context->ptx_reg_options(opp); + m_gpgpu_context->func_sim->ptx_opcocde_latency_options(opp); + + icnt_reg_options(opp); + + m_gpgpu_context->the_gpgpusim->g_the_gpu_config = + new gpgpu_sim_config(m_gpgpu_context); + m_gpgpu_context->the_gpgpusim->g_the_gpu_config->reg_options( + opp); // register GPU microrachitecture options + m_config->reg_options(opp); + + option_parser_cmdline(opp, argc, argv); // parse configuration options + fprintf(stdout, "GPGPU-Sim: Configuration options:\n\n"); + option_parser_print(opp, stdout); + // Set the Numeric locale to a standard locale where a decimal point is a + // "dot" not a "comma" so it does the parsing correctly independent of the + // system environment variables + assert(setlocale(LC_NUMERIC, "C")); + m_gpgpu_context->the_gpgpusim->g_the_gpu_config->init(); + + m_gpgpu_context->the_gpgpusim->g_the_gpu = new trace_gpgpu_sim( + *(m_gpgpu_context->the_gpgpusim->g_the_gpu_config), m_gpgpu_context); + + m_gpgpu_context->the_gpgpusim->g_stream_manager = + new stream_manager((m_gpgpu_context->the_gpgpusim->g_the_gpu), + m_gpgpu_context->func_sim->g_cuda_launch_blocking); + + m_gpgpu_context->the_gpgpusim->g_simulation_starttime = time((time_t*)NULL); + + return m_gpgpu_context->the_gpgpusim->g_the_gpu; +} diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 8fa63b4..d42ee65 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -575,25 +575,48 @@ bool trace_warp_inst_t::parse_from_string( return true; } -trace_config::trace_config(gpgpu_sim* m_gpgpu_sim) { - this->m_gpgpu_sim = m_gpgpu_sim; - parse_config(); +trace_config::trace_config() {} + +void trace_config::reg_options(option_parser_t opp) { + option_parser_register(opp, "-trace", OPT_CSTR, &g_traces_filename, + "traces kernel file" + "traces kernel file directory", + "./traces/kernelslist.g"); + + option_parser_register(opp, "-trace_opcode_latency_initiation_int", OPT_CSTR, + &trace_opcode_latency_initiation_int, + "Opcode latencies and initiation for integers in " + "trace driven mode <latency,initiation>", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_sp", OPT_CSTR, + &trace_opcode_latency_initiation_sp, + "Opcode latencies and initiation for sp in trace " + "driven mode <latency,initiation>", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_dp", OPT_CSTR, + &trace_opcode_latency_initiation_dp, + "Opcode latencies and initiation for dp in trace " + "driven mode <latency,initiation>", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_sfu", OPT_CSTR, + &trace_opcode_latency_initiation_sfu, + "Opcode latencies and initiation for sfu in trace " + "driven mode <latency,initiation>", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_tensor", + OPT_CSTR, &trace_opcode_latency_initiation_tensor, + "Opcode latencies and initiation for tensor in trace " + "driven mode <latency,initiation>", + "4,1"); } void trace_config::parse_config() { - sscanf( - m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_int, - "%u,%u", &int_latency, &int_init); - sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_sp, - "%u,%u", &fp_latency, &fp_init); - sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_dp, - "%u,%u", &dp_latency, &dp_init); - sscanf( - m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_sfu, - "%u,%u", &sfu_latency, &sfu_init); - sscanf(m_gpgpu_sim->getShaderCoreConfig() - ->trace_opcode_latency_initiation_tensor, - "%u,%u", &tensor_latency, &tensor_init); + sscanf(trace_opcode_latency_initiation_int, "%u,%u", &int_latency, &int_init); + sscanf(trace_opcode_latency_initiation_sp, "%u,%u", &fp_latency, &fp_init); + sscanf(trace_opcode_latency_initiation_dp, "%u,%u", &dp_latency, &dp_init); + sscanf(trace_opcode_latency_initiation_sfu, "%u,%u", &sfu_latency, &sfu_init); + sscanf(trace_opcode_latency_initiation_tensor, "%u,%u", &tensor_latency, + &tensor_init); } void trace_config::set_latency(unsigned category, unsigned& latency, unsigned& initiation_interval) { @@ -629,6 +652,64 @@ void trace_config::set_latency(unsigned category, unsigned& latency, } } +void trace_gpgpu_sim::createSIMTCluster() { + m_cluster = new simt_core_cluster*[m_shader_config->n_simt_clusters]; + for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++) + m_cluster[i] = + new trace_simt_core_cluster(this, i, m_shader_config, m_memory_config, + m_shader_stats, m_memory_stats); +} + +void trace_simt_core_cluster::create_shader_core_ctx() { + m_core = new shader_core_ctx*[m_config->n_simt_cores_per_cluster]; + for (unsigned i = 0; i < m_config->n_simt_cores_per_cluster; i++) { + unsigned sid = m_config->cid_to_sid(i, m_cluster_id); + m_core[i] = new trace_shader_core_ctx(m_gpu, this, sid, m_cluster_id, + m_config, m_mem_config, m_stats); + m_core_sim_order.push_back(i); + } +} + +void trace_shader_core_ctx::create_shd_warp() { + m_warp.resize(m_config->max_warps_per_shader); + for (unsigned k = 0; k < m_config->max_warps_per_shader; ++k) { + m_warp[k] = new trace_shd_warp_t(this, m_config->warp_size); + } +} + +void trace_shader_core_ctx::get_pdom_stack_top_info(unsigned warp_id, + const warp_inst_t* pI, + unsigned* pc, + unsigned* rpc) { + // In trace-driven mode, we assume no control hazard + *pc = pI->pc; + *rpc = pI->pc; +} + +const active_mask_t& trace_shader_core_ctx::get_active_mask( + unsigned warp_id, const warp_inst_t* pI) { + // For Trace-driven, the active mask already set in traces, so + // just read it from the inst + return pI->get_active_mask(); +} + +unsigned trace_shader_core_ctx::sim_init_thread( + kernel_info_t& kernel, ptx_thread_info** thread_info, int sid, unsigned tid, + unsigned threads_left, unsigned num_threads, core_t* core, + unsigned hw_cta_id, unsigned hw_warp_id, gpgpu_t* gpu) { + 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 trace_shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread, unsigned end_thread, unsigned ctaid, int cta_size, kernel_info_t& kernel) { @@ -644,6 +725,19 @@ void trace_shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread, init_traces(start_warp, end_warp, kernel); } +const warp_inst_t* trace_shader_core_ctx::get_next_inst(unsigned warp_id, + address_type pc) { + // read the inst from the traces + trace_shd_warp_t* m_trace_warp = + static_cast<trace_shd_warp_t*>(m_warp[warp_id]); + return m_trace_warp->get_next_trace_inst(); +} + +void trace_shader_core_ctx::updateSIMTStack(unsigned warpId, + warp_inst_t* inst) { + // No SIMT-stack in trace-driven mode +} + 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; diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index a35cd83..ea315a1 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -36,6 +36,7 @@ class trace_warp_inst_t : public warp_inst_t { m_gpgpu_context = NULL; m_opcode = 0; m_tconfig = NULL; + should_do_atomic = false; } trace_warp_inst_t(const class core_config* config, @@ -44,6 +45,7 @@ class trace_warp_inst_t : public warp_inst_t { m_gpgpu_context = gpgpu_context; m_opcode = 0; m_tconfig = tconfig; + should_do_atomic = false; } bool parse_from_string( @@ -80,16 +82,24 @@ class trace_kernel_info_t : public kernel_info_t { class trace_config { public: - trace_config(gpgpu_sim* m_gpgpu_sim); + trace_config(); void set_latency(unsigned category, unsigned& latency, unsigned& initiation_interval); void parse_config(); + void reg_options(option_parser_t opp); + char* get_traces_filename() { return g_traces_filename; } private: unsigned int_latency, fp_latency, dp_latency, sfu_latency, tensor_latency; unsigned int_init, fp_init, dp_init, sfu_init, tensor_init; - gpgpu_sim* m_gpgpu_sim; + + char* g_traces_filename; + char* trace_opcode_latency_initiation_int; + char* trace_opcode_latency_initiation_sp; + char* trace_opcode_latency_initiation_dp; + char* trace_opcode_latency_initiation_sfu; + char* trace_opcode_latency_initiation_tensor; }; class trace_parser { @@ -130,6 +140,30 @@ class trace_shd_warp_t : public shd_warp_t { unsigned trace_pc; }; +class trace_gpgpu_sim : public gpgpu_sim { + public: + trace_gpgpu_sim(const gpgpu_sim_config& config, gpgpu_context* ctx) + : gpgpu_sim(config, ctx) { + createSIMTCluster(); + } + + virtual void createSIMTCluster(); +}; + +class trace_simt_core_cluster : public simt_core_cluster { + public: + trace_simt_core_cluster(class gpgpu_sim* gpu, unsigned cluster_id, + const shader_core_config* config, + const memory_config* mem_config, + class shader_core_stats* stats, + class memory_stats_t* mstats) + : simt_core_cluster(gpu, cluster_id, config, mem_config, stats, mstats) { + create_shader_core_ctx(); + } + + virtual void create_shader_core_ctx(); +}; + class trace_shader_core_ctx : public shader_core_ctx { public: trace_shader_core_ctx(class gpgpu_sim* gpu, class simt_core_cluster* cluster, @@ -138,7 +172,12 @@ 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) {} + stats) { + create_front_pipeline(); + create_shd_warp(); + create_schedulers(); + create_exec_pipeline(); + } virtual void checkExecutionStatusAndUpdate(warp_inst_t& inst, unsigned t, unsigned tid); @@ -146,7 +185,19 @@ class trace_shader_core_ctx : public shader_core_ctx { 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; + virtual unsigned sim_init_thread(kernel_info_t& kernel, + ptx_thread_info** thread_info, int sid, + unsigned tid, unsigned threads_left, + unsigned num_threads, core_t* core, + unsigned hw_cta_id, unsigned hw_warp_id, + gpgpu_t* gpu); + virtual void create_shd_warp(); + virtual const warp_inst_t* get_next_inst(unsigned warp_id, address_type pc); + virtual void updateSIMTStack(unsigned warpId, warp_inst_t* inst); + virtual void get_pdom_stack_top_info(unsigned warp_id, const warp_inst_t* pI, + unsigned* pc, unsigned* rpc); + virtual const active_mask_t& get_active_mask(unsigned warp_id, + const warp_inst_t* pI); private: void init_traces(unsigned start_warp, unsigned end_warp, |
