summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMahmoud <[email protected]>2019-09-19 22:06:15 -0400
committerMahmoud <[email protected]>2019-09-19 22:06:15 -0400
commit5db69b3e5b058c030075c066db64922bf1e6af02 (patch)
tree1de5df881f370ee4e74796c02acf5c0772ff436f
parentde903552c8d716e6b2bd6d0c816063523e35c6c5 (diff)
support trace-driven and changing the shader.cc
-rw-r--r--Makefile10
-rw-r--r--src/abstract_hardware_model.cc7
-rw-r--r--src/gpgpu-sim/gpu-sim.cc10
-rw-r--r--src/gpgpu-sim/mem_latency_stat.cc5
-rw-r--r--src/gpgpu-sim/shader.cc166
-rw-r--r--src/gpgpu-sim/shader.h7
-rw-r--r--src/trace-driven/gpgpusim_trace_driven_main.cc253
-rw-r--r--src/trace-driven/trace_driven.h53
-rw-r--r--src/trace-driven/trace_opcode.h3
9 files changed, 384 insertions, 130 deletions
diff --git a/Makefile b/Makefile
index 5cd3101..73f22c6 100644
--- a/Makefile
+++ b/Makefile
@@ -171,7 +171,15 @@ $(SIM_LIB_DIR)/libcudart.so: makedirs $(LIBS) cudalib
$(SIM_LIB_DIR)/gpgpusim.out: makedirs $(LIBS) cudalib $(SIM_LIB_DIR)/libcudart.so
- g++ -std=c++0x -L$(SIM_LIB_DIR) -I$(CUDA_INSTALL_PATH)/include -lcudart -o $(SIM_LIB_DIR)/gpgpusim.out src/trace-driven/gpgpusim_trace_driven_main.cc
+ ar rvs $(SIM_LIB_DIR)/libcudart_static.a\
+ $(SIM_OBJ_FILES_DIR)/libcuda/*.o \
+ $(SIM_OBJ_FILES_DIR)/cuda-sim/*.o \
+ $(SIM_OBJ_FILES_DIR)/cuda-sim/decuda_pred_table/*.o \
+ $(SIM_OBJ_FILES_DIR)/gpgpu-sim/*.o \
+ $(SIM_OBJ_FILES_DIR)/$(INTERSIM)/*.o \
+ $(SIM_OBJ_FILES_DIR)/*.o \
+ $(MCPAT)
+ g++ -std=c++0x -L$(SIM_LIB_DIR) -I$(CUDA_INSTALL_PATH)/include -lcudart -lm -lz -lGL -pthread -o $(SIM_LIB_DIR)/gpgpusim.out src/trace-driven/gpgpusim_trace_driven_main.cc
$(SIM_LIB_DIR)/libcudart.dylib: makedirs $(LIBS) cudalib
g++ -dynamiclib -Wl,-headerpad_max_install_names,-undefined,dynamic_lookup,-compatibility_version,1.1,-current_version,1.1\
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index e8e4b51..063aa8d 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -471,7 +471,8 @@ void warp_inst_t::generate_mem_accesses()
}
if ( space.get_type() == global_space ) {
- m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_uncoalesced_gmem( pc, m_accessq.size() - starting_queue_size );
+ //TO DO: check here
+ // m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_uncoalesced_gmem( pc, m_accessq.size() - starting_queue_size );
}
m_mem_accesses_created=true;
}
@@ -706,7 +707,9 @@ void warp_inst_t::completed( unsigned long long cycle ) const
{
unsigned long long latency = cycle - issue_cycle;
assert(latency <= cycle); // underflow detection
- m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_latency(pc, latency * active_count());
+ //check the trace mode here
+ //TO DO
+ //m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_latency(pc, latency * active_count());
}
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index a70185e..ed96d42 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -66,6 +66,7 @@
#include "stats.h"
#include "../cuda-sim/cuda_device_runtime.h"
#include "../../libcuda/gpgpu_context.h"
+#include "../trace-driven/trace_driven.h"
#ifdef GPGPUSIM_POWER_MODEL
#include "power_interface.h"
@@ -1482,7 +1483,12 @@ 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;
- 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());
+ 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);
+ }
+ 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());
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 && ctaid >= m_gpu->resume_CTA && ctaid < m_gpu->checkpoint_CTA_t )
@@ -1512,7 +1518,7 @@ void shader_core_ctx::issue_block2core( kernel_info_t &kernel )
m_barriers.allocate_barrier(free_cta_hw_id,warps);
// initialize the SIMT stacks and fetch hardware
- init_warps( free_cta_hw_id, start_thread, end_thread, ctaid, cta_size, kernel.get_uid());
+ init_warps( free_cta_hw_id, start_thread, end_thread, ctaid, cta_size, kernel);
m_n_active_cta++;
shader_CTA_count_log(m_sid, 1);
diff --git a/src/gpgpu-sim/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc
index a1b43a8..1980a3b 100644
--- a/src/gpgpu-sim/mem_latency_stat.cc
+++ b/src/gpgpu-sim/mem_latency_stat.cc
@@ -195,8 +195,9 @@ void memory_stats_t::memlatstat_dram_access(mem_fetch *mf)
}
mem_access_type_stats[mf->get_access_type()][dram_id][bank]++;
}
- if (mf->get_pc() != (unsigned)-1)
- m_gpu->gpgpu_ctx->stats->ptx_file_line_stats_add_dram_traffic(mf->get_pc(), mf->get_data_size());
+ //TO DO: check here
+ //if (mf->get_pc() != (unsigned)-1)
+ // m_gpu->gpgpu_ctx->stats->ptx_file_line_stats_add_dram_traffic(mf->get_pc(), mf->get_data_size());
}
void memory_stats_t::memlatstat_icnt2mem_pop(mem_fetch *mf)
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 86508f6..8dddc36 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -46,6 +46,7 @@
#include "traffic_breakdown.h"
#include "shader_trace.h"
#include "../../libcuda/gpgpu_context.h"
+#include "../trace-driven/trace_driven.h"
#define PRIORITIZE_MSHR_OVER_WB 1
#define MAX(a,b) (((a)>(b))?(a):(b))
@@ -453,9 +454,11 @@ void shader_core_ctx::reinit(unsigned start_thread, unsigned end_thread, bool re
}
}
-void shader_core_ctx::init_warps( unsigned cta_id, unsigned start_thread, unsigned end_thread, unsigned ctaid, int cta_size, unsigned kernel_id )
+void shader_core_ctx::init_warps( unsigned cta_id, unsigned start_thread, unsigned end_thread, unsigned ctaid, int cta_size, kernel_info_t &kernel )
{
+ //
address_type start_pc = next_pc(start_thread);
+ unsigned kernel_id = kernel.get_uid();
if (m_config->model == POST_DOMINATOR) {
unsigned start_warp = start_thread / m_config->warp_size;
unsigned warp_per_cta = cta_size / m_config->warp_size;
@@ -482,8 +485,10 @@ void shader_core_ctx::init_warps( unsigned cta_id, unsigned start_thread, unsign
m_simt_stack[i]->resume(fname);
m_simt_stack[i]->get_pdom_stack_top_info(&pc,&rpc);
for (unsigned t = 0; t < m_config->warp_size; t++) {
- m_thread[i * m_config->warp_size + t]->set_npc(pc);
- m_thread[i * m_config->warp_size + t]->update_pc();
+ if(m_thread != NULL) {
+ m_thread[i * m_config->warp_size + t]->set_npc(pc);
+ m_thread[i * m_config->warp_size + t]->update_pc();
+ }
}
start_pc=pc;
}
@@ -493,6 +498,11 @@ void shader_core_ctx::init_warps( unsigned cta_id, unsigned start_thread, unsign
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 );
+ }
}
}
@@ -741,33 +751,45 @@ void shader_core_stats::visualizer_print( gzFile visualizer_file )
other memory spaces */
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 = 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();
- if( pI1 ) {
- m_stats->m_num_decoded_insn[m_sid]++;
- if(pI1->oprnd_type==INT_OP){
- m_stats->m_num_INTdecoded_insn[m_sid]++;
- }else if(pI1->oprnd_type==FP_OP) {
- m_stats->m_num_FPdecoded_insn[m_sid]++;
- }
- const warp_inst_t* 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_stats->m_num_decoded_insn[m_sid]++;
- if(pI2->oprnd_type==INT_OP){
- m_stats->m_num_INTdecoded_insn[m_sid]++;
- }else if(pI2->oprnd_type==FP_OP) {
- m_stats->m_num_FPdecoded_insn[m_sid]++;
- }
- }
- }
- m_inst_fetch_buffer.m_valid = false;
- }
+ 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()){
+ 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
+ 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();
+ if( pI1 ) {
+ m_stats->m_num_decoded_insn[m_sid]++;
+ if(pI1->oprnd_type==INT_OP){
+ m_stats->m_num_INTdecoded_insn[m_sid]++;
+ }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()){
+ 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
+ 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_stats->m_num_decoded_insn[m_sid]++;
+ if(pI2->oprnd_type==INT_OP){
+ m_stats->m_num_INTdecoded_insn[m_sid]++;
+ }else if(pI2->oprnd_type==FP_OP) {
+ m_stats->m_num_FPdecoded_insn[m_sid]++;
+ }
+ }
+ }
+ m_inst_fetch_buffer.m_valid = false;
+ }
}
void shader_core_ctx::fetch()
@@ -778,7 +800,12 @@ void shader_core_ctx::fetch()
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());
- assert( m_warp[mf->get_wid()].get_pc() == (mf->get_addr()-PROGRAM_MEM_START)); // Verify that we got the instruction we were expecting.
+ 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_inst_fetch_buffer.m_valid = true;
m_warp[mf->get_wid()].set_last_fetch(m_gpu->gpu_sim_cycle);
delete mf;
@@ -797,10 +824,14 @@ void shader_core_ctx::fetch()
if( m_threadState[tid].m_active == true ) {
m_threadState[tid].m_active = false;
unsigned cta_id = m_warp[warp_id].get_cta_id();
- register_cta_thread_exit(cta_id, &(m_thread[tid]->get_kernel()));
+ if(m_gpu->get_config().is_trace_driven_mode()) {
+ 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);
- assert( m_thread[tid]!= NULL );
+ if(!m_gpu->get_config().is_trace_driven_mode()) assert( m_thread[tid]!= NULL );
did_exit=true;
}
}
@@ -812,9 +843,15 @@ void shader_core_ctx::fetch()
// this code fetches instructions from the i-cache or generates memory requests
if( !m_warp[warp_id].functional_done() && !m_warp[warp_id].imiss_pending() && m_warp[warp_id].ibuffer_empty() ) {
- address_type pc = m_warp[warp_id].get_pc();
+ 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();
address_type ppc = pc + PROGRAM_MEM_START;
- unsigned nbytes=16;
+ unsigned nbytes= m_gpu->get_config().is_trace_driven_mode()? 32 : 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() )
nbytes = (m_config->m_L1I_config.get_line_sz()-offset_in_block);
@@ -869,25 +906,29 @@ void shader_core_ctx::func_exec_inst( warp_inst_t &inst )
void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t* next_inst, const active_mask_t &active_mask, unsigned warp_id, unsigned sch_id )
{
warp_inst_t** pipe_reg = pipe_reg_set.get_free(m_config->sub_core_model, sch_id);
- assert(pipe_reg);
+ assert(pipe_reg);
- 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(), 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,const_cast<warp_inst_t*> (next_inst));
+ 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(), sch_id ); // dynamic instruction information
+ m_stats->shader_cycle_distro[2+(*pipe_reg)->active_count()]++;
+ func_exec_inst( **pipe_reg );
- }else if( next_inst->op == MEMORY_BARRIER_OP ){
- m_warp[warp_id].set_membar();
- }
+ if( next_inst->op == BARRIER_OP ){
+ m_warp[warp_id].store_info_of_last_inst_at_barrier(*pipe_reg);
+ m_barriers.warp_reaches_barrier(m_warp[warp_id].get_cta_id(),warp_id,const_cast<warp_inst_t*> (next_inst));
+
+ }else if( next_inst->op == MEMORY_BARRIER_OP ){
+ 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);
+
+ m_scoreboard->reserveRegisters(*pipe_reg);
+ m_warp[warp_id].set_next_pc(next_inst->pc + next_inst->isize);
- updateSIMTStack(warp_id,*pipe_reg);
- m_scoreboard->reserveRegisters(*pipe_reg);
- m_warp[warp_id].set_next_pc(next_inst->pc + next_inst->isize);
}
void shader_core_ctx::issue(){
@@ -1034,7 +1075,11 @@ void scheduler_unit::cycle()
bool valid = warp(warp_id).ibuffer_next_valid();
bool warp_inst_issued = false;
unsigned pc,rpc;
- m_simt_stack[warp_id]->get_pdom_stack_top_info(&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
+ else
+ m_simt_stack[warp_id]->get_pdom_stack_top_info(&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(),
m_shader->m_config->gpgpu_ctx->func_sim->ptx_get_insn_str( pc).c_str() );
@@ -1052,7 +1097,11 @@ void scheduler_unit::cycle()
SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) passes scoreboard\n",
(*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id() );
ready_inst = true;
- const active_mask_t &active_mask = m_simt_stack[warp_id]->get_active_mask();
+
+ //For Trace-driven, the active mask already set in from 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();
+
assert( warp(warp_id).inst_in_pipeline() );
if ( (pI->op == LOAD_OP) || (pI->op == STORE_OP) || (pI->op == MEMORY_BARRIER_OP)||(pI->op==TENSOR_CORE_LOAD_OP)||(pI->op==TENSOR_CORE_STORE_OP) ) {
@@ -3241,6 +3290,10 @@ void barrier_set_t::deallocate_barrier( unsigned cta_id )
warp_set_t at_barrier = warps & m_warp_at_barrier;
assert( at_barrier.any() == false ); // no warps stuck at barrier
warp_set_t active = warps & m_warp_active;
+ std::cout<<active<<std::endl;
+ std::cout<<warps<<std::endl;
+ std::cout<<m_warp_active<<std::endl;
+
assert( active.any() == false ); // no warps in CTA still running
m_warp_active &= ~warps;
m_warp_at_barrier &= ~warps;
@@ -3839,7 +3892,10 @@ simt_core_cluster::simt_core_cluster( class gpgpu_sim *gpu,
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);
- m_core[i] = new shader_core_ctx(gpu,this,sid,m_cluster_id,config,mem_config,stats);
+ 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);
}
}
@@ -4158,3 +4214,5 @@ void shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned
}
}
+
+
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index 667cb2d..ae88b7d 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -1947,7 +1947,7 @@ public:
}
int test_res_bus(int latency);
- void init_warps(unsigned cta_id, unsigned start_thread, unsigned end_thread,unsigned ctaid, int cta_size, unsigned kernel_id);
+ 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();
@@ -1960,7 +1960,7 @@ public:
friend class TwoLevelScheduler;
friend class LooseRoundRobbinScheduler;
void issue_warp( register_set& warp, const warp_inst_t *pI, const active_mask_t &active_mask, unsigned warp_id, unsigned sch_id );
- void func_exec_inst( warp_inst_t &inst );
+ virtual void func_exec_inst( warp_inst_t &inst );
// Returns numbers of addresses in translated_addrs
unsigned translate_local_memaddr( address_type localaddr, unsigned tid, unsigned num_shader, unsigned datasize, new_addr_type* translated_addrs );
@@ -2052,7 +2052,8 @@ private:
std::bitset<MAX_THREAD_PER_SM> m_occupied_hwtid;
std::map<unsigned int, unsigned int> m_occupied_cta_to_hwtid;
-
+ //Trace-driven simulation
+ friend class trace_shader_core_ctx;
};
class simt_core_cluster {
diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc
index 2560338..fea56c1 100644
--- a/src/trace-driven/gpgpusim_trace_driven_main.cc
+++ b/src/trace-driven/gpgpusim_trace_driven_main.cc
@@ -8,30 +8,32 @@
#include <fstream>
#include <string>
#include <sstream>
-#include <stdio.h>
#include <math.h>
-//#include "../abstract_hardware_model.h"
-//#include "../option_parser.h"
-//#include "../cuda-sim/cuda-sim.h"
-//#include "../cuda-sim/ptx_ir.h"
-//#include "../cuda-sim/ptx_parser.h"
+#include "../abstract_hardware_model.h"
+#include "../option_parser.h"
+#include "../cuda-sim/cuda-sim.h"
+#include "../cuda-sim/ptx_ir.h"
+#include "../cuda-sim/ptx_parser.h"
#include "../gpgpu-sim/gpu-sim.h"
//#include "../gpgpu-sim/icnt_wrapper.h"
//#include "../gpgpu-sim/icnt_wrapper.h"
#include "../../libcuda/gpgpu_context.h"
#include "trace_driven.h"
#include "trace_opcode.h"
+#include "../gpgpusim_entrypoint.h"
+//#include "gpgpu_context.h"
//#include "../stream_manager.h"
void arguments_check();
+
int main ( int argc, const char **argv )
{
- gpgpu_context* m_gpgpu_context = GPGPU_Context();
+ gpgpu_context* m_gpgpu_context = new gpgpu_context();
gpgpu_sim * m_gpgpu_sim = m_gpgpu_context->gpgpu_trace_sim_init_perf(argc,argv);
m_gpgpu_sim->init();
@@ -187,6 +189,7 @@ trace_kernel_info_t* trace_parser::parse_kernel_info(const std::string& kerneltr
else if (string1 == "cuda" && string2 == "stream") {
sscanf(line.c_str(), "-cuda stream id = %d", &cuda_stream_id);
}
+ std::cout << line << std::endl;
continue;
}
}
@@ -212,22 +215,49 @@ void trace_parser::kernel_finalizer(trace_kernel_info_t* kernel_info){
delete kernel_info;
}
-bool trace_kernel_info_t::get_next_threadblock_traces(std::vector<std::vector<trace_warp_inst_t>>& threadblock_traces) {
+const trace_warp_inst_t* trace_shd_warp_t::get_next_inst(){
+ return &warp_traces[trace_pc++];
+}
+
+void trace_shd_warp_t::clear() {
+ trace_pc=0;
+ warp_traces.clear();
+}
+
+bool trace_shd_warp_t::trace_done() {
+ return trace_pc==warp_traces.size();
+}
- threadblock_traces.clear();
- unsigned warps_per_tb = ceil(float(threads_per_cta()/32));
- threadblock_traces.resize(warps_per_tb);
+address_type trace_shd_warp_t::get_start_pc(){
+ assert(warp_traces.size() > 0);
+ return warp_traces[0].pc;
+}
+
+address_type trace_shd_warp_t::get_pc(){
+ assert(warp_traces.size() > 0);
+ return warp_traces[trace_pc].pc;
+}
+
+bool trace_kernel_info_t::get_next_threadblock_traces(std::vector<std::vector<trace_warp_inst_t>*> threadblock_traces) {
+
+ for(unsigned i=0; i<threadblock_traces.size(); ++i) {
+ threadblock_traces[i]->clear();
+ }
+ //unsigned warps_per_tb = ceil(float(threads_per_cta()/32));
+ //threadblock_traces.resize(warps_per_tb);
unsigned block_id_x=0, block_id_y=0, block_id_z=0;
unsigned warp_id=0;
unsigned insts_num=0;
- std::string line;
- std::stringstream ss;
- std::string string1, string2;
+
bool start_of_tb_stream_found = false;
while(!ifs->eof()) {
+ std::string line;
+ std::stringstream ss;
+ std::string string1, string2;
+
getline(*ifs, line);
if (line.length() == 0) {
@@ -238,32 +268,41 @@ bool trace_kernel_info_t::get_next_threadblock_traces(std::vector<std::vector<tr
ss>>string1>>string2;
if (string1 == "#BEGIN_TB") {
if(!start_of_tb_stream_found)
+ {
start_of_tb_stream_found=true;
- else assert(0 && "Parsing error: thread block start before the previous one finish");
+ }
+ else
+ assert(0 && "Parsing error: thread block start before the previous one finish");
+ std::cout<<line<<std::endl;
}
else if (string1 == "#END_TB") {
assert(start_of_tb_stream_found);
+ std::cout<<line<< std::endl;
break; //end of TB stream
}
else if(string1 == "thread" && string2 == "block") {
assert(start_of_tb_stream_found);
sscanf(line.c_str(), "thread block = %d,%d,%d", &block_id_x, &block_id_y, &block_id_z);
+ std::cout << line << std::endl;
}
else if (string1 == "warp") {
//the start of new warp stream
assert(start_of_tb_stream_found);
sscanf(line.c_str(), "warp = %d", &warp_id);
+ //std::cout << line << std::endl;
}
else if (string1 == "insts") {
assert(start_of_tb_stream_found);
sscanf(line.c_str(), "insts = %d", &insts_num);
- threadblock_traces[warp_id].resize(insts_num);
+ threadblock_traces[warp_id]->reserve(insts_num);
+ //std::cout << line << std::endl;
}
else {
assert(start_of_tb_stream_found);
trace_warp_inst_t inst(m_gpgpu_sim->getShaderCoreConfig(), m_gpgpu_context);
+ //std::cout<<line << std::endl;
inst.parse_from_string(line);
- threadblock_traces[warp_id].push_back(inst);
+ threadblock_traces[warp_id]->push_back(inst);
}
}
}
@@ -282,8 +321,9 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){
unsigned threadblock_x=0, threadblock_y=0, threadblock_z=0, warpid_tb=0, sm_id=0, warpid_sm=0;
unsigned long long m_pc=0;
unsigned mask=0;
- unsigned reg_dest=0;
+ unsigned reg_dest[4];
std::string opcode;
+ unsigned reg_dsts_num=0;
unsigned reg_srcs_num=0;
unsigned reg_srcs[4];
unsigned mem_width=0;
@@ -292,20 +332,30 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){
ss>>std::dec>>threadblock_x>>threadblock_y>>threadblock_z>>warpid_tb>>sm_id>>warpid_sm;
ss>>std::hex>>m_pc>>mask;
+ //std::cout<<"m_pc= "<<m_pc<<std::endl;
+ //std::cout<<"mask= "<<mask<<std::endl;
+
std::bitset<MAX_WARP_SIZE> mask_bits(mask);
- ss>>std::dec>>temp;
- sscanf(temp.c_str(), "R%d", &reg_dest);
+ ss>>reg_dsts_num;
+
+ for(unsigned i=0; i<reg_dsts_num; ++i) {
+ ss>>std::dec>>temp;
+ sscanf(temp.c_str(), "R%d", &reg_dest[i]);
+ }
ss>>opcode;
+
ss>>reg_srcs_num;
for(unsigned i=0; i<reg_srcs_num; ++i) {
ss>>temp;
sscanf(temp.c_str(), "R%d", &reg_srcs[i]);
+
}
ss>>mem_width;
+
if(mem_width > 0) //then it is a memory inst
{
for (int s = 0; s < warp_size(); s++) {
@@ -327,7 +377,9 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){
//fill and initialize common params
m_decoded = true;
- pc = m_pc;
+ pc = (address_type)m_pc; //we will lose the high 32 bits from casting long to unsigned, it should be okay!
+ //std::cout<<"pc= "<<pc<<std::endl;
+
isize = 16; //TO DO, change this
for(unsigned i=0; i<MAX_OUTPUT_VALUES; i++) {
out[i] = 0;
@@ -345,21 +397,24 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){
op = ALU_OP;
mem_op= NOT_TEX;
- //get opcode and category
- std::unordered_map<const char*,OpcodeChar>::const_iterator it= OpcodeMap.find(opcode1.c_str());
+ std::unordered_map<std::string,OpcodeChar>::const_iterator it= OpcodeMap.find(opcode1);
if (it != OpcodeMap.end()) {
m_opcode = it->second.opcode;
op = (op_type)(it->second.opcode_category);
}
- else
+ else {
+ std::cout<<"ERROR: undefined instruction : "<<opcode<<" Opcode: "<<opcode1<<std::endl;
assert(0 && "undefined instruction");
+ }
//fill regs information
- num_regs = reg_srcs_num+1;
+ num_regs = reg_srcs_num+reg_dsts_num;
num_operands = num_regs;
- outcount=1;
- out[0]=reg_dest;
- arch_reg.dst[0]=reg_dest;
+ outcount=reg_dsts_num;
+ for(unsigned m=0; m<reg_dsts_num; ++m){
+ out[m]=reg_dest[m];
+ arch_reg.src[m]=reg_dest[m];
+ }
incount=reg_srcs_num;
for(unsigned m=0; m<reg_srcs_num; ++m){
@@ -379,7 +434,8 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){
}
// barrier_type bar_type;
- // reduction_type red_type;
+ // reduction_type red_type;
+
//fill memory space
switch(m_opcode){
@@ -389,6 +445,7 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){
assert(mem_width>0);
data_size = mem_width;
memory_op = memory_load;
+ cache_op = CACHE_ALL;
if(m_opcode == OP_LDL)
space.set_type(local_space);
else
@@ -403,6 +460,7 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){
assert(mem_width>0);
data_size = mem_width;
memory_op = memory_store;
+ cache_op = CACHE_ALL;
if(m_opcode == OP_STL)
space.set_type(local_space);
else
@@ -410,6 +468,14 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){
if(m_opcode == OP_ATOM || m_opcode == OP_ATOMG || m_opcode == OP_RED)
m_isatomic = true;
+
+ for(unsigned m=0; m<reg_dsts_num; ++m){
+ out[m]=0;
+ arch_reg.src[m]=-1;
+ }
+ reg_dsts_num=0;
+ outcount=0;
+
break;
case OP_LDS:
case OP_STS:
@@ -418,9 +484,16 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){
data_size = mem_width;
space.set_type(shared_space);
break;
-
+ case OP_BAR:
+ //TO DO fill this correctly
+ bar_id = 0;
+ bar_count = (unsigned)-1;
+ bar_type = SYNC;
+ //if bar_type = RED;
+ //set bar_type
+ break;
default:
- break;
+ break;
}
return true;
@@ -482,34 +555,98 @@ void trace_warp_inst_t::set_latency(unsigned category)
initiation_interval = latency = 1;
switch(category){
- case ALU_OP:
- case INTP_OP:
- case BRANCH_OP:
- case CALL_OPS:
- case RET_OPS:
- latency = int_latency[0];
- initiation_interval = int_init[0];
- break;
- case SP_OP:
- latency = fp_latency[0];
- initiation_interval = fp_latency[0];
- break;
- case DP_OP:
- latency = dp_latency[0];
- initiation_interval = dp_latency[0];
- break;
- case SFU_OP:
- latency = sfu_latency;
- initiation_interval = sfu_init;
- break;
- case TENSOR_CORE_OP:
- latency = tensor_latency;
- initiation_interval = tensor_init;
- break;
- default:
- break;
- }
+ case ALU_OP:
+ case INTP_OP:
+ case BRANCH_OP:
+ case CALL_OPS:
+ case RET_OPS:
+ latency = int_latency[0];
+ initiation_interval = int_init[0];
+ break;
+ case SP_OP:
+ latency = fp_latency[0];
+ initiation_interval = fp_latency[0];
+ break;
+ case DP_OP:
+ latency = dp_latency[0];
+ initiation_interval = dp_latency[0];
+ break;
+ case SFU_OP:
+ latency = sfu_latency;
+ initiation_interval = sfu_init;
+ break;
+ case TENSOR_CORE_OP:
+ latency = tensor_latency;
+ initiation_interval = tensor_init;
+ break;
+ default:
+ break;
+ }
}
+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();
+ }
+
+ if( !kernel.more_threads_in_cta() )
+ kernel.increment_cta_id();
+
+ return 1;
+}
+
+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) {
+ threadblock_traces.push_back(&(m_trace_warp[i].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
+ for (unsigned i = start_warp; i < end_warp; ++i) {
+ m_warp[i].set_next_pc(m_trace_warp[i].get_start_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 ( m_trace_warp[inst.warp_id()].trace_done() ) {
+ m_warp[inst.warp_id()].set_completed(t);
+ m_warp[inst.warp_id()].ibuffer_flush();
+ }
+
+}
+
+void trace_shader_core_ctx::func_exec_inst( warp_inst_t &inst )
+{
+ //here, we generate memory acessess and set the status if thread (done?)
+ if( inst.is_load() || inst.is_store() )
+ {
+ inst.generate_mem_accesses();
+ }
+ for ( unsigned t=0; t < m_warp_size; t++ ) {
+ if( inst.active(t) ) {
+ unsigned warpId = inst.warp_id();
+ unsigned tid=m_warp_size*warpId+t;
+
+ //virtual function
+ checkExecutionStatusAndUpdate(inst,t,tid);
+ }
+ }
+ if(m_trace_warp[inst.warp_id()].trace_done() )
+ m_barriers.warp_exit( inst.warp_id() );
+}
diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h
index fbf7a1e..2f97958 100644
--- a/src/trace-driven/trace_driven.h
+++ b/src/trace-driven/trace_driven.h
@@ -24,6 +24,10 @@ public:
m_kernel_info = info;
}
+ virtual ~trace_function_info() {
+
+ }
+
private:
@@ -33,21 +37,23 @@ class trace_warp_inst_t: public warp_inst_t {
public:
trace_warp_inst_t() {
-
+ m_gpgpu_context=NULL;
+ m_opcode=0;
}
+
trace_warp_inst_t(const class core_config *config, gpgpu_context* gpgpu_context ):warp_inst_t(config) {
m_gpgpu_context = gpgpu_context;
m_opcode=0;
}
bool parse_from_string(std::string trace);
-
+ unsigned m_opcode;
private:
void set_latency(unsigned cat);
gpgpu_context* m_gpgpu_context;
- unsigned m_opcode;
+
};
@@ -59,7 +65,7 @@ public:
m_gpgpu_context = gpgpu_context;
}
- bool get_next_threadblock_traces(std::vector<std::vector<trace_warp_inst_t>>& threadblock_traces);
+ bool get_next_threadblock_traces(std::vector<std::vector<trace_warp_inst_t>*> threadblock_traces);
private:
std::ifstream* ifs;
@@ -87,15 +93,48 @@ private:
};
-class trace_shd_warp_t: public shd_warp_t {
+class trace_shd_warp_t {
+public:
+ trace_shd_warp_t() {
+ trace_pc=0;
+ }
+
+ std::vector<trace_warp_inst_t> warp_traces;
+ const trace_warp_inst_t* get_next_inst();
+ void clear();
+ bool trace_done();
+ address_type get_start_pc();
+ address_type get_pc();
+ unsigned trace_pc;
+
+private:
+
+
+};
+
+class trace_shader_core_ctx: public shader_core_ctx {
+
public:
- trace_shd_warp_t(class shader_core_ctx *shader, unsigned warp_size):shd_warp_t(shader, warp_size) {
+ trace_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) {
+
+ m_trace_warp.resize(get_config()->max_warps_per_shader);
}
- bool get_next_threadblock_traces(std::vector<std::vector<trace_warp_inst_t>>& threadblock_traces);
+ 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 func_exec_inst( warp_inst_t &inst );
+ std::vector<trace_shd_warp_t> m_trace_warp;
private:
+
};
#endif
diff --git a/src/trace-driven/trace_opcode.h b/src/trace-driven/trace_opcode.h
index f809238..827c32c 100644
--- a/src/trace-driven/trace_opcode.h
+++ b/src/trace-driven/trace_opcode.h
@@ -5,6 +5,7 @@
#include "../abstract_hardware_model.h"
#include <unordered_map>
+#include <string>
enum TraceInstrOpcode {
@@ -60,7 +61,7 @@ struct OpcodeChar
///Volta SM_70 ISA
//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html
-static const std::unordered_map<const char*,OpcodeChar> OpcodeMap = {
+static const std::unordered_map<std::string,OpcodeChar> OpcodeMap = {
//Floating Point 32 Instructions
{"FADD", OpcodeChar(OP_FADD, SP_OP)},
{"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)},