diff options
| -rw-r--r-- | Makefile | 10 | ||||
| -rw-r--r-- | src/abstract_hardware_model.cc | 7 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 10 | ||||
| -rw-r--r-- | src/gpgpu-sim/mem_latency_stat.cc | 5 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 166 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 7 | ||||
| -rw-r--r-- | src/trace-driven/gpgpusim_trace_driven_main.cc | 253 | ||||
| -rw-r--r-- | src/trace-driven/trace_driven.h | 53 | ||||
| -rw-r--r-- | src/trace-driven/trace_opcode.h | 3 |
9 files changed, 384 insertions, 130 deletions
@@ -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", ®_dest); + ss>>reg_dsts_num; + + for(unsigned i=0; i<reg_dsts_num; ++i) { + ss>>std::dec>>temp; + sscanf(temp.c_str(), "R%d", ®_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", ®_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)}, |
