summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libcuda/gpgpu_context.h1
-rw-r--r--src/abstract_hardware_model.cc1
-rw-r--r--src/abstract_hardware_model.h4
-rw-r--r--src/gpgpu-sim/gpu-sim.cc82
-rw-r--r--src/gpgpu-sim/gpu-sim.h23
-rw-r--r--src/gpgpu-sim/l2cache.cc5
-rw-r--r--src/gpgpu-sim/shader.cc187
-rw-r--r--src/gpgpu-sim/shader.h98
-rw-r--r--src/gpgpusim_entrypoint.cc37
-rw-r--r--src/trace-driven/gpgpusim_trace_driven_main.cc62
-rw-r--r--src/trace-driven/trace_driven.cc126
-rw-r--r--src/trace-driven/trace_driven.h59
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,
&reg_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,