summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gpgpu-sim/gpu-sim.cc26
-rw-r--r--src/gpgpu-sim/l2cache.cc1
-rw-r--r--src/gpgpu-sim/shader.cc152
-rw-r--r--src/gpgpu-sim/shader.h31
-rw-r--r--src/trace-driven/ISA_Def/trace_opcode.h1
-rw-r--r--src/trace-driven/trace_driven.cc46
-rw-r--r--src/trace-driven/trace_driven.h26
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