diff options
Diffstat (limited to 'src/gpgpu-sim')
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 238 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.h | 39 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 104 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 21 | ||||
| -rw-r--r-- | src/gpgpu-sim/stat-tool.cc | 23 | ||||
| -rw-r--r-- | src/gpgpu-sim/stat-tool.h | 17 |
6 files changed, 265 insertions, 177 deletions
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 9bb6a23..9ae05d8 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -276,6 +276,8 @@ void gpgpu_sim_config::reg_options(option_parser_t opp) option_parser_register(opp, "-gpgpu_clock_domains", OPT_CSTR, &gpgpu_clock_domains, "Clock Domain Frequencies in MhZ {<Core Clock>:<ICNT Clock>:<L2 Clock>:<DRAM Clock>}", "500.0:2000.0:2000.0:2000.0"); + option_parser_register(opp, "-gpgpu_max_concurrent_kernel", OPT_INT32, &max_concurrent_kernel, + "maximum kernels that can run concurrently on GPU", "8" ); option_parser_register(opp, "-gpgpu_cflog_interval", OPT_INT32, &gpgpu_cflog_interval, "Interval between each snapshot in control flow logger", "0"); @@ -307,7 +309,6 @@ void increment_x_then_y_then_z( dim3 &i, const dim3 &bound) } } - void gpgpu_sim::launch( kernel_info_t &kinfo ) { unsigned cta_size = kinfo.threads_per_cta(); @@ -319,15 +320,57 @@ void gpgpu_sim::launch( kernel_info_t &kinfo ) printf(" modify the CUDA source to decrease the kernel block size.\n"); abort(); } + unsigned n=0; + for(n=0; n < m_running_kernels.size(); n++ ) { + if( m_running_kernels[n].done() ) { + m_running_kernels[n] = kinfo; + break; + } + } + assert(n < m_running_kernels.size()); +} + +bool gpgpu_sim::can_start_kernel() +{ + for(unsigned n=0; n < m_running_kernels.size(); n++ ) { + if( m_running_kernels[n].done() ) + return true; + } + return false; +} - m_running_kernels.push_back(kinfo); +bool gpgpu_sim::get_more_cta_left() const +{ + if (m_config.gpu_max_cta_opt != 0) { + if( m_total_cta_launched >= m_config.gpu_max_cta_opt ) + return false; + } + for(unsigned n=0; n < m_running_kernels.size(); n++ ) { + if( m_running_kernels[n].valid() && !m_running_kernels[n].no_more_ctas_to_run() ) + return true; + } + return false; +} + +kernel_info_t *gpgpu_sim::select_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( m_running_kernels[idx].valid() && !m_running_kernels[idx].no_more_ctas_to_run() ) { + m_last_issued_kernel=idx; + return &m_running_kernels[idx]; + } + } + return NULL; } -kernel_info_t *gpgpu_sim::next_grid() +unsigned gpgpu_sim::finished_kernel() { - m_the_kernel = m_running_kernels.front(); - m_running_kernels.pop_front(); - return &m_the_kernel; + if( m_finished_kernel.empty() ) + return 0; + unsigned result = m_finished_kernel.front(); + m_finished_kernel.pop_front(); + return result; } void set_ptx_warp_size(const struct core_config * warp_size); @@ -360,6 +403,10 @@ gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config ) time_vector_create(NUM_MEM_REQ_STAT); fprintf(stdout, "GPGPU-Sim uArch: performance model initialization complete.\n"); + + m_running_kernels.resize( config.max_concurrent_kernel ); + m_last_issued_kernel = 0; + m_last_cluster_issue = 0; } int gpgpu_sim::shared_mem_size() const @@ -421,94 +468,76 @@ void gpgpu_sim::reinit_clock_domains(void) l2_time = 0; } -// return the number of cycle required to run all the trace on the gpu -unsigned int gpgpu_sim::run_gpu_sim() +bool gpgpu_sim::active() { - // run a CUDA grid on the GPU microarchitecture simulator - kernel_info_t &entry = m_the_kernel; - size_t program_size = get_kernel_code_size(entry.entry()); - - int not_completed; - int mem_busy; - int icnt2mem_busy; - - gpu_sim_cycle = 0; - not_completed = 1; - mem_busy = 1; - icnt2mem_busy = 1; - more_thread = true; - g_total_cta_left=0; - gpu_sim_insn = 0; - m_shader_stats->new_grid(); + if (m_config.gpu_max_cycle_opt && (gpu_tot_sim_cycle + gpu_sim_cycle) >= m_config.gpu_max_cycle_opt) + return false; + if (m_config.gpu_max_insn_opt && (gpu_tot_sim_insn + gpu_sim_insn) >= m_config.gpu_max_insn_opt) + return false; + if (m_config.gpu_max_cta_opt && (gpu_tot_issued_cta >= m_config.gpu_max_cta_opt) ) + return false; + if (m_config.gpu_deadlock_detect && gpu_deadlock) + return false; + for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) + if( m_cluster[i]->get_not_completed()>0 ) + return true;; + for (unsigned i=0;i<m_memory_config->m_n_mem;i++) + if( m_memory_partition_unit[i]->busy()>0 ) + return true;; + if( icnt_busy() ) + return true; + if( get_more_cta_left() ) + return true; + return false; +} - reinit_clock_domains(); - set_param_gpgpu_num_shaders(m_config.num_shader()); - for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) - m_cluster[i]->reinit(); - if (m_config.gpu_max_cta_opt != 0) { - g_total_cta_left = m_config.gpu_max_cta_opt; - } else { - g_total_cta_left = m_the_kernel.num_blocks(); - } - if (m_config.gpu_max_cta_opt != 0) { - // the maximum number of CTA has been reached, stop any further simulation - if (gpu_tot_issued_cta >= m_config.gpu_max_cta_opt) - return 0; - } +void gpgpu_sim::init() +{ + // run a CUDA grid on the GPU microarchitecture simulator + gpu_sim_cycle = 0; + gpu_sim_insn = 0; + m_total_cta_launched=0; - if (m_config.gpu_max_cycle_opt && (gpu_tot_sim_cycle + gpu_sim_cycle) >= m_config.gpu_max_cycle_opt) { - return gpu_sim_cycle; - } - if (m_config.gpu_max_insn_opt && (gpu_tot_sim_insn + gpu_sim_insn) >= m_config.gpu_max_insn_opt) { - return gpu_sim_cycle; - } + reinit_clock_domains(); + set_param_gpgpu_num_shaders(m_config.num_shader()); + for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) + m_cluster[i]->reinit(); + m_shader_stats->new_grid(); + // initialize the control-flow, memory access, memory latency logger + create_thread_CFlogger( m_config.num_shader(), m_shader_config->n_thread_per_shader, 0, m_config.gpgpu_cflog_interval ); + shader_CTA_count_create( m_config.num_shader(), m_config.gpgpu_cflog_interval); + if (m_config.gpgpu_cflog_interval != 0) { + insn_warp_occ_create( m_config.num_shader(), m_shader_config->warp_size ); + shader_warp_occ_create( m_config.num_shader(), m_shader_config->warp_size, m_config.gpgpu_cflog_interval); + shader_mem_acc_create( m_config.num_shader(), m_memory_config->m_n_mem, 4, m_config.gpgpu_cflog_interval); + shader_mem_lat_create( m_config.num_shader(), m_config.gpgpu_cflog_interval); + shader_cache_access_create( m_config.num_shader(), 3, m_config.gpgpu_cflog_interval); + set_spill_interval (m_config.gpgpu_cflog_interval * 40); + } - // initialize the control-flow, memory access, memory latency logger - create_thread_CFlogger( m_config.num_shader(), m_shader_config->n_thread_per_shader, program_size, 0, m_config.gpgpu_cflog_interval ); - shader_CTA_count_create( m_config.num_shader(), m_config.gpgpu_cflog_interval); - if (m_config.gpgpu_cflog_interval != 0) { - insn_warp_occ_create( m_config.num_shader(), m_shader_config->warp_size, program_size ); - shader_warp_occ_create( m_config.num_shader(), m_shader_config->warp_size, m_config.gpgpu_cflog_interval); - shader_mem_acc_create( m_config.num_shader(), m_memory_config->m_n_mem, 4, m_config.gpgpu_cflog_interval); - shader_mem_lat_create( m_config.num_shader(), m_config.gpgpu_cflog_interval); - shader_cache_access_create( m_config.num_shader(), 3, m_config.gpgpu_cflog_interval); - set_spill_interval (m_config.gpgpu_cflog_interval * 40); - } + if (g_network_mode) + icnt_init_grid(); +} - if (g_network_mode) - icnt_init_grid(); +void gpgpu_sim::print_stats() +{ + m_memory_stats->memlatstat_lat_pw(); + gpu_tot_sim_cycle += gpu_sim_cycle; + gpu_tot_sim_insn += gpu_sim_insn; - last_gpu_sim_insn = 0; - while (not_completed || mem_busy || icnt2mem_busy) { - cycle(); - not_completed = 0; - for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) - not_completed += m_cluster[i]->get_not_completed(); - mem_busy = 0; - for (unsigned i=0;i<m_memory_config->m_n_mem;i++) - mem_busy += m_memory_partition_unit[i]->busy(); - icnt2mem_busy = icnt_busy(); - if (m_config.gpu_max_cycle_opt && (gpu_tot_sim_cycle + gpu_sim_cycle) >= m_config.gpu_max_cycle_opt) - break; - if (m_config.gpu_max_insn_opt && (gpu_tot_sim_insn + gpu_sim_insn) >= m_config.gpu_max_insn_opt) - break; - if (m_config.gpu_deadlock_detect && gpu_deadlock) - break; - } - m_memory_stats->memlatstat_lat_pw(); - gpu_tot_sim_cycle += gpu_sim_cycle; - gpu_tot_sim_insn += gpu_sim_insn; - - ptx_file_line_stats_write_file(); + ptx_file_line_stats_write_file(); + gpu_print_stat(); - gpu_print_stat(); - if (g_network_mode) { - interconnect_stats(); - printf("----------------------------Interconnect-DETAILS---------------------------------" ); - icnt_overal_stat(); - printf("----------------------------END-of-Interconnect-DETAILS-------------------------" ); - } + if (g_network_mode) { + interconnect_stats(); + printf("----------------------------Interconnect-DETAILS---------------------------------" ); + icnt_overal_stat(); + printf("----------------------------END-of-Interconnect-DETAILS-------------------------" ); + } +} +void gpgpu_sim::deadlock_check() +{ if (m_config.gpu_deadlock_detect && gpu_deadlock) { fflush(stdout); printf("\n\nGPGPU-Sim uArch: ERROR ** deadlock detected: last writeback core %u @ gpu_sim_cycle %u (+ gpu_tot_sim_cycle %u) (%u cycles ago)\n", @@ -545,7 +574,6 @@ unsigned int gpgpu_sim::run_gpu_sim() fflush(stdout); abort(); } - return gpu_sim_cycle; } void gpgpu_sim::gpu_print_stat() const @@ -634,11 +662,11 @@ 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); + // find a free CTA context unsigned free_cta_hw_id=(unsigned)-1; - unsigned max_concurrent_cta_this_kernel = m_config->max_cta(kernel); - assert( max_concurrent_cta_this_kernel <= MAX_CTA_PER_SHADER ); - for (unsigned i=0;i<max_concurrent_cta_this_kernel;i++ ) { + for (unsigned i=0;i<kernel_max_cta_per_shader;i++ ) { if( m_cta_status[i]==0 ) { free_cta_hw_id=i; break; @@ -722,6 +750,18 @@ int gpgpu_sim::next_clock_domain(void) return mask; } +void gpgpu_sim::issue_block2core() +{ + for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) { + unsigned idx = (i+m_last_cluster_issue+1) % m_shader_config->n_simt_clusters; + unsigned num = m_cluster[idx]->issue_block2core(); + if( num ) { + m_last_cluster_issue=idx; + m_total_cta_launched += num; + } + } +} + unsigned long long g_single_step=0; // set this in gdb to single step the pipeline void gpgpu_sim::cycle() @@ -778,10 +818,11 @@ void gpgpu_sim::cycle() icnt_transfer(); } + last_gpu_sim_insn = 0; if (clock_mask & CORE) { // L1 cache + shader core pipeline stages for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) { - if (m_cluster[i]->get_not_completed() || more_thread) { + if (m_cluster[i]->get_not_completed() || get_more_cta_left() ) { m_cluster[i]->core_cycle(); } } @@ -791,18 +832,9 @@ void gpgpu_sim::cycle() gpu_sim_cycle++; if( g_interactive_debugger_enabled ) gpgpu_debug(); - - for (unsigned i=0;i<m_shader_config->n_simt_clusters && more_thread;i++) { - if ( ( (m_cluster[i]->get_n_active_cta()+1) <= m_cluster[i]->max_cta(m_the_kernel) ) && g_total_cta_left ) { - unsigned num = m_cluster[i]->issue_block2core( m_the_kernel ); - if (num >= g_total_cta_left) { - g_total_cta_left = 0; - more_thread = false; - } else - g_total_cta_left -= num; - } - } - + + issue_block2core(); + // Flush the caches once all of threads are completed. if (m_config.gpgpu_flush_cache) { int all_threads_complete = 1 ; diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index db0b18f..5631ab9 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -192,20 +192,8 @@ public: m_valid=true; } - void set_max_cta( const kernel_info_t &kernel ) - { - // calcaulte the max cta count and cta size for local memory address mapping - m_shader_config.gpu_max_cta_per_shader = m_shader_config.max_cta(kernel); - //gpu_max_cta_per_shader is limited by number of CTAs if not enough - if( kernel.num_blocks() < m_shader_config.gpu_max_cta_per_shader*num_shader() ) { - m_shader_config.gpu_max_cta_per_shader = (kernel.num_blocks() / num_shader()); - if (kernel.num_blocks() % num_shader()) - m_shader_config.gpu_max_cta_per_shader++; - } - unsigned int gpu_cta_size = kernel.threads_per_cta(); - m_shader_config.gpu_padded_cta_size = (gpu_cta_size%32) ? 32*((gpu_cta_size/32)+1) : gpu_cta_size; - } unsigned num_shader() const { return m_shader_config.num_shader(); } + unsigned get_max_concurrent_kernel() const { return max_concurrent_kernel; } private: void init_clock_domains(void ); @@ -234,6 +222,7 @@ private: int gpgpu_dram_sched_queue_size; int gpgpu_cflog_interval; char * gpgpu_clock_domains; + unsigned max_concurrent_kernel; // visualizer bool g_visualizer_enabled; @@ -254,12 +243,17 @@ public: void set_prop( struct cudaDeviceProp *prop ); void launch( kernel_info_t &kinfo ); - kernel_info_t *next_grid(); + bool can_start_kernel(); + unsigned finished_kernel(); + void set_kernel_done( unsigned uid ) { m_finished_kernel.push_back(uid); } - unsigned run_gpu_sim(); + void init(); + void cycle(); + bool active(); + void print_stats(); + void deadlock_check(); void get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc ); - const kernel_info_t &the_kernel() const { return m_the_kernel; } int shared_mem_size() const; int num_registers_per_core() const; @@ -269,6 +263,8 @@ public: enum divergence_support_t simd_model() const; unsigned threads_per_core() const; + bool get_more_cta_left() const; + kernel_info_t *select_kernel(); const gpgpu_sim_config &get_config() const { return m_config; } void gpu_print_stat() const; @@ -278,8 +274,8 @@ private: // clocks void reinit_clock_domains(void); int next_clock_domain(void); + void issue_block2core(); - void cycle(); void L2c_print_cache_stat() const; void shader_print_runtime_stat( FILE *fout ); void shader_print_l1_miss_stat( FILE *fout ); @@ -293,11 +289,12 @@ private: class simt_core_cluster **m_cluster; class memory_partition_unit **m_memory_partition_unit; - kernel_info_t m_the_kernel; - std::list<kernel_info_t> m_running_kernels; + std::vector<kernel_info_t> m_running_kernels; + unsigned m_last_issued_kernel; - unsigned g_total_cta_left; - bool more_thread; + std::list<unsigned> m_finished_kernel; + unsigned m_total_cta_launched; + unsigned m_last_cluster_issue; // time of next rising edge double core_time; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 7a0ad59..07aeb6d 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -110,6 +110,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, shader_core_stats *stats ) : m_barriers( config->max_warps_per_shader, config->max_cta_per_core ) { + m_kernel = NULL; m_gpu = gpu; m_cluster = cluster; m_config = config; @@ -519,7 +520,8 @@ void shader_core_ctx::fetch() for( unsigned t=0; t<m_config->warp_size;t++) { unsigned tid=warp_id*m_config->warp_size+t; if( m_thread[tid].m_functional_model_thread_state ) { - register_cta_thread_exit(tid); + unsigned cta_id = m_warp[warp_id].get_cta_id(); + register_cta_thread_exit(cta_id); m_not_completed -= 1; m_active_threads.reset(tid); m_thread[tid].m_functional_model_thread_state=NULL; @@ -725,26 +727,37 @@ address_type shader_core_ctx::translate_local_memaddr( address_type localaddr, u { // During functional execution, each thread sees its own memory space for local memory, but these // need to be mapped to a shared address space for timing simulation. We do that mapping here. - localaddr /=4; + + address_type thread_base = 0; + unsigned max_concurrent_threads=0; if (m_config->gpgpu_local_mem_map) { - // Dnew = D*nTpC*nCpS*nS + nTpC*C + T%nTpC - // C = S + nS*(T/nTpC) - // D = data index; T = thread; C = CTA; S = shader core; p = per - // keep threads in a warp contiguous + // Dnew = D*N + T%nTpC + nTpC*C + // N = nTpC*nCpS*nS (max concurent threads) + // C = nS*K + S (hw cta number per gpu) + // K = T/nTpC (hw cta number per core) + // D = data index + // T = thread + // nTpC = number of threads per CTA + // nCpS = number of CTA per shader + // + // for a given local memory address threads in a CTA map to contiguous addresses, // then distribute across memory space by CTAs from successive shader cores first, // then by successive CTA in same shader core - localaddr *= m_config->gpu_padded_cta_size * m_config->gpu_max_cta_per_shader * num_shader; - localaddr += m_config->gpu_padded_cta_size * (m_sid + num_shader * (tid / m_config->gpu_padded_cta_size)); - localaddr += tid % m_config->gpu_padded_cta_size; + thread_base = 4*(kernel_padded_threads_per_cta * (m_sid + num_shader * (tid / kernel_padded_threads_per_cta)) + + tid % kernel_padded_threads_per_cta); + max_concurrent_threads = kernel_padded_threads_per_cta * kernel_max_cta_per_shader * num_shader; } else { // legacy mapping that maps the same address in the local memory space of all threads // to a single contiguous address region - localaddr *= num_shader * m_config->n_thread_per_shader; - localaddr += (m_config->n_thread_per_shader *m_sid) + tid; + thread_base = 4*(m_config->n_thread_per_shader * m_sid + tid); + max_concurrent_threads = num_shader * m_config->n_thread_per_shader; } - localaddr *= 4; + assert( thread_base < 4/*word size*/*max_concurrent_threads ); - return localaddr; + address_type local_word = localaddr/4; + address_type word_offset = localaddr%4; + address_type linear_address = local_word*max_concurrent_threads + thread_base + word_offset; + return linear_address; } ///////////////////////////////////////////////////////////////////////////////////////// @@ -1181,19 +1194,29 @@ void ldst_unit::cycle() } } -void shader_core_ctx::register_cta_thread_exit(int tid ) +void shader_core_ctx::register_cta_thread_exit( unsigned cta_num ) { - unsigned padded_cta_size = m_gpu->the_kernel().threads_per_cta(); - if (padded_cta_size%m_config->warp_size) - padded_cta_size = ((padded_cta_size/m_config->warp_size)+1)*(m_config->warp_size); - int cta_num = tid/padded_cta_size; assert( m_cta_status[cta_num] > 0 ); m_cta_status[cta_num]--; if (!m_cta_status[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)\n", m_sid, cta_num, gpu_sim_cycle, gpu_tot_sim_cycle ); + 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.\n", m_sid ); + if( m_kernel->no_more_ctas_to_run() ) { + if( !m_kernel->running() ) { + m_gpu->set_kernel_done( m_kernel->get_uid() ); + printf("GPGPU-Sim uArch: GPU detected kernel \'%s\' finished on shader %u.\n", m_kernel->name().c_str(), m_sid ); + } + } + m_kernel=NULL; + fflush(stdout); + } } } @@ -1483,11 +1506,20 @@ unsigned int shader_core_config::max_cta( const kernel_info_t &k ) const printf ("\n"); } - if (result < 1) { - printf ("GPGPU-Sim uArch: ERROR ** Kernel requires more resources than shader has.\n"); - abort(); - } - return result; + //gpu_max_cta_per_shader is limited by number of CTAs if not enough to keep all cores busy + if( k.num_blocks() < result*num_shader() ) { + result = k.num_blocks() / num_shader(); + if (k.num_blocks() % num_shader()) + result++; + } + + assert( result <= MAX_CTA_PER_SHADER ); + if (result < 1) { + printf ("GPGPU-Sim uArch: ERROR ** Kernel requires more resources than shader has.\n"); + abort(); + } + + return result; } void shader_core_ctx::cycle() @@ -1712,6 +1744,16 @@ bool shader_core_ctx::warp_waiting_at_mem_barrier( unsigned warp_id ) return true; } +void shader_core_ctx::set_max_cta( const kernel_info_t &kernel ) +{ + // calculate the max cta count and cta size for local memory address mapping + kernel_max_cta_per_shader = m_config->max_cta(kernel); + unsigned int gpu_cta_size = kernel.threads_per_cta(); + kernel_padded_threads_per_cta = (gpu_cta_size%m_config->warp_size) ? + m_config->warp_size*((gpu_cta_size/m_config->warp_size)+1) : + gpu_cta_size; +} + gpgpu_sim *shader_core_ctx::get_gpu() { return m_gpu; @@ -2120,13 +2162,21 @@ unsigned simt_core_cluster::get_n_active_cta() const return n; } -unsigned simt_core_cluster::issue_block2core( class kernel_info_t &kernel ) +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_n_active_cta() < m_config->max_cta(kernel) ) { - m_core[core]->issue_block2core(kernel); + 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 = m_core[core]->get_kernel(); + if( kernel && !kernel->no_more_ctas_to_run() && (m_core[core]->get_n_active_cta() < m_config->max_cta(*kernel)) ) { + m_core[core]->issue_block2core(*kernel); num_blocks_issued++; m_cta_issue_next_core=core; break; diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 9200c99..7f41cfe 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -983,11 +983,8 @@ struct shader_core_config : public core_config unsigned gpgpu_shader_registers; int gpgpu_warpdistro_shader; unsigned gpgpu_num_reg_banks; - unsigned gpu_max_cta_per_shader; // TODO: modify this for fermi... computed based upon kernel - // resource usage; used in shader_core_ctx::translate_local_memaddr bool gpgpu_reg_bank_use_warp_id; bool gpgpu_local_mem_map; - int gpu_padded_cta_size; unsigned max_sp_latency; unsigned max_sfu_latency; @@ -1122,12 +1119,20 @@ public: void cache_flush(); void accept_fetch_response( mem_fetch *mf ); void accept_ldst_unit_response( class mem_fetch * mf ); + void set_kernel( kernel_info_t *k ) + { + assert(k); + m_kernel=k; + if(k) k->inc_running(); + printf("GPGPU-Sim uArch: Shader %d kernel = 0x%p\n", m_sid, m_kernel ); + } // accessors bool fetch_unit_response_buffer_full() const; bool ldst_unit_response_buffer_full() const; unsigned get_not_completed() const { return m_not_completed; } unsigned get_n_active_cta() const { return m_n_active_cta; } + kernel_info_t *get_kernel() { return m_kernel; } // used by functional simulation: // modifiers @@ -1148,6 +1153,7 @@ public: void dec_inst_in_pipeline( unsigned warp_id ) { 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 ); + void set_max_cta( const kernel_info_t &kernel ); // accessors std::list<unsigned> get_regs_written( const inst_t &fvt ) const; @@ -1163,7 +1169,7 @@ private: address_type next_pc( int tid ) const; void fetch(); - void register_cta_thread_exit(int cta_num ); + void register_cta_thread_exit( unsigned cta_num ); void decode(); void issue_warp( warp_inst_t *&warp, const warp_inst_t *pI, const active_mask_t &active_mask, unsigned warp_id ); @@ -1189,6 +1195,7 @@ private: const memory_config *m_memory_config; class simt_core_cluster *m_cluster; class gpgpu_sim *m_gpu; + kernel_info_t *m_kernel; // statistics shader_core_stats *m_stats; @@ -1228,6 +1235,10 @@ private: ldst_unit *m_ldst_unit; static const unsigned MAX_ALU_LATENCY = 64; std::bitset<MAX_ALU_LATENCY> m_result_bus; + + // used for local address mapping with single kernel launch + unsigned kernel_max_cta_per_shader; + unsigned kernel_padded_threads_per_cta; }; class simt_core_cluster { @@ -1243,7 +1254,7 @@ public: void icnt_cycle(); void reinit(); - unsigned issue_block2core( class kernel_info_t &kernel ); + unsigned issue_block2core(); void cache_flush(); bool icnt_injection_buffer_full(unsigned size, bool write); void icnt_inject_request_packet(class mem_fetch *mf); diff --git a/src/gpgpu-sim/stat-tool.cc b/src/gpgpu-sim/stat-tool.cc index 744a39d..576412c 100644 --- a/src/gpgpu-sim/stat-tool.cc +++ b/src/gpgpu-sim/stat-tool.cc @@ -152,7 +152,7 @@ unsigned translate_pc_to_ptxlineno(unsigned pc); static int n_thread_CFloggers = 0; static thread_CFlocality** thread_CFlogger = NULL; -void create_thread_CFlogger( int n_loggers, int n_threads, int n_insn, address_type start_pc, unsigned long long logging_interval) +void create_thread_CFlogger( int n_loggers, int n_threads, address_type start_pc, unsigned long long logging_interval) { destroy_thread_CFlogger(); @@ -163,7 +163,7 @@ void create_thread_CFlogger( int n_loggers, int n_threads, int n_insn, address_t char buffer[32]; for (int i = 0; i < n_thread_CFloggers; i++) { snprintf(buffer, 32, "%02d", i); - thread_CFlogger[i] = new thread_CFlocality( name_tpl + buffer, logging_interval, n_threads, n_insn, start_pc); + thread_CFlogger[i] = new thread_CFlocality( name_tpl + buffer, logging_interval, n_threads, start_pc); if (logging_interval != 0) { add_snap_shot_trigger(thread_CFlogger[i]); add_spill_log(thread_CFlogger[i]); @@ -222,10 +222,10 @@ int insn_warp_occ_logger::s_ids = 0; static std::vector<insn_warp_occ_logger> iwo_logger; -void insn_warp_occ_create( int n_loggers, int simd_width, int n_insn) +void insn_warp_occ_create( int n_loggers, int simd_width ) { iwo_logger.clear(); - iwo_logger.assign(n_loggers, insn_warp_occ_logger(simd_width, n_insn)); + iwo_logger.assign(n_loggers, insn_warp_occ_logger(simd_width)); for (unsigned i = 0; i < iwo_logger.size(); i++) { iwo_logger[i].set_id(i); } @@ -509,12 +509,12 @@ void shader_CTA_count_visualizer_gzprint( gzFile fout ) //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -thread_insn_span::thread_insn_span(unsigned long long cycle, int n_insn) - : m_cycle(cycle), m_n_insn(n_insn), +thread_insn_span::thread_insn_span(unsigned long long cycle) + : m_cycle(cycle), #ifdef USE_MAP m_insn_span_count() #else - m_insn_span_count(n_insn * 2) + m_insn_span_count(32*1024) #endif { } @@ -522,7 +522,7 @@ thread_insn_span::thread_insn_span(unsigned long long cycle, int n_insn) thread_insn_span::~thread_insn_span() { } thread_insn_span::thread_insn_span(const thread_insn_span& other) - : m_cycle(other.m_cycle), m_n_insn(other.m_n_insn), + : m_cycle(other.m_cycle), m_insn_span_count(other.m_insn_span_count) { } @@ -530,8 +530,7 @@ thread_insn_span::thread_insn_span(const thread_insn_span& other) thread_insn_span& thread_insn_span::operator=(const thread_insn_span& other) { printf("thread_insn_span& operator=\n"); - if (this != &other && m_n_insn != other.m_n_insn) { - m_n_insn = other.m_n_insn; + if (this != &other) { m_insn_span_count = other.m_insn_span_count; m_cycle = other.m_cycle; } @@ -540,7 +539,6 @@ thread_insn_span& thread_insn_span::operator=(const thread_insn_span& other) thread_insn_span& thread_insn_span::operator+=(const thread_insn_span& other) { - assert(m_n_insn == other.m_n_insn); // no way to aggregate if they are different programs span_count_map::const_iterator i_sc = other.m_insn_span_count.begin(); for (; i_sc != other.m_insn_span_count.end(); ++i_sc) { m_insn_span_count[i_sc->first] += i_sc->second; @@ -615,12 +613,11 @@ void thread_insn_span::print_sparse_histo(gzFile fout) const thread_CFlocality::thread_CFlocality(std::string name, unsigned long long snap_shot_interval, int nthreads, - int n_insn, address_type start_pc, unsigned long long start_cycle) : snap_shot_trigger(snap_shot_interval), m_name(name), m_nthreads(nthreads), m_thread_pc(nthreads, start_pc), m_cycle(start_cycle), - m_thd_span(start_cycle, n_insn) + m_thd_span(start_cycle) { std::fill(m_thread_pc.begin(), m_thread_pc.end(), -1); // so that hw thread with no work assigned will not clobber results } diff --git a/src/gpgpu-sim/stat-tool.h b/src/gpgpu-sim/stat-tool.h index 00b7771..31a1dcb 100644 --- a/src/gpgpu-sim/stat-tool.h +++ b/src/gpgpu-sim/stat-tool.h @@ -118,7 +118,7 @@ public: class thread_insn_span { public: - thread_insn_span(unsigned long long cycle, int n_insn); + thread_insn_span(unsigned long long cycle); thread_insn_span(const thread_insn_span& other); ~thread_insn_span(); @@ -135,14 +135,13 @@ public: private: typedef my_hash_map<address_type, int> span_count_map; unsigned long long m_cycle; - int m_n_insn; span_count_map m_insn_span_count; }; class thread_CFlocality : public snap_shot_trigger, public spill_log_interface { public: thread_CFlocality(std::string name, unsigned long long snap_shot_interval, - int nthreads, int n_insn, address_type start_pc, unsigned long long start_cycle = 0); + int nthreads, address_type start_pc, unsigned long long start_cycle = 0); ~thread_CFlocality(); void update_thread_pc( int thread_id, address_type pc ); @@ -170,9 +169,9 @@ private: class insn_warp_occ_logger { public: - insn_warp_occ_logger(int simd_width, int n_insn) + insn_warp_occ_logger(int simd_width) : m_simd_width(simd_width), - m_insn_warp_occ(n_insn, linear_histogram(1, "", m_simd_width)), + m_insn_warp_occ(1,linear_histogram(1, "", m_simd_width)), m_id(s_ids++) {} insn_warp_occ_logger(const insn_warp_occ_logger& other) @@ -191,7 +190,9 @@ public: void set_id(int id) { m_id = id; } void log(address_type pc, int warp_occ) { - m_insn_warp_occ[pc].add2bin(warp_occ - 1); + if( pc >= m_insn_warp_occ.size() ) + m_insn_warp_occ.resize(2*pc, linear_histogram(1, "", m_simd_width)); + m_insn_warp_occ[pc].add2bin(warp_occ - 1); } void print(FILE *fout) const @@ -307,7 +308,7 @@ void try_snap_shot (unsigned long long current_cycle); void set_spill_interval (unsigned long long interval); void spill_log_to_file (FILE *fout, int final, unsigned long long current_cycle); -void create_thread_CFlogger( int n_loggers, int n_threads, int n_insn, address_type start_pc, unsigned long long logging_interval); +void create_thread_CFlogger( int n_loggers, int n_threads, address_type start_pc, unsigned long long logging_interval); void destroy_thread_CFlogger( ); void cflog_update_thread_pc( int logger_id, int thread_id, address_type pc ); void cflog_snapshot( int logger_id, unsigned long long cycle ); @@ -316,7 +317,7 @@ void cflog_print_path_expression(FILE *fout); void cflog_visualizer_print(FILE *fout); void cflog_visualizer_gzprint(gzFile fout); -void insn_warp_occ_create( int n_loggers, int simd_width, int n_insn ); +void insn_warp_occ_create( int n_loggers, int simd_width ); void insn_warp_occ_log( int logger_id, address_type pc, int warp_occ ); void insn_warp_occ_print( FILE *fout ); |
