diff options
| author | Tim Rogers <[email protected]> | 2017-05-09 13:39:46 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2017-05-09 13:39:46 -0400 |
| commit | bcd1867f8f800f2f4eda9da4e8b2b2d6a567e622 (patch) | |
| tree | 81d2baa94e8f8f298aff5b44e164df43ae30a57d /src/gpgpu-sim | |
| parent | 54529f8b3556427526fd416118c444ce0eb10a21 (diff) | |
| parent | 96d528311239d6ff82d7bec807a2509b344c9a60 (diff) | |
Merge branch 'dev' into dev
Diffstat (limited to 'src/gpgpu-sim')
| -rw-r--r-- | src/gpgpu-sim/Makefile | 1 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 195 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.h | 20 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 114 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 42 |
5 files changed, 338 insertions, 34 deletions
diff --git a/src/gpgpu-sim/Makefile b/src/gpgpu-sim/Makefile index bead38a..f10a8a4 100644 --- a/src/gpgpu-sim/Makefile +++ b/src/gpgpu-sim/Makefile @@ -59,6 +59,7 @@ ifneq ($(GPGPUSIM_POWER_MODEL),) endif OPTFLAGS += -g3 -fPIC +OPTFLAGS += -DCUDART_VERSION=$(CUDART_VERSION) CPP = g++ $(SNOW) OEXT = o diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index eafb909..58a5d16 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -61,6 +61,7 @@ #include "power_stat.h" #include "visualizer.h" #include "stats.h" +#include "../cuda-sim/cuda_device_runtime.h" #ifdef GPGPUSIM_POWER_MODEL #include "power_interface.h" @@ -366,6 +367,10 @@ void shader_core_config::reg_options(class OptionParser * opp) "For complete list of prioritization values see shader.h enum scheduler_prioritization_type" "Default: gto", "gto"); + + option_parser_register(opp, "-gpgpu_concurrent_kernel_sm", OPT_BOOL, &gpgpu_concurrent_kernel_sm, + "Support concurrent kernels on a SM (default = disabled)", + "0"); } void gpgpu_sim_config::reg_options(option_parser_t opp) @@ -438,6 +443,16 @@ void gpgpu_sim_config::reg_options(option_parser_t opp) &Trace::sampling_memory_partition, "The memory partition which is printed using MEMPART_DPRINTF. Default -1 (i.e. all)", "-1"); ptx_file_line_stats_options(opp); + + //Jin: kernel launch latency + extern unsigned g_kernel_launch_latency; + option_parser_register(opp, "-gpgpu_kernel_launch_latency", OPT_INT32, + &g_kernel_launch_latency, "Kernel launch latency in cycles. Default: 0", + "0"); + extern bool g_cdp_enabled; + option_parser_register(opp, "-gpgpu_cdp_enabled", OPT_BOOL, + &g_cdp_enabled, "Turn on CDP", + "0"); } ///////////////////////////////////////////////////////////////////////////// @@ -518,16 +533,27 @@ bool gpgpu_sim::get_more_cta_left() const kernel_info_t *gpgpu_sim::select_kernel() { + if(m_running_kernels[m_last_issued_kernel] && + !m_running_kernels[m_last_issued_kernel]->no_more_ctas_to_run()) { + unsigned launch_uid = m_running_kernels[m_last_issued_kernel]->get_uid(); + if(std::find(m_executed_kernel_uids.begin(), m_executed_kernel_uids.end(), launch_uid) == m_executed_kernel_uids.end()) { + m_running_kernels[m_last_issued_kernel]->start_cycle = gpu_sim_cycle + gpu_tot_sim_cycle; + m_executed_kernel_uids.push_back(launch_uid); + m_executed_kernel_names.push_back(m_running_kernels[m_last_issued_kernel]->name()); + } + return m_running_kernels[m_last_issued_kernel]; + } + for(unsigned n=0; n < m_running_kernels.size(); n++ ) { unsigned idx = (n+m_last_issued_kernel+1)%m_config.max_concurrent_kernel; if( kernel_more_cta_left(m_running_kernels[idx]) ){ m_last_issued_kernel=idx; + m_running_kernels[idx]->start_cycle = gpu_sim_cycle + gpu_tot_sim_cycle; // record this kernel for stat print if it is the first time this kernel is selected for execution unsigned launch_uid = m_running_kernels[idx]->get_uid(); - if (std::find(m_executed_kernel_uids.begin(), m_executed_kernel_uids.end(), launch_uid) == m_executed_kernel_uids.end()) { - m_executed_kernel_uids.push_back(launch_uid); - m_executed_kernel_names.push_back(m_running_kernels[idx]->name()); - } + assert(std::find(m_executed_kernel_uids.begin(), m_executed_kernel_uids.end(), launch_uid) == m_executed_kernel_uids.end()); + m_executed_kernel_uids.push_back(launch_uid); + m_executed_kernel_names.push_back(m_running_kernels[idx]->name()); return m_running_kernels[idx]; } @@ -551,6 +577,7 @@ void gpgpu_sim::set_kernel_done( kernel_info_t *kernel ) std::vector<kernel_info_t*>::iterator k; for( k=m_running_kernels.begin(); k!=m_running_kernels.end(); k++ ) { if( *k == kernel ) { + kernel->end_cycle = gpu_sim_cycle + gpu_tot_sim_cycle; *k = NULL; break; } @@ -622,6 +649,10 @@ gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config ) *active_sms=0; last_liveness_message_time = 0; + + //Jin: functional simulation for CDP + m_functional_sim = false; + m_functional_sim_kernel = NULL; } int gpgpu_sim::shared_mem_size() const @@ -927,7 +958,8 @@ void gpgpu_sim::gpu_print_stat() printf("gpu_tot_ipc = %12.4f\n", (float)(gpu_tot_sim_insn+gpu_sim_insn) / (gpu_tot_sim_cycle+gpu_sim_cycle)); printf("gpu_tot_issued_cta = %lld\n", gpu_tot_issued_cta + m_total_cta_launched); - + extern unsigned long long g_max_total_param_size; + fprintf(statfout, "max_total_param_size = %llu\n", g_max_total_param_size); // performance counter for stalls due to congestion. printf("gpu_stall_dramfull = %d\n", gpu_stall_dramfull); @@ -1070,7 +1102,119 @@ void shader_core_ctx::mem_instruction_stats(const warp_inst_t &inst) abort(); } } +bool shader_core_ctx::can_issue_1block(kernel_info_t & kernel) { + + //Jin: concurrent kernels on one SM + if(m_config->gpgpu_concurrent_kernel_sm) { + if(m_config->max_cta(kernel) < 1) + return false; + + return occupy_shader_resource_1block(kernel, false); + } + else { + return (get_n_active_cta() < m_config->max_cta(kernel)); + } +} + +int shader_core_ctx::find_available_hwtid(unsigned int cta_size, bool occupy) { + + unsigned int step; + for(step = 0; step < m_config->n_thread_per_shader; + step += cta_size) { + + unsigned int hw_tid; + for(hw_tid = step; hw_tid < step + cta_size; + hw_tid++) { + if(m_occupied_hwtid.test(hw_tid)) + break; + } + if(hw_tid == step + cta_size) //consecutive non-active + break; + } + if(step >= m_config->n_thread_per_shader) //didn't find + return -1; + else { + if(occupy) { + for(unsigned hw_tid = step; hw_tid < step + cta_size; + hw_tid++) + m_occupied_hwtid.set(hw_tid); + } + return step; + } +} + +bool shader_core_ctx::occupy_shader_resource_1block(kernel_info_t & k, bool occupy) { + unsigned threads_per_cta = k.threads_per_cta(); + const class function_info *kernel = k.entry(); + unsigned int padded_cta_size = threads_per_cta; + unsigned int warp_size = m_config->warp_size; + if (padded_cta_size%warp_size) + padded_cta_size = ((padded_cta_size/warp_size)+1)*(warp_size); + + if(m_occupied_n_threads + padded_cta_size > m_config->n_thread_per_shader) + return false; + if(find_available_hwtid(padded_cta_size, false) == -1) + return false; + + const struct gpgpu_ptx_sim_info *kernel_info = ptx_sim_kernel_info(kernel); + + if(m_occupied_shmem + kernel_info->smem > m_config->gpgpu_shmem_size) + return false; + + unsigned int used_regs = padded_cta_size * ((kernel_info->regs+3)&~3); + if(m_occupied_regs + used_regs > m_config->gpgpu_shader_registers) + return false; + + if(m_occupied_ctas +1 > m_config->max_cta_per_core) + return false; + + if(occupy) { + m_occupied_n_threads += padded_cta_size; + m_occupied_shmem += kernel_info->smem; + m_occupied_regs += (padded_cta_size * ((kernel_info->regs+3)&~3)); + m_occupied_ctas++; + + printf("GPGPU-Sim uArch: Shader %d occupied %d threads, %d shared mem, %d registers, %d ctas\n", + m_sid, m_occupied_n_threads, m_occupied_shmem, m_occupied_regs, m_occupied_ctas); + } + + return true; +} + +void shader_core_ctx::release_shader_resource_1block(unsigned hw_ctaid, kernel_info_t & k) { + + if(m_config->gpgpu_concurrent_kernel_sm) { + unsigned threads_per_cta = k.threads_per_cta(); + const class function_info *kernel = k.entry(); + unsigned int padded_cta_size = threads_per_cta; + unsigned int warp_size = m_config->warp_size; + if (padded_cta_size%warp_size) + padded_cta_size = ((padded_cta_size/warp_size)+1)*(warp_size); + + assert(m_occupied_n_threads >= padded_cta_size); + m_occupied_n_threads -= padded_cta_size; + + int start_thread = m_occupied_cta_to_hwtid[hw_ctaid]; + + for(unsigned hwtid = start_thread; hwtid < start_thread + padded_cta_size; + hwtid++) + m_occupied_hwtid.reset(hwtid); + m_occupied_cta_to_hwtid.erase(hw_ctaid); + + const struct gpgpu_ptx_sim_info *kernel_info = ptx_sim_kernel_info(kernel); + + assert(m_occupied_shmem >= (unsigned int)kernel_info->smem); + m_occupied_shmem -= kernel_info->smem; + + unsigned int used_regs = padded_cta_size * ((kernel_info->regs+3)&~3); + assert(m_occupied_regs >= used_regs); + m_occupied_regs -= used_regs; + + assert(m_occupied_ctas >= 1); + m_occupied_ctas--; + } +} //////////////////////////////////////////////////////////////////////////////////////////////// @@ -1083,11 +1227,23 @@ void shader_core_ctx::mem_instruction_stats(const warp_inst_t &inst) void shader_core_ctx::issue_block2core( kernel_info_t &kernel ) { - set_max_cta(kernel); + + if(!m_config->gpgpu_concurrent_kernel_sm) + set_max_cta(kernel); + else + assert(occupy_shader_resource_1block(kernel, true)); + + kernel.inc_running(); // find a free CTA context unsigned free_cta_hw_id=(unsigned)-1; - for (unsigned i=0;i<kernel_max_cta_per_shader;i++ ) { + + unsigned max_cta_per_core; + if(!m_config->gpgpu_concurrent_kernel_sm) + max_cta_per_core = kernel_max_cta_per_shader; + else + max_cta_per_core = m_config->max_cta_per_core; + for (unsigned i=0;i<max_cta_per_core;i++ ) { if( m_cta_status[i]==0 ) { free_cta_hw_id=i; break; @@ -1104,8 +1260,20 @@ void shader_core_ctx::issue_block2core( kernel_info_t &kernel ) int padded_cta_size = cta_size; if (cta_size%m_config->warp_size) padded_cta_size = ((cta_size/m_config->warp_size)+1)*(m_config->warp_size); - unsigned start_thread = free_cta_hw_id * padded_cta_size; - unsigned end_thread = start_thread + cta_size; + + unsigned int start_thread, end_thread; + + if(!m_config->gpgpu_concurrent_kernel_sm) { + start_thread = free_cta_hw_id * padded_cta_size; + end_thread = start_thread + cta_size; + } + else { + start_thread = find_available_hwtid(padded_cta_size, true); + assert((int)start_thread != -1); + end_thread = start_thread + cta_size; + assert(m_occupied_cta_to_hwtid.find(free_cta_hw_id) == m_occupied_cta_to_hwtid.end()); + m_occupied_cta_to_hwtid[free_cta_hw_id]= start_thread; + } // reset the microarchitecture state of the selected hardware thread and warp contexts reinit(start_thread, end_thread,false); @@ -1133,7 +1301,9 @@ void shader_core_ctx::issue_block2core( kernel_info_t &kernel ) m_n_active_cta++; shader_CTA_count_log(m_sid, 1); - printf("GPGPU-Sim uArch: core:%3d, cta:%2u initialized @(%lld,%lld)\n", m_sid, free_cta_hw_id, gpu_sim_cycle, gpu_tot_sim_cycle ); + printf("GPGPU-Sim uArch: core:%3d, cta:%2u, start_tid:%4u, end_tid:%4u, initialized @(%lld,%lld)\n", + m_sid, free_cta_hw_id, start_thread, end_thread, gpu_sim_cycle, gpu_tot_sim_cycle ); + } /////////////////////////////////////////////////////////////////////////////////////////// @@ -1366,6 +1536,11 @@ void gpgpu_sim::cycle() } try_snap_shot(gpu_sim_cycle); spill_log_to_file (stdout, 0, gpu_sim_cycle); + +#if (CUDART_VERSION >= 5000) + //launch device kernel + launch_one_device_kernel(); +#endif } } diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 33fffd3..a2d1b9b 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -492,6 +492,7 @@ private: std::string executed_kernel_info_string(); //< format the kernel information into a string for stat printout void clear_executed_kernel_info(); //< clear the kernel information after stat printout + public: unsigned long long gpu_sim_insn; unsigned long long gpu_tot_sim_insn; @@ -504,6 +505,25 @@ public: void change_cache_config(FuncCache cache_config); void set_cache_config(std::string kernel_name); + //Jin: functional simulation for CDP +private: + //set by stream operation every time a functoinal simulation is done + bool m_functional_sim; + kernel_info_t * m_functional_sim_kernel; + +public: + bool is_functional_sim() { return m_functional_sim; } + kernel_info_t * get_functional_kernel() { return m_functional_sim_kernel; } + void functional_launch(kernel_info_t * k) { + m_functional_sim = true; + m_functional_sim_kernel = k; + } + void finish_functional_sim(kernel_info_t * k) { + assert(m_functional_sim); + assert(m_functional_sim_kernel == k); + m_functional_sim = false; + m_functional_sim_kernel = NULL; + } }; #endif diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index ff2fac7..d17e51d 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -296,6 +296,14 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_last_inst_gpu_sim_cycle = 0; m_last_inst_gpu_tot_sim_cycle = 0; + + //Jin: for concurrent kernels on a SM + m_occupied_n_threads = 0; + m_occupied_shmem = 0; + m_occupied_regs = 0; + m_occupied_ctas = 0; + m_occupied_hwtid.reset(); + m_occupied_cta_to_hwtid.clear(); } void shader_core_ctx::reinit(unsigned start_thread, unsigned end_thread, bool reset_not_completed ) @@ -303,6 +311,15 @@ void shader_core_ctx::reinit(unsigned start_thread, unsigned end_thread, bool re if( reset_not_completed ) { m_not_completed = 0; m_active_threads.reset(); + + //Jin: for concurrent kernels on a SM + m_occupied_n_threads = 0; + m_occupied_shmem = 0; + m_occupied_regs = 0; + m_occupied_ctas = 0; + m_occupied_hwtid.reset(); + m_occupied_cta_to_hwtid.clear(); + } for (unsigned i = start_thread; i<end_thread; i++) { m_threadState[i].n_insn = 0; @@ -620,7 +637,7 @@ 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); + 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 ); @@ -828,6 +845,13 @@ void scheduler_unit::cycle() unsigned max_issue = m_shader->m_config->gpgpu_max_insn_issue_per_warp; while( !warp(warp_id).waiting() && !warp(warp_id).ibuffer_empty() && (checked < max_issue) && (checked <= issued) && (issued < max_issue) ) { const warp_inst_t *pI = warp(warp_id).ibuffer_next_inst(); + //Jin: handle cdp latency; + if(pI && pI->m_is_cdp && warp(warp_id).m_cdp_latency > 0) { + assert(warp(warp_id).m_cdp_dummy); + warp(warp_id).m_cdp_latency--; + break; + } + bool valid = warp(warp_id).ibuffer_next_valid(); bool warp_inst_issued = false; unsigned pc,rpc; @@ -862,6 +886,25 @@ void scheduler_unit::cycle() bool sp_pipe_avail = m_sp_out->has_free(); bool sfu_pipe_avail = m_sfu_out->has_free(); if( sp_pipe_avail && (pI->op != SFU_OP) ) { + + //Jin: special for CDP api + if(pI->m_is_cdp && !warp(warp_id).m_cdp_dummy) { + assert(warp(warp_id).m_cdp_latency == 0); + + extern unsigned cdp_latency[5]; + if(pI->m_is_cdp == 1) + warp(warp_id).m_cdp_latency = cdp_latency[pI->m_is_cdp - 1]; + else //cudaLaunchDeviceV2 and cudaGetParameterBufferV2 + warp(warp_id).m_cdp_latency = cdp_latency[pI->m_is_cdp - 1] + + cdp_latency[pI->m_is_cdp] * active_mask.count(); + warp(warp_id).m_cdp_dummy = true; + break; + } + else if(pI->m_is_cdp && warp(warp_id).m_cdp_dummy) { + assert(warp(warp_id).m_cdp_latency == 0); + warp(warp_id).m_cdp_dummy = false; + } + // always prefer SP pipe for operations that can use both SP and SFU pipelines m_shader->issue_warp(*m_sp_out,pI,active_mask,warp_id); issued++; @@ -1917,7 +1960,7 @@ void ldst_unit::cycle() } } -void shader_core_ctx::register_cta_thread_exit( unsigned cta_num ) +void shader_core_ctx::register_cta_thread_exit( unsigned cta_num, kernel_info_t * kernel) { assert( m_cta_status[cta_num] > 0 ); m_cta_status[cta_num]--; @@ -1925,22 +1968,35 @@ void shader_core_ctx::register_cta_thread_exit( unsigned cta_num ) m_n_active_cta--; m_barriers.deallocate_barrier(cta_num); shader_CTA_count_unlog(m_sid, 1); + printf("GPGPU-Sim uArch: Shader %d finished CTA #%d (%lld,%lld), %u CTAs running\n", m_sid, cta_num, gpu_sim_cycle, gpu_tot_sim_cycle, m_n_active_cta ); + if( m_n_active_cta == 0 ) { - assert( m_kernel != NULL ); - m_kernel->dec_running(); - printf("GPGPU-Sim uArch: Shader %u empty (release kernel %u \'%s\').\n", m_sid, m_kernel->get_uid(), - m_kernel->name().c_str() ); - if( !m_gpu->kernel_more_cta_left(m_kernel) ) { - if( !m_kernel->running() ) { - printf("GPGPU-Sim uArch: GPU detected kernel \'%s\' finished on shader %u.\n", m_kernel->name().c_str(), m_sid ); - m_gpu->set_kernel_done( m_kernel ); - } - } - m_kernel=NULL; + printf("GPGPU-Sim uArch: Shader %u empty (last released kernel %u \'%s\').\n", m_sid, kernel->get_uid(), + kernel->name().c_str() ); fflush(stdout); + + //Shader can only be empty when no more cta are dispatched + if(kernel != m_kernel) { + assert(m_kernel == NULL || !m_gpu->kernel_more_cta_left(m_kernel)); + } + m_kernel = NULL; + } + + //Jin: for concurrent kernels on sm + release_shader_resource_1block(cta_num, *kernel); + kernel->dec_running(); + if( !m_gpu->kernel_more_cta_left(kernel) ) { + if( !kernel->running() ) { + printf("GPGPU-Sim uArch: GPU detected kernel %u \'%s\' finished on shader %u.\n", kernel->get_uid(), + kernel->name().c_str(), m_sid ); + if(m_kernel == kernel) + m_kernel = NULL; + m_gpu->set_kernel_done( kernel ); + } } + } } @@ -3238,15 +3294,33 @@ unsigned simt_core_cluster::issue_block2core() unsigned num_blocks_issued=0; for( unsigned i=0; i < m_config->n_simt_cores_per_cluster; i++ ) { unsigned core = (i+m_cta_issue_next_core+1)%m_config->n_simt_cores_per_cluster; - if( m_core[core]->get_not_completed() == 0 ) { - if( m_core[core]->get_kernel() == NULL ) { - kernel_info_t *k = m_gpu->select_kernel(); - if( k ) - m_core[core]->set_kernel(k); + + kernel_info_t * kernel; + //Jin: fetch kernel according to concurrent kernel setting + if(m_config->gpgpu_concurrent_kernel_sm) {//concurrent kernel on sm + //always select latest issued kernel + kernel_info_t *k = m_gpu->select_kernel(); + kernel = k; + } + else { + //first select core kernel, if no more cta, get a new kernel + //only when core completes + kernel = m_core[core]->get_kernel(); + if( !m_gpu->kernel_more_cta_left(kernel) ) { + //wait till current kernel finishes + if(m_core[core]->get_not_completed() == 0) + { + kernel_info_t *k = m_gpu->select_kernel(); + if( k ) + m_core[core]->set_kernel(k); + kernel = k; + } } } - kernel_info_t *kernel = m_core[core]->get_kernel(); - if( m_gpu->kernel_more_cta_left(kernel) && (m_core[core]->get_n_active_cta() < m_config->max_cta(*kernel)) ) { + + if( m_gpu->kernel_more_cta_left(kernel) && +// (m_core[core]->get_n_active_cta() < m_config->max_cta(*kernel)) ) { + m_core[core]->can_issue_1block(*kernel)) { m_core[core]->issue_block2core(*kernel); num_blocks_issued++; m_cta_issue_next_core=core; diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 1aa468b..bdd8dbe 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -108,6 +108,10 @@ public: m_last_fetch=0; m_next=0; m_inst_at_barrier=NULL; + + //Jin: cdp support + m_cdp_latency = 0; + m_cdp_dummy = false; } void init( address_type start_pc, unsigned cta_id, @@ -124,6 +128,10 @@ public: n_completed -= active.count(); // active threads are not yet completed m_active_threads = active; m_done_exit=false; + + //Jin: cdp support + m_cdp_latency = 0; + m_cdp_dummy = false; } bool functional_done() const; @@ -260,6 +268,11 @@ private: unsigned m_stores_outstanding; // number of store requests sent but not yet acknowledged unsigned m_inst_in_pipeline; + + //Jin: cdp support +public: + unsigned int m_cdp_latency; + bool m_cdp_dummy; }; @@ -267,7 +280,7 @@ private: inline unsigned hw_tid_from_wid(unsigned wid, unsigned warp_size, unsigned i){return wid * warp_size + i;}; inline unsigned wid_from_hw_tid(unsigned tid, unsigned warp_size){return tid/warp_size;}; -const unsigned WARP_PER_CTA_MAX = 48; +const unsigned WARP_PER_CTA_MAX = 64; typedef std::bitset<WARP_PER_CTA_MAX> warp_set_t; int register_bank(int regnum, int wid, unsigned num_banks, unsigned bank_warp_shift); @@ -1327,11 +1340,14 @@ struct shader_core_config : public core_config int simt_core_sim_order; unsigned mem2device(unsigned memid) const { return memid + n_simt_clusters; } + + //Jin: concurrent kernel on sm + bool gpgpu_concurrent_kernel_sm; }; struct shader_core_stats_pod { - void* shader_core_stats_pod_start[0]; // DO NOT MOVE FROM THE TOP - spaceless pointer to the start of this structure + void* shader_core_stats_pod_start[]; // DO NOT MOVE FROM THE TOP - spaceless pointer to the start of this structure unsigned long long *shader_cycles; unsigned *m_num_sim_insn; // number of scalar thread instructions committed by this shader core unsigned *m_num_sim_winsn; // number of warp instructions committed by this shader core @@ -1574,6 +1590,7 @@ public: void cycle(); void reinit(unsigned start_thread, unsigned end_thread, bool reset_not_completed ); void issue_block2core( class kernel_info_t &kernel ); + void cache_flush(); void accept_fetch_response( mem_fetch *mf ); void accept_ldst_unit_response( class mem_fetch * mf ); @@ -1582,7 +1599,7 @@ public: { assert(k); m_kernel=k; - k->inc_running(); +// k->inc_running(); printf("GPGPU-Sim uArch: Shader %d bind to kernel %u \'%s\'\n", m_sid, m_kernel->get_uid(), m_kernel->name().c_str() ); } @@ -1749,7 +1766,7 @@ public: virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid); address_type next_pc( int tid ) const; void fetch(); - void register_cta_thread_exit( unsigned cta_num ); + void register_cta_thread_exit(unsigned cta_num, kernel_info_t * kernel ); void decode(); @@ -1831,6 +1848,22 @@ public: // is that the dynamic_warp_id is a running number unique to every warp // run on this shader, where the warp_id is the static warp slot. unsigned m_dynamic_warp_id; + + //Jin: concurrent kernels on a sm +public: + bool can_issue_1block(kernel_info_t & kernel); + bool occupy_shader_resource_1block(kernel_info_t & kernel, bool occupy); + void release_shader_resource_1block(unsigned hw_ctaid, kernel_info_t & kernel); + int find_available_hwtid(unsigned int cta_size, bool occupy); +private: + unsigned int m_occupied_n_threads; + unsigned int m_occupied_shmem; + unsigned int m_occupied_regs; + unsigned int m_occupied_ctas; + std::bitset<MAX_THREAD_PER_SM> m_occupied_hwtid; + std::map<unsigned int, unsigned int> m_occupied_cta_to_hwtid; + + }; class simt_core_cluster { @@ -1851,6 +1884,7 @@ public: bool icnt_injection_buffer_full(unsigned size, bool write); void icnt_inject_request_packet(class mem_fetch *mf); + // for perfect memory interface bool response_queue_full() { return ( m_response_fifo.size() >= m_config->n_simt_ejection_buffer_size ); |
