diff options
Diffstat (limited to 'src/gpgpu-sim')
| -rw-r--r-- | src/gpgpu-sim/addrdec.cc | 3 | ||||
| -rw-r--r-- | src/gpgpu-sim/addrdec.h | 1 | ||||
| -rw-r--r-- | src/gpgpu-sim/dram.cc | 18 | ||||
| -rw-r--r-- | src/gpgpu-sim/dram.h | 4 | ||||
| -rw-r--r-- | src/gpgpu-sim/dram_sched.cc | 4 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 661 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.h | 151 | ||||
| -rw-r--r-- | src/gpgpu-sim/icnt_wrapper.cc | 5 | ||||
| -rw-r--r-- | src/gpgpu-sim/icnt_wrapper.h | 2 | ||||
| -rw-r--r-- | src/gpgpu-sim/l2cache.cc | 15 | ||||
| -rw-r--r-- | src/gpgpu-sim/l2cache.h | 2 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 320 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 212 | ||||
| -rw-r--r-- | src/gpgpu-sim/stats.h | 47 | ||||
| -rw-r--r-- | src/gpgpu-sim/visualizer.cc | 120 | ||||
| -rw-r--r-- | src/gpgpu-sim/visualizer.h | 2 |
16 files changed, 735 insertions, 832 deletions
diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc index 464aff0..f6f5018 100644 --- a/src/gpgpu-sim/addrdec.cc +++ b/src/gpgpu-sim/addrdec.cc @@ -93,6 +93,9 @@ void linear_to_raw_address_translation::addrdec_setoption(option_parser_t opp) option_parser_register(opp, "-gpgpu_mem_addr_mapping", OPT_CSTR, &addrdec_option, "mapping memory address to dram model {dramid@<start bit>;<memory address map>}", NULL); + option_parser_register(opp, "-gpgpu_mem_address_mask", OPT_INT32, &gpgpu_mem_address_mask, + "0 = old addressing mask, 1 = new addressing mask, 2 = new add. mask + flipped bank sel and chip sel bits", + "0"); } new_addr_type linear_to_raw_address_translation::partition_address( new_addr_type addr ) const diff --git a/src/gpgpu-sim/addrdec.h b/src/gpgpu-sim/addrdec.h index 60cbcf1..65fc059 100644 --- a/src/gpgpu-sim/addrdec.h +++ b/src/gpgpu-sim/addrdec.h @@ -106,6 +106,7 @@ private: }; const char *addrdec_option; + int gpgpu_mem_address_mask; int ADDR_CHIP_S; unsigned char addrdec_mklow[N_ADDRDEC]; diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc index a1187ec..9227310 100644 --- a/src/gpgpu-sim/dram.cc +++ b/src/gpgpu-sim/dram.cc @@ -102,9 +102,9 @@ dram_t::dram_t( unsigned int partition_id, const struct memory_config *config, m rwq = new fifo_pipeline<dram_req_t>("rwq",m_config->CL,m_config->CL+1); mrqq = new fifo_pipeline<dram_req_t>("mrqq",0,2); returnq = new fifo_pipeline<mem_fetch>("dramreturnq",0,m_config->gpgpu_dram_sched_queue_size); - m_fast_ideal_scheduler = NULL; + m_frfcfs_scheduler = NULL; if ( m_config->scheduler_type == DRAM_FRFCFS ) - m_fast_ideal_scheduler = new frfcfs_scheduler(m_config,this,stats); + m_frfcfs_scheduler = new frfcfs_scheduler(m_config,this,stats); n_cmd = 0; n_activity = 0; n_nop = 0; @@ -143,7 +143,7 @@ bool dram_t::full() const if( m_config->gpgpu_dram_sched_queue_size == 0 ) return false; if( m_config->scheduler_type == DRAM_FRFCFS ) - return m_fast_ideal_scheduler->num_pending() >= m_config->gpgpu_dram_sched_queue_size; + return m_frfcfs_scheduler->num_pending() >= m_config->gpgpu_dram_sched_queue_size; else return mrqq->full(); } @@ -152,7 +152,7 @@ unsigned dram_t::que_length() const { unsigned nreqs = 0; if (m_config->scheduler_type == DRAM_FRFCFS ) { - nreqs = m_fast_ideal_scheduler->num_pending(); + nreqs = m_frfcfs_scheduler->num_pending(); } else { nreqs = mrqq->get_length(); } @@ -199,7 +199,7 @@ void dram_t::push( class mem_fetch *data ) n_req += 1; n_req_partial += 1; if ( m_config->scheduler_type == DRAM_FRFCFS ) { - unsigned nreqs = m_fast_ideal_scheduler->num_pending(); + unsigned nreqs = m_frfcfs_scheduler->num_pending(); if ( nreqs > max_mrqs_temp) max_mrqs_temp = nreqs; } else { @@ -252,13 +252,13 @@ void dram_t::cycle() switch (m_config->scheduler_type) { case DRAM_FIFO: scheduler_fifo(); break; - case DRAM_FRFCFS: fast_scheduler_ideal(); break; + case DRAM_FRFCFS: scheduler_frfcfs(); break; default: printf("Error: Unknown DRAM scheduler type\n"); assert(0); } if ( m_config->scheduler_type == DRAM_FRFCFS ) { - unsigned nreqs = m_fast_ideal_scheduler->num_pending(); + unsigned nreqs = m_frfcfs_scheduler->num_pending(); if ( nreqs > max_mrqs) { max_mrqs = nreqs; } @@ -464,8 +464,8 @@ void dram_t::visualize() const printf("txf: %d %d", bk[i]->mrq->nbytes, bk[i]->mrq->txbytes); printf("\n"); } - if ( m_fast_ideal_scheduler ) - m_fast_ideal_scheduler->print(stdout); + if ( m_frfcfs_scheduler ) + m_frfcfs_scheduler->print(stdout); } void dram_t::print_stat( FILE* simFile ) diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h index 2a94a31..1a684c2 100644 --- a/src/gpgpu-sim/dram.h +++ b/src/gpgpu-sim/dram.h @@ -144,7 +144,7 @@ public: private: void scheduler_fifo(); - void fast_scheduler_ideal(); + void scheduler_frfcfs(); const struct memory_config *m_config; @@ -184,7 +184,7 @@ private: unsigned int max_mrqs; unsigned int ave_mrqs; - class frfcfs_scheduler* m_fast_ideal_scheduler; + class frfcfs_scheduler* m_frfcfs_scheduler; unsigned int n_cmd_partial; unsigned int n_activity_partial; diff --git a/src/gpgpu-sim/dram_sched.cc b/src/gpgpu-sim/dram_sched.cc index 8881e8f..9801313 100644 --- a/src/gpgpu-sim/dram_sched.cc +++ b/src/gpgpu-sim/dram_sched.cc @@ -166,10 +166,10 @@ void frfcfs_scheduler::print( FILE *fp ) } } -void dram_t::fast_scheduler_ideal() +void dram_t::scheduler_frfcfs() { unsigned mrq_latency; - frfcfs_scheduler *sched = m_fast_ideal_scheduler; + frfcfs_scheduler *sched = m_frfcfs_scheduler; while ( !mrqq->empty() && (!m_config->gpgpu_dram_sched_queue_size || sched->num_pending() < m_config->gpgpu_dram_sched_queue_size)) { dram_req_t *req = mrqq->pop(); req->data->set_status(IN_PARTITION_MC_INPUT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index a7b2ecf..e31ab67 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -1,5 +1,5 @@ /* - * gpu-sim.c + * gpu-sim.cc * * Copyright (c) 2009 by Tor M. Aamodt, Wilson W. L. Fung, Ali Bakhoda, * George L. Yuan, Ivan Sham, Henry Wong, Dan O'Connor and the @@ -110,35 +110,9 @@ unsigned long long gpu_sim_cycle = 0; unsigned long long gpu_tot_sim_cycle = 0; // performance counter for stalls due to congestion. -unsigned int gpu_stall_wr_back = 0; unsigned int gpu_stall_dramfull = 0; unsigned int gpu_stall_icnt2sh = 0; -//shader cannot send to icnt because icnt buffer is full -//Note: it is accumulative for all shaders and is never reset -//so it might increase 8 times in a cycle if we have 8 shaders -char *gpgpu_runtime_stat; -int gpu_stat_sample_freq = 10000; -int gpu_runtime_stat_flag = 0; - -unsigned long long gpu_max_cycle = 0; -unsigned long long gpu_max_insn = 0; -int g_total_cta_left; - -// GPGPU-Sim timing model options -int gpu_max_cycle_opt; -int gpu_max_insn_opt; -int gpu_max_cta_opt; -char *gpgpu_shader_core_pipeline_opt; -int gpgpu_dram_sched_queue_size; -bool gpgpu_flush_cache; -int gpgpu_mem_address_mask; -int gpgpu_cflog_interval; -char * gpgpu_clock_domains; -int g_ptx_inst_debug_to_file; -char* g_ptx_inst_debug_file; -int g_ptx_inst_debug_thread_uid; - /* Clock Domains */ #define CORE 0x01 @@ -150,14 +124,119 @@ int g_ptx_inst_debug_thread_uid; #define MEM_LATENCY_STAT_IMPL #include "mem_latency_stat.h" -void visualizer_options(option_parser_t opp); +void memory_config::reg_options(class OptionParser * opp) +{ + option_parser_register(opp, "-gpgpu_dram_scheduler", OPT_INT32, &scheduler_type, + "0 = fifo, 1 = FR-FCFS (defaul)", "1"); + option_parser_register(opp, "-gpgpu_dram_partition_queues", OPT_CSTR, &gpgpu_L2_queue_config, + "i2$:$2d:d2$:$2i", + "8:8:8:8"); + + option_parser_register(opp, "-l2_ideal", OPT_BOOL, &l2_ideal, + "Use a ideal L2 cache that always hit", + "0"); + option_parser_register(opp, "-gpgpu_cache:dl2", OPT_CSTR, &m_L2_config.m_config_string, + "unified banked L2 data cache config, i.e., {<nsets>:<bsize>:<assoc>:<repl>|none}; disabled by default", + NULL); + option_parser_register(opp, "-gpgpu_n_mem", OPT_UINT32, &m_n_mem, + "number of memory modules (e.g. memory controllers) in gpu", + "8"); + option_parser_register(opp, "-gpgpu_n_mem_per_ctrlr", OPT_UINT32, &gpu_n_mem_per_ctrlr, + "number of memory chips per memory controller", + "1"); + option_parser_register(opp, "-gpgpu_memlatency_stat", OPT_INT32, &gpgpu_memlatency_stat, + "track and display latency statistics 0x2 enables MC, 0x4 enables queue logs", + "0"); + option_parser_register(opp, "-gpgpu_dram_sched_queue_size", OPT_INT32, &gpgpu_dram_sched_queue_size, + "0 = unlimited (default); # entries per chip", + "0"); + option_parser_register(opp, "-gpgpu_dram_buswidth", OPT_UINT32, &busW, + "default = 4 bytes (8 bytes per cycle at DDR)", + "4"); + option_parser_register(opp, "-gpgpu_dram_burst_length", OPT_UINT32, &BL, + "Burst length of each DRAM request (default = 4 DDR cycle)", + "4"); + option_parser_register(opp, "-gpgpu_dram_timing_opt", OPT_CSTR, &gpgpu_dram_timing_opt, + "DRAM timing parameters = {nbk:tCCD:tRRD:tRCD:tRAS:tRP:tRC:CL:WL:tWTR}", + "4:2:8:12:21:13:34:9:4:5"); -void gpgpu_sim::reg_options(option_parser_t opp) + m_address_mapping.addrdec_setoption(opp); +} + +void shader_core_config::reg_options(class OptionParser * opp) { - option_parser_register(opp, "-gpgpu_simd_model", OPT_INT32, &m_shader_config->model, - "0 = no recombination, 1 = post-dominator, 2 = MIMD, 3 = dynamic warp formation", "0"); - option_parser_register(opp, "-gpgpu_dram_scheduler", OPT_INT32, &m_memory_config->scheduler_type, - "0 = fifo, 1 = FR-FCFS (defaul)", "1"); + option_parser_register(opp, "-gpgpu_simd_model", OPT_INT32, &model, + "1 = post-dominator", "1"); + option_parser_register(opp, "-gpgpu_shader_core_pipeline", OPT_CSTR, &gpgpu_shader_core_pipeline_opt, + "shader core pipeline config, i.e., {<nthread>:<warpsize>:<pipe_simd_width>}", + "256:32:32"); + option_parser_register(opp, "-gpgpu_tex_cache:l1", OPT_CSTR, &m_L1T_config.m_config_string, + "per-shader L1 texture cache (READ-ONLY) config, i.e., {<nsets>:<linesize>:<assoc>:<repl>|none}", + "512:64:2:L:R:m"); + option_parser_register(opp, "-gpgpu_const_cache:l1", OPT_CSTR, &m_L1C_config.m_config_string, + "per-shader L1 constant memory cache (READ-ONLY) config, i.e., {<nsets>:<linesize>:<assoc>:<repl>|none}", + "64:64:2:L:R:f"); + option_parser_register(opp, "-gpgpu_cache:il1", OPT_CSTR, &m_L1I_config.m_config_string, + "shader L1 instruction cache config, i.e., {<nsets>:<bsize>:<assoc>:<repl>|none}", + "4:256:4:L:R:f"); + option_parser_register(opp, "-gpgpu_perfect_mem", OPT_BOOL, &gpgpu_perfect_mem, + "enable perfect memory mode (no cache miss)", + "0"); + option_parser_register(opp, "-gpgpu_shader_registers", OPT_UINT32, &gpgpu_shader_registers, + "Number of registers per shader core. Limits number of concurrent CTAs. (default 8192)", + "8192"); + option_parser_register(opp, "-gpgpu_shader_cta", OPT_UINT32, &max_cta_per_core, + "Maximum number of concurrent CTAs in shader (default 8)", + "8"); + option_parser_register(opp, "-gpgpu_n_clusters", OPT_UINT32, &n_simt_clusters, + "number of processing clusters", + "10"); + option_parser_register(opp, "-gpgpu_n_cores_per_cluster", OPT_UINT32, &n_simt_cores_per_cluster, + "number of simd cores per cluster", + "3"); + option_parser_register(opp, "-gpgpu_n_cluster_ejection_buffer_size", OPT_UINT32, &n_simt_ejection_buffer_size, + "number of packets in ejection buffer", + "8"); + option_parser_register(opp, "-gpgpu_n_ldst_response_buffer_size", OPT_UINT32, &ldst_unit_response_queue_size, + "number of response packets in ld/st unit ejection buffer", + "2"); + option_parser_register(opp, "-gpgpu_shmem_size", OPT_UINT32, &gpgpu_shmem_size, + "Size of shared memory per shader core (default 16kB)", + "16384"); + option_parser_register(opp, "-gpgpu_shmem_warp_parts", OPT_INT32, &mem_warp_parts, + "Number of portions a warp is divided into for shared memory bank conflict check ", + "2"); + option_parser_register(opp, "-gpgpu_warpdistro_shader", OPT_INT32, &gpgpu_warpdistro_shader, + "Specify which shader core to collect the warp size distribution from", + "-1"); + option_parser_register(opp, "-gpgpu_local_mem_map", OPT_BOOL, &gpgpu_local_mem_map, + "Mapping from local memory space address to simulated GPU physical address space (default = enabled)", + "1"); + option_parser_register(opp, "-gpgpu_num_reg_banks", OPT_INT32, &gpgpu_num_reg_banks, + "Number of register banks (default = 8)", + "8"); + option_parser_register(opp, "-gpgpu_reg_bank_use_warp_id", OPT_BOOL, &gpgpu_reg_bank_use_warp_id, + "Use warp ID in mapping registers to banks (default = off)", + "0"); + option_parser_register(opp, "-gpgpu_operand_collector_num_units_sp", OPT_INT32, &gpgpu_operand_collector_num_units_sp, + "number of collector units (default = 4)", + "4"); + option_parser_register(opp, "-gpgpu_operand_collector_num_units_sfu", OPT_INT32, &gpgpu_operand_collector_num_units_sfu, + "number of collector units (default = 4)", + "4"); + option_parser_register(opp, "-gpgpu_operand_collector_num_units_mem", OPT_INT32, &gpgpu_operand_collector_num_units_mem, + "number of collector units (default = 2)", + "2"); + option_parser_register(opp, "-gpgpu_coalesce_arch", OPT_INT32, &gpgpu_coalesce_arch, + "Coalescing arch (default = 13, anything else is off for now)", + "13"); +} + +void gpgpu_sim_config::reg_options(option_parser_t opp) +{ + gpgpu_functional_sim_config::reg_options(opp); + m_shader_config.reg_options(opp); + m_memory_config.reg_options(opp); option_parser_register(opp, "-gpgpu_max_cycle", OPT_INT32, &gpu_max_cycle_opt, "terminates gpu simulation early (0 = no limit)", @@ -168,118 +247,15 @@ void gpgpu_sim::reg_options(option_parser_t opp) option_parser_register(opp, "-gpgpu_max_cta", OPT_INT32, &gpu_max_cta_opt, "terminates gpu simulation early (0 = no limit)", "0"); - - option_parser_register(opp, "-gpgpu_tex_cache:l1", OPT_CSTR, &m_shader_config->m_L1T_config.m_config_string, - "per-shader L1 texture cache (READ-ONLY) config, i.e., {<nsets>:<linesize>:<assoc>:<repl>|none}", - "512:64:2:L:R:m"); - - option_parser_register(opp, "-gpgpu_const_cache:l1", OPT_CSTR, &m_shader_config->m_L1C_config.m_config_string, - "per-shader L1 constant memory cache (READ-ONLY) config, i.e., {<nsets>:<linesize>:<assoc>:<repl>|none}", - "64:64:2:L:R:f"); - - option_parser_register(opp, "-gpgpu_cache:il1", OPT_CSTR, &m_shader_config->m_L1I_config.m_config_string, - "shader L1 instruction cache config, i.e., {<nsets>:<bsize>:<assoc>:<repl>|none}", - "4:256:4:L:R:f"); - - option_parser_register(opp, "-gpgpu_cache:dl2", OPT_CSTR, &m_memory_config->m_L2_config.m_config_string, - "unified banked L2 data cache config, i.e., {<nsets>:<bsize>:<assoc>:<repl>|none}; disabled by default", - NULL); - - option_parser_register(opp, "-gpgpu_perfect_mem", OPT_BOOL, &m_shader_config->gpgpu_perfect_mem, - "enable perfect memory mode (no cache miss)", - "0"); - - option_parser_register(opp, "-gpgpu_shader_core_pipeline", OPT_CSTR, &gpgpu_shader_core_pipeline_opt, - "shader core pipeline config, i.e., {<nthread>:<warpsize>:<pipe_simd_width>}", - "256:32:32"); - - option_parser_register(opp, "-gpgpu_shader_registers", OPT_UINT32, &m_shader_config->gpgpu_shader_registers, - "Number of registers per shader core. Limits number of concurrent CTAs. (default 8192)", - "8192"); - - option_parser_register(opp, "-gpgpu_shader_cta", OPT_UINT32, &m_shader_config->max_cta_per_core, - "Maximum number of concurrent CTAs in shader (default 8)", - "8"); - option_parser_register(opp, "-gpgpu_n_clusters", OPT_UINT32, &m_shader_config->n_simt_clusters, - "number of processing clusters", - "10"); - option_parser_register(opp, "-gpgpu_n_cores_per_cluster", OPT_UINT32, &m_shader_config->n_simt_cores_per_cluster, - "number of simd cores per cluster", - "3"); - option_parser_register(opp, "-gpgpu_n_cluster_ejection_buffer_size", OPT_UINT32, &m_shader_config->n_simt_ejection_buffer_size, - "number of packets in ejection buffer", - "8"); - option_parser_register(opp, "-gpgpu_n_ldst_response_buffer_size", OPT_UINT32, &m_shader_config->ldst_unit_response_queue_size, - "number of response packets in ld/st unit ejection buffer", - "2"); - option_parser_register(opp, "-gpgpu_n_mem", OPT_UINT32, &m_memory_config->m_n_mem, - "number of memory modules (e.g. memory controllers) in gpu", - "8"); - option_parser_register(opp, "-gpgpu_n_mem_per_ctrlr", OPT_UINT32, &m_memory_config->gpu_n_mem_per_ctrlr, - "number of memory chips per memory controller", - "1"); option_parser_register(opp, "-gpgpu_runtime_stat", OPT_CSTR, &gpgpu_runtime_stat, "display runtime statistics such as dram utilization {<freq>:<flag>}", "10000:0"); - - option_parser_register(opp, "-gpgpu_memlatency_stat", OPT_INT32, &m_memory_config->gpgpu_memlatency_stat, - "track and display latency statistics 0x2 enables MC, 0x4 enables queue logs", - "0"); - - option_parser_register(opp, "-gpu_n_mshr_per_shader", OPT_UINT32, &m_shader_config->n_mshr_per_shader, - "Number of MSHRs per shader", - "64"); - - option_parser_register(opp, "-gpgpu_dram_sched_queue_size", OPT_INT32, &m_memory_config->gpgpu_dram_sched_queue_size, - "0 = unlimited (default); # entries per chip", - "0"); - - option_parser_register(opp, "-gpgpu_dram_buswidth", OPT_UINT32, &m_memory_config->busW, - "default = 4 bytes (8 bytes per cycle at DDR)", - "4"); - - option_parser_register(opp, "-gpgpu_dram_burst_length", OPT_UINT32, &m_memory_config->BL, - "Burst length of each DRAM request (default = 4 DDR cycle)", - "4"); - - option_parser_register(opp, "-gpgpu_dram_timing_opt", OPT_CSTR, &m_memory_config->gpgpu_dram_timing_opt, - "DRAM timing parameters = {nbk:tCCD:tRRD:tRCD:tRAS:tRP:tRC:CL:WL:tWTR}", - "4:2:8:12:21:13:34:9:4:5"); - - - option_parser_register(opp, "-gpgpu_mem_address_mask", OPT_INT32, &gpgpu_mem_address_mask, - "0 = old addressing mask, 1 = new addressing mask, 2 = new add. mask + flipped bank sel and chip sel bits", - "0"); - option_parser_register(opp, "-gpgpu_flush_cache", OPT_BOOL, &gpgpu_flush_cache, "Flush cache at the end of each kernel call", "0"); - - option_parser_register(opp, "-gpgpu_shmem_size", OPT_UINT32, &m_shader_config->gpgpu_shmem_size, - "Size of shared memory per shader core (default 16kB)", - "16384"); - - option_parser_register(opp, "-gpgpu_shmem_warp_parts", OPT_INT32, &m_shader_config->shmem_warp_parts, - "Number of portions a warp is divided into for shared memory bank conflict check ", - "2"); - option_parser_register(opp, "-gpgpu_deadlock_detect", OPT_BOOL, &gpu_deadlock_detect, "Stop the simulation at deadlock (1=on (default), 0=off)", "1"); - - option_parser_register(opp, "-gpgpu_warpdistro_shader", OPT_INT32, &m_shader_config->gpgpu_warpdistro_shader, - "Specify which shader core to collect the warp size distribution from", - "-1"); - - option_parser_register(opp, "-gpgpu_pdom_sched_type", OPT_INT32, &m_pdom_sched_type, - "0 = first ready warp found, 1 = random, 8 = loose round robin", - "8"); - - option_parser_register(opp, "-gpgpu_stall_on_use", OPT_BOOL, - &m_shader_config->gpgpu_stall_on_use, - "Enable stall-on-use", - "1"); - option_parser_register(opp, "-gpgpu_ptx_instruction_classification", OPT_INT32, &gpgpu_ptx_instruction_classification, "if enabled will classify ptx instruction types per kernel (Max 255 kernels now)", @@ -290,62 +266,19 @@ void gpgpu_sim::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_shmem_port_per_bank", OPT_INT32, &m_shader_config->gpgpu_shmem_port_per_bank, - "Number of access processed by a shared memory bank per cycle (default = 2)", - "2"); option_parser_register(opp, "-gpgpu_cflog_interval", OPT_INT32, &gpgpu_cflog_interval, "Interval between each snapshot in control flow logger", "0"); - option_parser_register(opp, "-gpgpu_local_mem_map", OPT_BOOL, &m_shader_config->gpgpu_local_mem_map, - "Mapping from local memory space address to simulated GPU physical address space (default = enabled)", - "1"); - option_parser_register(opp, "-gpgpu_num_reg_banks", OPT_INT32, &m_shader_config->gpgpu_num_reg_banks, - "Number of register banks (default = 8)", - "8"); - option_parser_register(opp, "-gpgpu_reg_bank_use_warp_id", OPT_BOOL, &m_shader_config->gpgpu_reg_bank_use_warp_id, - "Use warp ID in mapping registers to banks (default = off)", - "0"); - option_parser_register(opp, "-gpgpu_ptx_inst_debug_to_file", OPT_BOOL, - &g_ptx_inst_debug_to_file, - "Dump executed instructions' debug information to file", - "0"); - option_parser_register(opp, "-gpgpu_ptx_inst_debug_file", OPT_CSTR, &g_ptx_inst_debug_file, - "Executed instructions' debug output file", - "inst_debug.txt"); - option_parser_register(opp, "-gpgpu_ptx_inst_debug_thread_uid", OPT_INT32, &g_ptx_inst_debug_thread_uid, - "Thread UID for executed instructions' debug output", - "1"); - option_parser_register(opp, "-gpgpu_ptx_convert_to_ptxplus", OPT_BOOL, - &m_ptx_convert_to_ptxplus, - "Convert embedded ptx to ptxplus", - "0"); - option_parser_register(opp, "-gpgpu_ptx_save_converted_ptxplus", OPT_BOOL, - &m_ptx_save_converted_ptxplus, - "Saved converted ptxplus to a file", - "0"); - option_parser_register(opp, "-gpgpu_ptx_force_max_capability", OPT_UINT32, - &m_ptx_force_max_capability, - "Force maximum compute capability", - "0"); - option_parser_register(opp, "-gpgpu_operand_collector_num_units_sp", OPT_INT32, &m_shader_config->gpgpu_operand_collector_num_units_sp, - "number of collector units (default = 4)", - "4"); - option_parser_register(opp, "-gpgpu_operand_collector_num_units_sfu", OPT_INT32, &m_shader_config->gpgpu_operand_collector_num_units_sfu, - "number of collector units (default = 4)", - "4"); - option_parser_register(opp, "-gpgpu_operand_collector_num_units_mem", OPT_INT32, &m_shader_config->gpgpu_operand_collector_num_units_mem, - "number of collector units (default = 2)", - "2"); - option_parser_register(opp, "-gpgpu_coalesce_arch", OPT_INT32, &m_shader_config->gpgpu_coalesce_arch, - "Coalescing arch (default = 13, anything else is off for now)", - "13"); - m_memory_config->m_address_mapping.addrdec_setoption(opp); - L2c_options(opp); - visualizer_options(opp); + option_parser_register(opp, "-visualizer_enabled", OPT_BOOL, + &g_visualizer_enabled, "Turn on visualizer output (1=On, 0=Off)", + "1"); + option_parser_register(opp, "-visualizer_outputfile", OPT_CSTR, + &g_visualizer_filename, "Specifies the output log file for visualizer", + NULL); + option_parser_register(opp, "-visualizer_zlevel", OPT_INT32, + &g_visualizer_zlevel, "Compression level of the visualizer output log (0=no comp, 9=highest)", + "6"); ptx_file_line_stats_options(opp); - - m_options_set = true; } ///////////////////////////////////////////////////////////////////////////// @@ -380,76 +313,44 @@ void gpgpu_sim::launch( kernel_info_t &kinfo ) m_running_kernels.push_back(kinfo); } -void gpgpu_sim::next_grid() +kernel_info_t *gpgpu_sim::next_grid() { m_the_kernel = m_running_kernels.front(); m_running_kernels.pop_front(); -} - -gpgpu_sim::gpgpu_sim() -{ - m_options_set=false; - m_shader_config = new shader_core_config(); - m_memory_config = new memory_config(); - m_shader_stats = (shader_core_stats*) calloc(1,sizeof(shader_core_stats)); - m_memory_stats = NULL; - gpu_sim_insn = 0; - gpu_tot_sim_insn = 0; - gpu_tot_issued_cta = 0; - gpu_tot_completed_thread = 0; - gpu_deadlock = false; + return &m_the_kernel; } void set_ptx_warp_size(const struct core_config * warp_size); -void gpgpu_sim::init_gpu() -{ - assert( m_options_set ); - - gpu_max_cycle = gpu_max_cycle_opt; - gpu_max_insn = gpu_max_insn_opt; - - int ntok = sscanf(gpgpu_shader_core_pipeline_opt,"%d:%d", - &m_shader_config->n_thread_per_shader, - &m_shader_config->warp_size); - set_ptx_warp_size(m_shader_config); - - m_shader_config->init(); - m_memory_config->init(); - - ptx_set_tex_cache_linesize(m_shader_config->m_L1T_config.get_line_sz()); - - m_shader_stats->num_warps_issuable = (int*) calloc(m_shader_config->max_warps_per_shader+1, sizeof(int)); - m_shader_stats->num_warps_issuable_pershader = (int*) calloc(m_shader_config->n_simt_clusters*m_shader_config->n_simt_cores_per_cluster, sizeof(int)); - m_shader_stats->shader_cycle_distro = (unsigned int*) calloc(m_shader_config->warp_size + 3, sizeof(unsigned int)); - - if(ntok != 2) { - printf("GPGPU-Sim uArch: error while parsing configuration string gpgpu_shader_core_pipeline_opt\n"); - abort(); - } - - sscanf(gpgpu_runtime_stat, "%d:%x", &gpu_stat_sample_freq, &gpu_runtime_stat_flag); - - m_shader_config->pdom_sched_type = m_pdom_sched_type; - m_shader_config->num_shmem_bank=16; +gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config ) + : gpgpu_t(config), m_config(config) +{ + m_shader_config = &m_config.m_shader_config; + m_memory_config = &m_config.m_memory_config; + set_ptx_warp_size(m_shader_config); + ptx_file_line_stats_create_exposed_latency_tracker(m_config.num_shader()); - m_cluster = new simt_core_cluster*[m_shader_config->n_simt_clusters]; - for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) - m_cluster[i] = new simt_core_cluster(this,i,m_shader_config,m_memory_config,m_shader_stats); + m_shader_stats = new shader_core_stats(m_shader_config); + m_memory_stats = new memory_stats_t(m_config.num_shader(),m_shader_config,m_memory_config); - ptx_file_line_stats_create_exposed_latency_tracker(num_shader()); + gpu_sim_insn = 0; + gpu_tot_sim_insn = 0; + gpu_tot_issued_cta = 0; + gpu_tot_completed_thread = 0; + gpu_deadlock = false; - m_memory_stats = new memory_stats_t(num_shader(),m_shader_config,m_memory_config); + m_cluster = new simt_core_cluster*[m_shader_config->n_simt_clusters]; + for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) + m_cluster[i] = new simt_core_cluster(this,i,m_shader_config,m_memory_config,m_shader_stats); - m_memory_partition_unit = new memory_partition_unit*[m_memory_config->m_n_mem]; - for (unsigned i=0;i<m_memory_config->m_n_mem;i++) - m_memory_partition_unit[i] = new memory_partition_unit(i, m_memory_config, m_memory_stats); + m_memory_partition_unit = new memory_partition_unit*[m_memory_config->m_n_mem]; + for (unsigned i=0;i<m_memory_config->m_n_mem;i++) + m_memory_partition_unit[i] = new memory_partition_unit(i, m_memory_config, m_memory_stats); - icnt_init(m_shader_config->n_simt_clusters, m_memory_config->m_n_mem,m_shader_config); + icnt_init(m_shader_config->n_simt_clusters,m_memory_config->m_n_mem); - time_vector_create(NUM_MEM_REQ_STAT); - fprintf(stdout, "GPGPU-Sim uArch: performance model initialization complete.\n"); - init_clock_domains(); + time_vector_create(NUM_MEM_REQ_STAT); + fprintf(stdout, "GPGPU-Sim uArch: performance model initialization complete.\n"); } int gpgpu_sim::shared_mem_size() const @@ -469,7 +370,7 @@ int gpgpu_sim::wrp_size() const int gpgpu_sim::shader_clock() const { - return core_freq/1000; + return m_config.core_freq/1000; } void gpgpu_sim::set_prop( cudaDeviceProp *prop ) @@ -487,7 +388,7 @@ enum divergence_support_t gpgpu_sim::simd_model() const return m_shader_config->model; } -void gpgpu_sim::init_clock_domains(void ) +void gpgpu_sim_config::init_clock_domains(void ) { sscanf(gpgpu_clock_domains,"%lf:%lf:%lf:%lf", &core_freq, &icnt_freq, &l2_freq, &dram_freq); @@ -499,10 +400,6 @@ void gpgpu_sim::init_clock_domains(void ) icnt_period = 1/icnt_freq; dram_period = 1/dram_freq; l2_period = 1/l2_freq; - core_time = 0 ; - dram_time = 0 ; - icnt_time = 0; - l2_time = 0; printf("GPGPU-Sim uArch: clock freqs: %lf:%lf:%lf:%lf\n",core_freq,icnt_freq,l2_freq,dram_freq); printf("GPGPU-Sim uArch: clock periods: %.20lf:%.20lf:%.20lf:%.20lf\n",core_period,icnt_period,l2_period,dram_period); } @@ -530,60 +427,47 @@ unsigned int gpgpu_sim::run_gpu_sim() not_completed = 1; mem_busy = 1; icnt2mem_busy = 1; - more_thread = 1; + more_thread = true; + g_total_cta_left=0; gpu_sim_insn = 0; - m_shader_stats->gpu_sim_insn_no_ld_const = 0; - m_shader_stats->gpu_completed_thread = 0; + m_shader_stats->new_grid(); reinit_clock_domains(); - set_param_gpgpu_num_shaders(num_shader()); + 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 (gpu_max_cta_opt != 0) { - g_total_cta_left = gpu_max_cta_opt; + 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 (gpu_max_cta_opt != 0) { + 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 >= (unsigned)gpu_max_cta_opt) { + if (gpu_tot_issued_cta >= m_config.gpu_max_cta_opt) return 0; - } } - if (gpu_max_cycle && (gpu_tot_sim_cycle + gpu_sim_cycle) >= gpu_max_cycle) { + 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 (gpu_max_insn && (gpu_tot_sim_insn + gpu_sim_insn) >= gpu_max_insn) { + if (m_config.gpu_max_insn_opt && (gpu_tot_sim_insn + gpu_sim_insn) >= m_config.gpu_max_insn_opt) { return gpu_sim_cycle; } // initialize the control-flow, memory access, memory latency logger - create_thread_CFlogger( num_shader(), m_shader_config->n_thread_per_shader, program_size, 0, gpgpu_cflog_interval ); - shader_CTA_count_create( num_shader(), gpgpu_cflog_interval); - if (gpgpu_cflog_interval != 0) { - insn_warp_occ_create( num_shader(), m_shader_config->warp_size, program_size ); - shader_warp_occ_create( num_shader(), m_shader_config->warp_size, gpgpu_cflog_interval); - shader_mem_acc_create( num_shader(), m_memory_config->m_n_mem, 4, gpgpu_cflog_interval); - shader_mem_lat_create( num_shader(), gpgpu_cflog_interval); - shader_cache_access_create( num_shader(), 3, gpgpu_cflog_interval); - set_spill_interval (gpgpu_cflog_interval * 40); + 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); } - // calcaulte the max cta count and cta size for local memory address mapping - m_shader_config->gpu_max_cta_per_shader = m_cluster[0]->max_cta(entry.entry()); - //gpu_max_cta_per_shader is limited by number of CTAs if not enough - if (m_the_kernel.num_blocks() < m_shader_config->gpu_max_cta_per_shader*num_shader()) { - m_shader_config->gpu_max_cta_per_shader = (m_the_kernel.num_blocks() / num_shader()); - if (m_the_kernel.num_blocks() % num_shader()) - m_shader_config->gpu_max_cta_per_shader++; - } - unsigned int gpu_cta_size = m_the_kernel.threads_per_cta(); - m_shader_config->gpu_padded_cta_size = (gpu_cta_size%32) ? 32*((gpu_cta_size/32)+1) : gpu_cta_size; - - if (g_network_mode) { + if (g_network_mode) icnt_init_grid(); - } last_gpu_sim_insn = 0; while (not_completed || mem_busy || icnt2mem_busy) { @@ -595,17 +479,17 @@ unsigned int gpgpu_sim::run_gpu_sim() 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 (gpu_max_cycle && (gpu_tot_sim_cycle + gpu_sim_cycle) >= gpu_max_cycle) + if (m_config.gpu_max_cycle_opt && (gpu_tot_sim_cycle + gpu_sim_cycle) >= m_config.gpu_max_cycle_opt) break; - if (gpu_max_insn && (gpu_tot_sim_insn + gpu_sim_insn) >= gpu_max_insn) + if (m_config.gpu_max_insn_opt && (gpu_tot_sim_insn + gpu_sim_insn) >= m_config.gpu_max_insn_opt) break; - if (gpu_deadlock_detect && gpu_deadlock) + if (m_config.gpu_deadlock_detect && gpu_deadlock) break; } - m_memory_stats->memlatstat_lat_pw(num_shader(),m_shader_config->n_thread_per_shader,m_shader_config->warp_size); + m_memory_stats->memlatstat_lat_pw(m_config.num_shader(),m_shader_config->n_thread_per_shader,m_shader_config->warp_size); gpu_tot_sim_cycle += gpu_sim_cycle; gpu_tot_sim_insn += gpu_sim_insn; - gpu_tot_completed_thread += m_shader_stats->gpu_completed_thread; + gpu_tot_completed_thread += m_shader_stats->get_gpu_completed_thread(); ptx_file_line_stats_write_file(); @@ -617,7 +501,7 @@ unsigned int gpgpu_sim::run_gpu_sim() printf("----------------------------END-of-Interconnect-DETAILS-------------------------" ); } - if (gpu_deadlock_detect && gpu_deadlock) { + if (m_config.gpu_deadlock_detect && gpu_deadlock) { fflush(stdout); printf("GPGPU-Sim uArch: ERROR ** deadlock detected: last writeback core %u @ gpu_sim_cycle %u (+ gpu_tot_sim_cycle %u) (%u cycles ago)\n", gpu_sim_insn_last_update_sid, @@ -657,9 +541,7 @@ void gpgpu_sim::gpu_print_stat() const { printf("gpu_sim_cycle = %lld\n", gpu_sim_cycle); printf("gpu_sim_insn = %lld\n", gpu_sim_insn); - printf("gpu_sim_no_ld_const_insn = %lld\n", m_shader_stats->gpu_sim_insn_no_ld_const); printf("gpu_ipc = %12.4f\n", (float)gpu_sim_insn / gpu_sim_cycle); - printf("gpu_completed_thread = %lld\n", m_shader_stats->gpu_completed_thread); printf("gpu_tot_sim_cycle = %lld\n", gpu_tot_sim_cycle); printf("gpu_tot_sim_insn = %lld\n", gpu_tot_sim_insn); printf("gpu_tot_ipc = %12.4f\n", (float)gpu_tot_sim_insn / gpu_tot_sim_cycle); @@ -667,66 +549,19 @@ void gpgpu_sim::gpu_print_stat() const printf("gpu_tot_issued_cta = %lld\n", gpu_tot_issued_cta); // performance counter for stalls due to congestion. - printf("gpu_stall_by_MSHRwb= %d\n", m_shader_stats->gpu_stall_by_MSHRwb); - printf("gpu_stall_shd_mem = %d\n", m_shader_stats->gpu_stall_shd_mem ); - printf("gpu_stall_wr_back = %d\n", gpu_stall_wr_back ); printf("gpu_stall_dramfull = %d\n", gpu_stall_dramfull); - printf("gpu_stall_icnt2sh = %d\n", gpu_stall_icnt2sh ); - printf("gpu_stall_sh2icnt = %d\n", m_shader_stats->gpu_stall_sh2icnt ); - // performance counter that are not local to one shader - shader_print_accstats(stdout); + printf("gpu_stall_icnt2sh = %d\n", gpu_stall_icnt2sh ); + + m_shader_stats->print(stdout); + // performance counter that are not local to one shader m_memory_stats->memlatstat_print(m_memory_config->m_n_mem,m_memory_config->nbk); - // merge misses - printf("L1 read misses = %d\n", m_shader_stats->L1_read_miss); - printf("L1 write misses = %d\n", m_shader_stats->L1_write_miss); - printf("L1 write hit on misses = %d\n", m_shader_stats->L1_write_hit_on_miss); - printf("L1 writebacks = %d\n", m_shader_stats->L1_writeback); - printf("L1 texture misses = %d\n", m_shader_stats->L1_texture_miss); - printf("L1 const misses = %d\n", m_shader_stats->L1_const_miss); m_memory_stats->print(stdout); - - printf("gpgpu_n_mem_read_local = %d\n", m_shader_stats->gpgpu_n_mem_read_local); - printf("gpgpu_n_mem_write_local = %d\n", m_shader_stats->gpgpu_n_mem_write_local); - printf("gpgpu_n_mem_read_global = %d\n", m_shader_stats->gpgpu_n_mem_read_global); - printf("gpgpu_n_mem_write_global = %d\n", m_shader_stats->gpgpu_n_mem_write_global); - printf("gpgpu_n_mem_texture = %d\n", m_shader_stats->gpgpu_n_mem_texture); - printf("gpgpu_n_mem_const = %d\n", m_shader_stats->gpgpu_n_mem_const); - - //printf("max_n_mshr_used = "); - //for (unsigned i=0; i< m_n_shader; i++) printf("%d ", m_sc[i]->get_max_mshr_used() ); - //printf("\n"); - for (unsigned i=0;i<m_memory_config->m_n_mem;i++) m_memory_partition_unit[i]->print(stdout); -/* - unsigned a,m; - for (unsigned i=0, a=0, m=0;i<m_n_shader;i++) - m_sc[i]->L1cache_print(stdout,a,m); - printf("L1 Data Cache Total Miss Rate = %0.3f\n", (float)m/a); - for (i=0,a=0,m=0;i<m_n_shader;i++) - m_sc[i]->L1texcache_print(stdout,a,m); - printf("L1 Texture Cache Total Miss Rate = %0.3f\n", (float)m/a); - for (i=0,a=0,m=0;i<m_n_shader;i++) - m_sc[i]->L1constcache_print(stdout,a,m); - printf("L1 Const Cache Total Miss Rate = %0.3f\n", (float)m/a); -*/ if (m_memory_config->m_L2_config.get_num_lines()) L2c_print_cache_stat(); - - if (m_shader_config->model == POST_DOMINATOR) { - printf("num_warps_issuable:"); - for (unsigned i=0;i<(m_shader_config->max_warps_per_shader+1);i++) { - printf("%d ", m_shader_stats->num_warps_issuable[i]); - } - printf("\n"); - } - - printf("gpgpu_commit_pc_beyond_two = %d\n", m_shader_stats->gpgpu_commit_pc_beyond_two); - - print_shader_cycle_distro( stdout ); - - if (gpgpu_cflog_interval != 0) { + if (m_config.gpgpu_cflog_interval != 0) { spill_log_to_file (stdout, 1, gpu_sim_cycle); insn_warp_occ_print(stdout); } @@ -735,71 +570,17 @@ void gpgpu_sim::gpu_print_stat() const StatDisp( g_inst_op_classification_stat[g_ptx_kernel_count]); } time_vector_print(); - fflush(stdout); } // performance counter that are not local to one shader -void gpgpu_sim::shader_print_accstats( FILE* fout ) const -{ - fprintf(fout, "gpgpu_n_load_insn = %d\n", m_shader_stats->gpgpu_n_load_insn); - fprintf(fout, "gpgpu_n_store_insn = %d\n", m_shader_stats->gpgpu_n_store_insn); - fprintf(fout, "gpgpu_n_shmem_insn = %d\n", m_shader_stats->gpgpu_n_shmem_insn); - fprintf(fout, "gpgpu_n_tex_insn = %d\n", m_shader_stats->gpgpu_n_tex_insn); - fprintf(fout, "gpgpu_n_const_mem_insn = %d\n", m_shader_stats->gpgpu_n_const_insn); - fprintf(fout, "gpgpu_n_param_mem_insn = %d\n", m_shader_stats->gpgpu_n_param_insn); - - fprintf(fout, "gpgpu_n_shmem_bkconflict = %d\n", m_shader_stats->gpgpu_n_shmem_bkconflict); - fprintf(fout, "gpgpu_n_cache_bkconflict = %d\n", m_shader_stats->gpgpu_n_cache_bkconflict); - - fprintf(fout, "gpgpu_n_intrawarp_mshr_merge = %d\n", m_shader_stats->gpgpu_n_intrawarp_mshr_merge); - fprintf(fout, "gpgpu_n_cmem_portconflict = %d\n", m_shader_stats->gpgpu_n_cmem_portconflict); - - fprintf(fout, "gpgpu_stall_shd_mem[c_mem][bk_conf] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[C_MEM][BK_CONF]); - fprintf(fout, "gpgpu_stall_shd_mem[c_mem][mshr_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[C_MEM][MSHR_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[c_mem][icnt_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[C_MEM][ICNT_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[t_mem][mshr_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[T_MEM][MSHR_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[t_mem][icnt_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[T_MEM][ICNT_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[s_mem][bk_conf] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[S_MEM][BK_CONF]); - fprintf(fout, "gpgpu_stall_shd_mem[gl_mem][bk_conf] = %d\n", - m_shader_stats->gpu_stall_shd_mem_breakdown[G_MEM_LD][BK_CONF] + - m_shader_stats->gpu_stall_shd_mem_breakdown[G_MEM_ST][BK_CONF] + - m_shader_stats->gpu_stall_shd_mem_breakdown[L_MEM_LD][BK_CONF] + - m_shader_stats->gpu_stall_shd_mem_breakdown[L_MEM_ST][BK_CONF] - ); // coalescing stall at data cache - fprintf(fout, "gpgpu_stall_shd_mem[gl_mem][coal_stall] = %d\n", - m_shader_stats->gpu_stall_shd_mem_breakdown[G_MEM_LD][COAL_STALL] + - m_shader_stats->gpu_stall_shd_mem_breakdown[G_MEM_ST][COAL_STALL] + - m_shader_stats->gpu_stall_shd_mem_breakdown[L_MEM_LD][COAL_STALL] + - m_shader_stats->gpu_stall_shd_mem_breakdown[L_MEM_ST][COAL_STALL] - ); // coalescing stall + bank conflict at data cache - fprintf(fout, "gpgpu_stall_shd_mem[g_mem_ld][mshr_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[G_MEM_LD][MSHR_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[g_mem_ld][icnt_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[G_MEM_LD][ICNT_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[g_mem_ld][wb_icnt_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[G_MEM_LD][WB_ICNT_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[g_mem_ld][wb_rsrv_fail] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[G_MEM_LD][WB_CACHE_RSRV_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[g_mem_st][mshr_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[G_MEM_ST][MSHR_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[g_mem_st][icnt_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[G_MEM_ST][ICNT_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[g_mem_st][wb_icnt_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[G_MEM_ST][WB_ICNT_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[g_mem_st][wb_rsrv_fail] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[G_MEM_ST][WB_CACHE_RSRV_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[l_mem_ld][mshr_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[L_MEM_LD][MSHR_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[l_mem_ld][icnt_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[L_MEM_LD][ICNT_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[l_mem_ld][wb_icnt_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[L_MEM_LD][WB_ICNT_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[l_mem_ld][wb_rsrv_fail] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[L_MEM_LD][WB_CACHE_RSRV_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[l_mem_st][mshr_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[L_MEM_ST][MSHR_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[l_mem_st][icnt_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[L_MEM_ST][ICNT_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[l_mem_ld][wb_icnt_rc] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[L_MEM_ST][WB_ICNT_RC_FAIL]); - fprintf(fout, "gpgpu_stall_shd_mem[l_mem_ld][wb_rsrv_fail] = %d\n", m_shader_stats->gpu_stall_shd_mem_breakdown[L_MEM_ST][WB_CACHE_RSRV_FAIL]); - - fprintf(fout, "gpu_reg_bank_conflict_stalls = %d\n", m_shader_stats->gpu_reg_bank_conflict_stalls); -} - unsigned gpgpu_sim::threads_per_core() const { return m_shader_config->n_thread_per_shader; } -void gpgpu_sim::mem_instruction_stats(const warp_inst_t &inst) +void shader_core_ctx::mem_instruction_stats(const warp_inst_t &inst) { //this breaks some encapsulation: the is_[space] functions, if you change those, change this. switch (inst.space.get_type()) { @@ -807,24 +588,24 @@ void gpgpu_sim::mem_instruction_stats(const warp_inst_t &inst) case reg_space: break; case shared_space: - m_shader_stats->gpgpu_n_shmem_insn++; + m_stats->gpgpu_n_shmem_insn++; break; case const_space: - m_shader_stats->gpgpu_n_const_insn++; + m_stats->gpgpu_n_const_insn++; break; case param_space_kernel: case param_space_local: - m_shader_stats->gpgpu_n_param_insn++; + m_stats->gpgpu_n_param_insn++; break; case tex_space: - m_shader_stats->gpgpu_n_tex_insn++; + m_stats->gpgpu_n_tex_insn++; break; case global_space: case local_space: if( inst.is_store() ) - m_shader_stats->gpgpu_n_store_insn++; + m_stats->gpgpu_n_store_insn++; else - m_shader_stats->gpgpu_n_load_insn++; + m_stats->gpgpu_n_load_insn++; break; default: abort(); @@ -845,7 +626,7 @@ void shader_core_ctx::issue_block2core( kernel_info_t &kernel ) { // find a free CTA context unsigned free_cta_hw_id=(unsigned)-1; - unsigned max_concurrent_cta_this_kernel = max_cta(kernel.entry()); + 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++ ) { if( m_cta_status[i]==0 ) { @@ -889,16 +670,10 @@ void shader_core_ctx::issue_block2core( kernel_info_t &kernel ) // initialize the SIMT stacks and fetch hardware init_warps( free_cta_hw_id, start_thread, end_thread); - m_n_active_cta++; - g_total_cta_left-=1; // used for exiting early from simulation shader_CTA_count_log(m_sid, 1); - - printf("GPGPU-Sim uArch: Shader %d initialized CTA #%d with hw tids from %d to %d @(%lld,%lld)", - m_sid, free_cta_hw_id, start_thread, start_thread+nthreads_in_block, gpu_sim_cycle, gpu_tot_sim_cycle ); - printf(" active threads = %d\n", get_not_completed() ); - + printf("GPGPU-Sim uArch: core:%d, cta:%u initialized @(%lld,%lld)\n", m_sid, free_cta_hw_id, gpu_sim_cycle, gpu_tot_sim_cycle ); } /////////////////////////////////////////////////////////////////////////////////////////// @@ -917,23 +692,22 @@ int gpgpu_sim::next_clock_domain(void) { double smallest = min3(core_time,icnt_time,dram_time); int mask = 0x00; - if ( m_memory_config->m_L2_config.get_num_lines() //when no-L2 it will never be L2's turn - && (l2_time <= smallest) ) { + if ( l2_time <= smallest ) { smallest = l2_time; mask |= L2 ; - l2_time += l2_period; + l2_time += m_config.l2_period; } if ( icnt_time <= smallest ) { mask |= ICNT; - icnt_time += icnt_period; + icnt_time += m_config.icnt_period; } if ( dram_time <= smallest ) { mask |= DRAM; - dram_time += dram_period; + dram_time += m_config.dram_period; } if ( core_time <= smallest ) { mask |= CORE; - core_time += core_period; + core_time += m_config.core_period; } return mask; } @@ -1009,16 +783,18 @@ void gpgpu_sim::cycle() 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.entry()) ) && g_total_cta_left ) { - m_cluster[i]->issue_block2core( m_the_kernel ); - if (!g_total_cta_left) - more_thread = 0; - assert( g_total_cta_left > -1 ); + 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; } } // Flush the caches once all of threads are completed. - if (gpgpu_flush_cache) { + if (m_config.gpgpu_flush_cache) { int all_threads_complete = 1 ; for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) { if (m_cluster[i]->get_not_completed() == 0) @@ -1039,7 +815,7 @@ void gpgpu_sim::cycle() } } - if (!(gpu_sim_cycle % gpu_stat_sample_freq)) { + if (!(gpu_sim_cycle % m_config.gpu_stat_sample_freq)) { time_t days, hrs, minutes, sec; time_t curr_time; time(&curr_time); @@ -1055,44 +831,27 @@ void gpgpu_sim::cycle() (unsigned)days,(unsigned)hrs,(unsigned)minutes,(unsigned)sec, ctime(&curr_time)); fflush(stdout); - m_memory_stats->memlatstat_lat_pw(num_shader(),m_shader_config->n_thread_per_shader,m_shader_config->warp_size); + m_memory_stats->memlatstat_lat_pw(m_config.num_shader(),m_shader_config->n_thread_per_shader,m_shader_config->warp_size); visualizer_printstat(); - if (gpgpu_runtime_stat && (gpu_runtime_stat_flag != 0) ) { - if (gpu_runtime_stat_flag & GPU_RSTAT_BW_STAT) { + if (m_config.gpgpu_runtime_stat && (m_config.gpu_runtime_stat_flag != 0) ) { + if (m_config.gpu_runtime_stat_flag & GPU_RSTAT_BW_STAT) { for (unsigned i=0;i<m_memory_config->m_n_mem;i++) m_memory_partition_unit[i]->print_stat(stdout); printf("maxmrqlatency = %d \n", m_memory_stats->max_mrq_latency); printf("maxmflatency = %d \n", m_memory_stats->max_mf_latency); } - if (gpu_runtime_stat_flag & GPU_RSTAT_SHD_INFO) { + if (m_config.gpu_runtime_stat_flag & GPU_RSTAT_SHD_INFO) shader_print_runtime_stat( stdout ); - } - if (gpu_runtime_stat_flag & GPU_RSTAT_WARP_DIS) { + if (m_config.gpu_runtime_stat_flag & GPU_RSTAT_WARP_DIS) print_shader_cycle_distro( stdout ); - } - if (gpu_runtime_stat_flag & GPU_RSTAT_L1MISS) { + if (m_config.gpu_runtime_stat_flag & GPU_RSTAT_L1MISS) shader_print_l1_miss_stat( stdout ); - } - if (gpu_runtime_stat_flag & GPU_RSTAT_PDOM ) { - if (m_pdom_sched_type) { - printf ("pdom_original_warps_count %d \n",m_shader_stats->n_pdom_sc_orig_stat ); - printf ("pdom_single_warps_count %d \n",m_shader_stats->n_pdom_sc_single_stat ); - } - } - if (gpu_runtime_stat_flag & GPU_RSTAT_SCHED ) { - printf("Average Num. Warps Issuable per Shader:\n"); - for (unsigned i=0;i<num_shader();i++) { - printf("%2.2f ", (float) m_shader_stats->num_warps_issuable_pershader[i]/ gpu_stat_sample_freq); - m_shader_stats->num_warps_issuable_pershader[i] = 0; - } - printf("\n"); - } } } if (!(gpu_sim_cycle % 20000)) { // deadlock detection - if (gpu_deadlock_detect && gpu_sim_insn == last_gpu_sim_insn) { + if (m_config.gpu_deadlock_detect && gpu_sim_insn == last_gpu_sim_insn) { gpu_deadlock = true; } else { last_gpu_sim_insn = gpu_sim_insn; @@ -1103,7 +862,7 @@ void gpgpu_sim::cycle() } } -void shader_core_ctx::dump_istream_state( FILE *fout ) +void shader_core_ctx::dump_istream_state( FILE *fout ) const { fprintf(fout, "\n"); for (unsigned w=0; w < m_config->max_warps_per_shader; w++ ) diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 0c1a473..2065f2d 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -120,6 +120,7 @@ struct memory_config { m_L2_config.init(); m_valid = true; } + void reg_options(class OptionParser * opp); bool m_valid; cache_config m_L2_config; @@ -154,29 +155,105 @@ struct memory_config { linear_to_raw_address_translation m_address_mapping; }; -// global config -extern int gpgpu_mem_address_mask; -extern int gpu_runtime_stat_flag; -extern int gpgpu_cflog_interval; -extern bool g_interactive_debugger_enabled; -extern int g_ptx_inst_debug_to_file; -extern char* g_ptx_inst_debug_file; -extern int g_ptx_inst_debug_thread_uid; - -// global counters +// global counters and flags (please try not to add to this list!!!) extern unsigned long long gpu_sim_cycle; extern unsigned long long gpu_tot_sim_cycle; +extern bool g_interactive_debugger_enabled; + +class gpgpu_sim_config : public gpgpu_functional_sim_config { +public: + gpgpu_sim_config() { m_valid = false; } + void reg_options(class OptionParser * opp); + void init() + { + gpu_stat_sample_freq = 10000; + gpu_runtime_stat_flag = 0; + sscanf(gpgpu_runtime_stat, "%d:%x", &gpu_stat_sample_freq, &gpu_runtime_stat_flag); + m_shader_config.init(); + ptx_set_tex_cache_linesize(m_shader_config.m_L1T_config.get_line_sz()); + m_memory_config.init(); + init_clock_domains(); + + // initialize file name if it is not set + time_t curr_time; + time(&curr_time); + char *date = ctime(&curr_time); + char *s = date; + while (*s) { + if (*s == ' ' || *s == '\t' || *s == ':') *s = '-'; + if (*s == '\n' || *s == '\r' ) *s = 0; + s++; + } + char buf[1024]; + snprintf(buf,1024,"gpgpusim_visualizer__%s.log.gz",date); + g_visualizer_filename = strdup(buf); + + 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(); } + +private: + void init_clock_domains(void ); + + bool m_valid; + shader_core_config m_shader_config; + memory_config m_memory_config; + + // clock domains - frequency + double core_freq; + double icnt_freq; + double dram_freq; + double l2_freq; + double core_period; + double icnt_period; + double dram_period; + double l2_period; + + // GPGPU-Sim timing model options + unsigned gpu_max_cycle_opt; + unsigned gpu_max_insn_opt; + unsigned gpu_max_cta_opt; + char *gpgpu_runtime_stat; + bool gpgpu_flush_cache; + bool gpu_deadlock_detect; + int gpgpu_dram_sched_queue_size; + int gpgpu_cflog_interval; + char * gpgpu_clock_domains; + + // visualizer + bool g_visualizer_enabled; + char *g_visualizer_filename; + int g_visualizer_zlevel; + + // statistics collection + int gpu_stat_sample_freq; + int gpu_runtime_stat_flag; + + friend class gpgpu_sim; +}; class gpgpu_sim : public gpgpu_t { public: - gpgpu_sim(); + gpgpu_sim( const gpgpu_sim_config &config ); - void reg_options(class OptionParser * opp); - void init_gpu(); void set_prop( struct cudaDeviceProp *prop ); void launch( kernel_info_t &kinfo ); - void next_grid(); + kernel_info_t *next_grid(); unsigned run_gpu_sim(); @@ -190,29 +267,21 @@ public: const struct cudaDeviceProp *get_prop() const; enum divergence_support_t simd_model() const; - unsigned num_shader() const { return m_shader_config->n_simt_clusters*m_shader_config->n_simt_cores_per_cluster; } unsigned threads_per_core() const; - void mem_instruction_stats( const class warp_inst_t &inst); + const gpgpu_sim_config &get_config() const { return m_config; } void gpu_print_stat() const; void dump_pipeline( int mask, int s, int m ) const; - unsigned get_forced_max_capability() const { return m_ptx_force_max_capability; } - bool convert_to_ptxplus() const { return m_ptx_convert_to_ptxplus; } - bool saved_converted_ptxplus() const { return m_ptx_save_converted_ptxplus; } - private: // clocks - void init_clock_domains(void); void reinit_clock_domains(void); - int next_clock_domain(void); + int next_clock_domain(void); void cycle(); - void L2c_options(class OptionParser *opp); void L2c_print_cache_stat() const; void shader_print_runtime_stat( FILE *fout ); void shader_print_l1_miss_stat( FILE *fout ); - void shader_print_accstats( FILE* fout ) const; void visualizer_printstat(); void print_shader_cycle_distro( FILE *fout ) const; @@ -227,7 +296,8 @@ private: kernel_info_t m_the_kernel; std::list<kernel_info_t> m_running_kernels; - unsigned int more_thread; + unsigned g_total_cta_left; + bool more_thread; // time of next rising edge double core_time; @@ -239,34 +309,15 @@ private: bool gpu_deadlock; //// configuration parameters //// - bool m_options_set; - - // clock domains - frequency - double core_freq; - double icnt_freq; - double dram_freq; - double l2_freq; + const gpgpu_sim_config &m_config; - // clock period - double core_period; - double icnt_period; - double dram_period; - double l2_period; - - struct cudaDeviceProp *m_cuda_properties; - struct shader_core_config *m_shader_config; - struct memory_config *m_memory_config; - - int m_pdom_sched_type; - - bool gpu_deadlock_detect; - int m_ptx_convert_to_ptxplus; - int m_ptx_save_converted_ptxplus; - unsigned m_ptx_force_max_capability; + const struct cudaDeviceProp *m_cuda_properties; + const struct shader_core_config *m_shader_config; + const struct memory_config *m_memory_config; // stats - struct shader_core_stats *m_shader_stats; - class memory_stats_t *m_memory_stats; + class shader_core_stats *m_shader_stats; + class memory_stats_t *m_memory_stats; unsigned long long gpu_tot_issued_cta; unsigned long long gpu_tot_completed_thread; unsigned long long last_gpu_sim_insn; diff --git a/src/gpgpu-sim/icnt_wrapper.cc b/src/gpgpu-sim/icnt_wrapper.cc index 25238f9..3c2e941 100644 --- a/src/gpgpu-sim/icnt_wrapper.cc +++ b/src/gpgpu-sim/icnt_wrapper.cc @@ -85,12 +85,11 @@ void icnt_reg_options( class OptionParser * opp ) option_parser_register(opp, "-inter_config_file", OPT_CSTR, &g_network_config_filename, "Interconnection network config file", "mesh"); } -void icnt_init( unsigned int n_shader, unsigned int n_mem, struct shader_core_config *shader_config ) +void icnt_init( unsigned int n_shader, unsigned int n_mem ) { switch (g_network_mode) { - case INTERSIM: - init_interconnect(g_network_config_filename, n_shader, n_mem, shader_config ); + init_interconnect(g_network_config_filename, n_shader, n_mem ); icnt_has_buffer = interconnect_has_buffer; icnt_push = interconnect_push; icnt_pop = interconnect_pop; diff --git a/src/gpgpu-sim/icnt_wrapper.h b/src/gpgpu-sim/icnt_wrapper.h index ff8905d..d37755a 100644 --- a/src/gpgpu-sim/icnt_wrapper.h +++ b/src/gpgpu-sim/icnt_wrapper.h @@ -88,7 +88,7 @@ enum network_mode { N_NETWORK_MODE }; -void icnt_init( unsigned int n_shader, unsigned int n_mem, struct shader_core_config *shader_config ); +void icnt_init( unsigned int n_shader, unsigned int n_mem ); void icnt_reg_options( class OptionParser * opp ); #endif diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index 9c443f0..fa55d0b 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -83,21 +83,8 @@ #include "shader.h" #include "mem_latency_stat.h" -void gpgpu_sim::L2c_options(option_parser_t opp) -{ - option_parser_register(opp, "-gpgpu_dram_partition_queues", OPT_CSTR, &m_memory_config->gpgpu_L2_queue_config, - "i2$:$2d:d2$:$2i", - "8:8:8:8"); - - option_parser_register(opp, "-l2_ideal", OPT_BOOL, &m_memory_config->l2_ideal, - "Use a ideal L2 cache that always hit", - "0"); -} - -////////// - memory_partition_unit::memory_partition_unit( unsigned partition_id, - struct memory_config *config, + const struct memory_config *config, class memory_stats_t *stats ) { m_id = partition_id; diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h index 7d1a8b2..b80f384 100644 --- a/src/gpgpu-sim/l2cache.h +++ b/src/gpgpu-sim/l2cache.h @@ -77,7 +77,7 @@ class mem_fetch; class memory_partition_unit { public: - memory_partition_unit( unsigned partition_id, struct memory_config *config, class memory_stats_t *stats ); + memory_partition_unit( unsigned partition_id, const struct memory_config *config, class memory_stats_t *stats ); ~memory_partition_unit(); bool busy() const; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 79665cc..1b9ab0d 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -107,7 +107,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, unsigned tpc_id, const struct shader_core_config *config, const struct memory_config *mem_config, - struct shader_core_stats *stats ) + shader_core_stats *stats ) : m_barriers( config->max_warps_per_shader, config->max_cta_per_core ) { m_gpu = gpu; @@ -135,7 +135,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_thread[i].m_cta_id = -1; } - m_icnt = new shader_memory_interface(cluster); + m_icnt = new shader_memory_interface(this,cluster); // fetch m_last_warp_fetched = 0; @@ -320,13 +320,13 @@ void gpgpu_sim::get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *p m_cluster[cluster_id]->get_pdom_stack_top_info(sid,tid,pc,rpc); } -void shader_core_ctx::get_pdom_stack_top_info( unsigned tid, unsigned *pc, unsigned *rpc ) +void shader_core_ctx::get_pdom_stack_top_info( unsigned tid, unsigned *pc, unsigned *rpc ) const { unsigned warp_id = tid/m_config->warp_size; m_pdom_warp[warp_id]->get_pdom_stack_top_info(pc,rpc); } -void pdom_warp_ctx_t::get_pdom_stack_top_info( unsigned *pc, unsigned *rpc ) +void pdom_warp_ctx_t::get_pdom_stack_top_info( unsigned *pc, unsigned *rpc ) const { *pc = m_pc[m_stack_top]; *rpc = m_recvg_pc[m_stack_top]; @@ -364,18 +364,176 @@ void pdom_warp_ctx_t::print (FILE *fout) const } } -void gpgpu_sim::print_shader_cycle_distro( FILE *fout ) const +void shader_core_stats::print( FILE* fout ) const { + fprintf(fout,"gpu_sim_no_ld_const_insn = %lld\n", gpu_sim_insn_no_ld_const); + fprintf(fout,"gpu_completed_thread = %lld\n", gpu_completed_thread); + fprintf(fout,"gpu_stall_shd_mem = %d\n", gpu_stall_shd_mem ); + fprintf(fout,"gpu_stall_sh2icnt = %d\n", gpu_stall_sh2icnt ); + fprintf(fout,"L1 read misses = %d\n", L1_read_miss); + fprintf(fout,"L1 write misses = %d\n", L1_write_miss); + fprintf(fout,"L1 write hit on misses = %d\n", L1_write_hit_on_miss); + fprintf(fout,"L1 writebacks = %d\n", L1_writeback); + fprintf(fout,"L1 texture misses = %d\n", L1_texture_miss); + fprintf(fout,"L1 const misses = %d\n", L1_const_miss); + fprintf(fout,"gpgpu_n_mem_read_local = %d\n", gpgpu_n_mem_read_local); + fprintf(fout,"gpgpu_n_mem_write_local = %d\n", gpgpu_n_mem_write_local); + fprintf(fout,"gpgpu_n_mem_read_global = %d\n", gpgpu_n_mem_read_global); + fprintf(fout,"gpgpu_n_mem_write_global = %d\n", gpgpu_n_mem_write_global); + fprintf(fout,"gpgpu_n_mem_texture = %d\n", gpgpu_n_mem_texture); + fprintf(fout,"gpgpu_n_mem_const = %d\n", gpgpu_n_mem_const); + if( m_config->model == POST_DOMINATOR) { + fprintf(fout,"num_warps_issuable:"); + for (unsigned i=0;i<(m_config->max_warps_per_shader+1);i++) + fprintf(fout,"%d ", num_warps_issuable[i]); + fprintf(fout,"\n"); + } + fprintf(fout,"gpgpu_commit_pc_beyond_two = %d\n",gpgpu_commit_pc_beyond_two); +/* + unsigned a,m; + for (unsigned i=0, a=0, m=0;i<m_n_shader;i++) + m_sc[i]->L1cache_print(stdout,a,m); + printf("L1 Data Cache Total Miss Rate = %0.3f\n", (float)m/a); + for (i=0,a=0,m=0;i<m_n_shader;i++) + m_sc[i]->L1texcache_print(stdout,a,m); + printf("L1 Texture Cache Total Miss Rate = %0.3f\n", (float)m/a); + for (i=0,a=0,m=0;i<m_n_shader;i++) + m_sc[i]->L1constcache_print(stdout,a,m); + printf("L1 Const Cache Total Miss Rate = %0.3f\n", (float)m/a); +*/ + fprintf(fout, "gpgpu_n_load_insn = %d\n", gpgpu_n_load_insn); + fprintf(fout, "gpgpu_n_store_insn = %d\n", gpgpu_n_store_insn); + fprintf(fout, "gpgpu_n_shmem_insn = %d\n", gpgpu_n_shmem_insn); + fprintf(fout, "gpgpu_n_tex_insn = %d\n", gpgpu_n_tex_insn); + fprintf(fout, "gpgpu_n_const_mem_insn = %d\n", gpgpu_n_const_insn); + fprintf(fout, "gpgpu_n_param_mem_insn = %d\n", gpgpu_n_param_insn); + + fprintf(fout, "gpgpu_n_shmem_bkconflict = %d\n", gpgpu_n_shmem_bkconflict); + fprintf(fout, "gpgpu_n_cache_bkconflict = %d\n", gpgpu_n_cache_bkconflict); + + fprintf(fout, "gpgpu_n_intrawarp_mshr_merge = %d\n", gpgpu_n_intrawarp_mshr_merge); + fprintf(fout, "gpgpu_n_cmem_portconflict = %d\n", gpgpu_n_cmem_portconflict); + + fprintf(fout, "gpgpu_stall_shd_mem[c_mem][bk_conf] = %d\n", gpu_stall_shd_mem_breakdown[C_MEM][BK_CONF]); + fprintf(fout, "gpgpu_stall_shd_mem[c_mem][mshr_rc] = %d\n", gpu_stall_shd_mem_breakdown[C_MEM][MSHR_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[c_mem][icnt_rc] = %d\n", gpu_stall_shd_mem_breakdown[C_MEM][ICNT_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[t_mem][mshr_rc] = %d\n", gpu_stall_shd_mem_breakdown[T_MEM][MSHR_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[t_mem][icnt_rc] = %d\n", gpu_stall_shd_mem_breakdown[T_MEM][ICNT_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[s_mem][bk_conf] = %d\n", gpu_stall_shd_mem_breakdown[S_MEM][BK_CONF]); + fprintf(fout, "gpgpu_stall_shd_mem[gl_mem][bk_conf] = %d\n", + gpu_stall_shd_mem_breakdown[G_MEM_LD][BK_CONF] + + gpu_stall_shd_mem_breakdown[G_MEM_ST][BK_CONF] + + gpu_stall_shd_mem_breakdown[L_MEM_LD][BK_CONF] + + gpu_stall_shd_mem_breakdown[L_MEM_ST][BK_CONF] + ); // coalescing stall at data cache + fprintf(fout, "gpgpu_stall_shd_mem[gl_mem][coal_stall] = %d\n", + gpu_stall_shd_mem_breakdown[G_MEM_LD][COAL_STALL] + + gpu_stall_shd_mem_breakdown[G_MEM_ST][COAL_STALL] + + gpu_stall_shd_mem_breakdown[L_MEM_LD][COAL_STALL] + + gpu_stall_shd_mem_breakdown[L_MEM_ST][COAL_STALL] + ); // coalescing stall + bank conflict at data cache + fprintf(fout, "gpgpu_stall_shd_mem[g_mem_ld][mshr_rc] = %d\n", gpu_stall_shd_mem_breakdown[G_MEM_LD][MSHR_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[g_mem_ld][icnt_rc] = %d\n", gpu_stall_shd_mem_breakdown[G_MEM_LD][ICNT_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[g_mem_ld][wb_icnt_rc] = %d\n", gpu_stall_shd_mem_breakdown[G_MEM_LD][WB_ICNT_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[g_mem_ld][wb_rsrv_fail] = %d\n", gpu_stall_shd_mem_breakdown[G_MEM_LD][WB_CACHE_RSRV_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[g_mem_st][mshr_rc] = %d\n", gpu_stall_shd_mem_breakdown[G_MEM_ST][MSHR_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[g_mem_st][icnt_rc] = %d\n", gpu_stall_shd_mem_breakdown[G_MEM_ST][ICNT_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[g_mem_st][wb_icnt_rc] = %d\n", gpu_stall_shd_mem_breakdown[G_MEM_ST][WB_ICNT_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[g_mem_st][wb_rsrv_fail] = %d\n", gpu_stall_shd_mem_breakdown[G_MEM_ST][WB_CACHE_RSRV_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[l_mem_ld][mshr_rc] = %d\n", gpu_stall_shd_mem_breakdown[L_MEM_LD][MSHR_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[l_mem_ld][icnt_rc] = %d\n", gpu_stall_shd_mem_breakdown[L_MEM_LD][ICNT_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[l_mem_ld][wb_icnt_rc] = %d\n", gpu_stall_shd_mem_breakdown[L_MEM_LD][WB_ICNT_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[l_mem_ld][wb_rsrv_fail] = %d\n", gpu_stall_shd_mem_breakdown[L_MEM_LD][WB_CACHE_RSRV_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[l_mem_st][mshr_rc] = %d\n", gpu_stall_shd_mem_breakdown[L_MEM_ST][MSHR_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[l_mem_st][icnt_rc] = %d\n", gpu_stall_shd_mem_breakdown[L_MEM_ST][ICNT_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[l_mem_ld][wb_icnt_rc] = %d\n", gpu_stall_shd_mem_breakdown[L_MEM_ST][WB_ICNT_RC_FAIL]); + fprintf(fout, "gpgpu_stall_shd_mem[l_mem_ld][wb_rsrv_fail] = %d\n", gpu_stall_shd_mem_breakdown[L_MEM_ST][WB_CACHE_RSRV_FAIL]); + + fprintf(fout, "gpu_reg_bank_conflict_stalls = %d\n", gpu_reg_bank_conflict_stalls); + fprintf(fout, "Warp Occupancy Distribution:\n"); - fprintf(fout, "Stall:%d\t", m_shader_stats->shader_cycle_distro[0]); - fprintf(fout, "W0_Idle:%d\t", m_shader_stats->shader_cycle_distro[1]); - fprintf(fout, "W0_Mem:%d", m_shader_stats->shader_cycle_distro[2]); - for (unsigned i = 3; i < m_shader_config->warp_size + 3; i++) { - fprintf(fout, "\tW%d:%d", i-2, m_shader_stats->shader_cycle_distro[i]); - } + fprintf(fout, "Stall:%d\t", shader_cycle_distro[0]); + fprintf(fout, "W0_Idle:%d\t", shader_cycle_distro[1]); + fprintf(fout, "W0_Mem:%d", shader_cycle_distro[2]); + for (unsigned i = 3; i < m_config->warp_size + 3; i++) + fprintf(fout, "\tW%d:%d", i-2, shader_cycle_distro[i]); fprintf(fout, "\n"); } +void shader_core_stats::visualizer_print( gzFile visualizer_file ) +{ + // warp divergence breakdown + gzprintf(visualizer_file, "WarpDivergenceBreakdown:"); + unsigned int total=0; + unsigned int cf = (m_config->gpgpu_warpdistro_shader==-1)?m_config->num_shader():1; + gzprintf(visualizer_file, " %d", (shader_cycle_distro[0] - last_shader_cycle_distro[0]) / cf ); + gzprintf(visualizer_file, " %d", (shader_cycle_distro[1] - last_shader_cycle_distro[1]) / cf ); + gzprintf(visualizer_file, " %d", (shader_cycle_distro[2] - last_shader_cycle_distro[2]) / cf ); + for (unsigned i=0; i<m_config->warp_size+3; i++) { + if ( i>=3 ) { + total += (shader_cycle_distro[i] - last_shader_cycle_distro[i]); + if ( ((i-3) % (m_config->warp_size/8)) == ((m_config->warp_size/8)-1) ) { + gzprintf(visualizer_file, " %d", total / cf ); + total=0; + } + } + last_shader_cycle_distro[i] = shader_cycle_distro[i]; + } + gzprintf(visualizer_file,"\n"); + + // overall cache miss rates + gzprintf(visualizer_file, "Lonetexturemiss: %d\n", L1_texture_miss); + gzprintf(visualizer_file, "Loneconstmiss: %d\n", L1_const_miss); + gzprintf(visualizer_file, "Lonereadmiss: %d\n", L1_read_miss); + gzprintf(visualizer_file, "Lonewritemiss: %d\n", L1_write_miss); + gzprintf(visualizer_file, "gpucompletedthreads: %lld\n", gpu_completed_thread); + gzprintf(visualizer_file, "gpgpu_n_cache_bkconflict: %d\n", gpgpu_n_cache_bkconflict); + gzprintf(visualizer_file, "gpgpu_n_shmem_bkconflict: %d\n", gpgpu_n_shmem_bkconflict); + +/* + // instruction count per shader core + gzprintf(visualizer_file, "shaderinsncount: "); + for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) + for (unsigned j=0;j<m_shader_config->n_simt_cores_per_cluster;j++) + gzprintf(visualizer_file, "%u ",m_cluster[i]->get_core(j)->get_core_stats()->m_icount); + gzprintf(visualizer_file, "\n"); + // warp divergence per shader core + gzprintf(visualizer_file, "shaderwarpdiv: "); + for (unsigned i=0;i<m_n_shader;i++) + gzprintf(visualizer_file, "%u ", m_sc[i]->get_n_diverge()); + gzprintf(visualizer_file, "\n"); +*/ + +/* + gzprintf(visualizer_file, "CacheMissRate_GlobalLocalL1_All: "); + for (unsigned i=0;i<m_n_shader;i++) + gzprintf(visualizer_file, "%0.4f ", m_sc[i]->L1_windowed_cache_miss_rate(0)); + gzprintf(visualizer_file, "\n"); + gzprintf(visualizer_file, "CacheMissRate_TextureL1_All: "); + for (unsigned i=0;i<m_n_shader;i++) + gzprintf(visualizer_file, "%0.4f ", m_sc[i]->L1tex_windowed_cache_miss_rate(0)); + gzprintf(visualizer_file, "\n"); + gzprintf(visualizer_file, "CacheMissRate_ConstL1_All: "); + for (unsigned i=0;i<m_n_shader;i++) + gzprintf(visualizer_file, "%0.4f ", m_sc[i]->L1const_windowed_cache_miss_rate(0)); + gzprintf(visualizer_file, "\n"); + gzprintf(visualizer_file, "CacheMissRate_GlobalLocalL1_noMgHt: "); + for (unsigned i=0;i<m_n_shader;i++) + gzprintf(visualizer_file, "%0.4f ", m_sc[i]->L1_windowed_cache_miss_rate(1)); + gzprintf(visualizer_file, "\n"); + gzprintf(visualizer_file, "CacheMissRate_TextureL1_noMgHt: "); + for (unsigned i=0;i<m_n_shader;i++) + gzprintf(visualizer_file, "%0.4f ", m_sc[i]->L1tex_windowed_cache_miss_rate(1)); + gzprintf(visualizer_file, "\n"); + gzprintf(visualizer_file, "CacheMissRate_ConstL1_noMgHt: "); + for (unsigned i=0;i<m_n_shader;i++) + gzprintf(visualizer_file, "%0.4f ", m_sc[i]->L1const_windowed_cache_miss_rate(1)); + gzprintf(visualizer_file, "\n"); + // reset for next interval + for (unsigned i=0;i<m_n_shader;i++) + m_sc[i]->new_cache_window(); +*/ +} #define PROGRAM_MEM_START 0xF0000000 /* should be distinct from other memory spaces... check ptx_ir.h to verify this does not overlap @@ -487,9 +645,10 @@ void shader_core_ctx::issue_warp( warp_inst_t *&pipe_reg, const warp_inst_t *nex assert(next_inst->valid()); *pipe_reg = *next_inst; // static instruction information pipe_reg->issue( active_mask, warp_id, gpu_tot_sim_cycle + gpu_sim_cycle ); // dynamic instruction information + m_stats->shader_cycle_distro[2+pipe_reg->active_count()]++; func_exec_inst( *pipe_reg ); if( next_inst->op == BARRIER_OP ) - set_at_barrier(m_warp[warp_id].get_cta_id(),warp_id); + m_barriers.warp_reaches_barrier(m_warp[warp_id].get_cta_id(),warp_id); else if( next_inst->op == MEMORY_BARRIER_OP ) set_at_memory_barrier(warp_id); m_pdom_warp[warp_id]->pdom_update_warp_mask(); @@ -499,6 +658,10 @@ void shader_core_ctx::issue_warp( warp_inst_t *&pipe_reg, const warp_inst_t *nex void shader_core_ctx::decode() { + bool valid_inst = false; // there was one warp with a valid instruction to issue (didn't require flush due to control hazard) + bool ready_inst = false; // of the valid instructions, there was one not waiting for pending register writes + bool issued_inst = false; // of these we issued one + for ( unsigned i=0; i < m_config->max_warps_per_shader; i++ ) { unsigned warp_id = (m_last_warp_issued+1+i) % m_config->max_warps_per_shader; unsigned checked=0; @@ -514,27 +677,34 @@ void shader_core_ctx::decode() // control hazard m_warp[warp_id].set_next_pc(pc); m_warp[warp_id].ibuffer_flush(); - } else if ( !m_scoreboard->checkCollision(warp_id, pI) ) { - unsigned active_mask = m_pdom_warp[warp_id]->get_active_mask(); - assert( m_warp[warp_id].inst_in_pipeline() ); - if ( (pI->op == LOAD_OP) || (pI->op == STORE_OP) || (pI->op == MEMORY_BARRIER_OP) ) { - if( m_pipeline_reg[ID_OC_MEM]->empty() ) { - issue_warp(m_pipeline_reg[ID_OC_MEM],pI,active_mask,warp_id); - issued++; - } - } else { - bool sp_pipe_avail = m_pipeline_reg[ID_OC_SP]->empty(); - bool sfu_pipe_avail = m_pipeline_reg[ID_OC_SFU]->empty(); - if( sp_pipe_avail && (pI->op != SFU_OP) ) { - // always prefer SP pipe for operations that can use both SP and SFU pipelines - issue_warp(m_pipeline_reg[ID_OC_SP],pI,active_mask,warp_id); - issued++; - } else if ( (pI->op == SFU_OP) || (pI->op == ALU_SFU_OP) ) { - if( sfu_pipe_avail ) { - issue_warp(m_pipeline_reg[ID_OC_SFU],pI,active_mask,warp_id); + } else { + valid_inst = true; + if ( !m_scoreboard->checkCollision(warp_id, pI) ) { + ready_inst = true; + unsigned active_mask = m_pdom_warp[warp_id]->get_active_mask(); + assert( m_warp[warp_id].inst_in_pipeline() ); + if ( (pI->op == LOAD_OP) || (pI->op == STORE_OP) || (pI->op == MEMORY_BARRIER_OP) ) { + if( m_pipeline_reg[ID_OC_MEM]->empty() ) { + issue_warp(m_pipeline_reg[ID_OC_MEM],pI,active_mask,warp_id); issued++; + issued_inst=true; } - } + } else { + bool sp_pipe_avail = m_pipeline_reg[ID_OC_SP]->empty(); + bool sfu_pipe_avail = m_pipeline_reg[ID_OC_SFU]->empty(); + if( sp_pipe_avail && (pI->op != SFU_OP) ) { + // always prefer SP pipe for operations that can use both SP and SFU pipelines + issue_warp(m_pipeline_reg[ID_OC_SP],pI,active_mask,warp_id); + issued++; + issued_inst=true; + } else if ( (pI->op == SFU_OP) || (pI->op == ALU_SFU_OP) ) { + if( sfu_pipe_avail ) { + issue_warp(m_pipeline_reg[ID_OC_SFU],pI,active_mask,warp_id); + issued++; + issued_inst=true; + } + } + } } } } else if( valid ) { @@ -550,6 +720,19 @@ void shader_core_ctx::decode() break; } } + +// fprintf(fout, "Stall:%d\t", m_shader_stats->shader_cycle_distro[0]); +// fprintf(fout, "W0_Idle:%d\t", m_shader_stats->shader_cycle_distro[1]); +// fprintf(fout, "W0_Mem:%d", m_shader_stats->shader_cycle_distro[2]); + + // statistics: + if( !valid_inst ) + m_stats->shader_cycle_distro[0]++; // idle or control hazard + else if( !ready_inst ) + m_stats->shader_cycle_distro[1]++; // waiting for RAW hazards (possibly due to memory) + else if( !issued_inst ) + m_stats->shader_cycle_distro[2]++; // pipeline stalled + } address_type coalesced_segment(address_type addr, unsigned segment_size_lg2bytes) @@ -589,7 +772,9 @@ void shader_core_ctx::execute() { m_result_bus >>= 1; for( unsigned n=0; n < m_num_function_units; n++ ) { - m_fu[n]->cycle(); + unsigned multiplier = m_fu[n]->clock_multiplier(); + for( unsigned c=0; c < multiplier; c++ ) + m_fu[n]->cycle(); enum pipeline_stage_name_t issue_port = m_issue_port[n]; warp_inst_t *& issue_inst = m_pipeline_reg[ issue_port ]; if( !issue_inst->empty() && m_fu[n]->can_issue( *issue_inst ) ) { @@ -805,7 +990,7 @@ ldst_unit::ldst_unit( shader_memory_interface *icnt, const memory_config *mem_config, shader_core_stats *stats, unsigned sid, - unsigned tpc ) : pipelined_simd_unit(NULL,config,6), m_next_wb(config) + unsigned tpc ) : pipelined_simd_unit(NULL,config,3), m_next_wb(config) { m_memory_config = mem_config; m_icnt = icnt; @@ -888,6 +1073,11 @@ void ldst_unit::writeback() } } +unsigned ldst_unit::clock_multiplier() const +{ + return m_config->mem_warp_parts; +} + void ldst_unit::cycle() { for( unsigned stage=0; (stage+1)<m_pipeline_depth; stage++ ) @@ -942,9 +1132,9 @@ void ldst_unit::cycle() unsigned warp_id = pipe_reg.warp_id(); if( pipe_reg.is_load() ) { if( pipe_reg.space.get_type() == shared_space ) { - if( m_pipeline_reg[5]->empty() ) { + if( m_pipeline_reg[2]->empty() ) { // new shared memory request - move_warp(m_pipeline_reg[5],m_dispatch_reg); + move_warp(m_pipeline_reg[2],m_dispatch_reg); m_dispatch_reg->clear(); } } else { @@ -1091,7 +1281,7 @@ void shader_core_ctx::print_stage(unsigned int stage, FILE *fout ) const m_pipeline_reg[stage]->print(fout); } -void shader_core_ctx::display_pdom_state(FILE *fout, int mask ) +void shader_core_ctx::display_pdom_state(FILE *fout, int mask ) const { if ( (mask & 4) && m_config->model == POST_DOMINATOR ) { fprintf(fout,"warp status:\n"); @@ -1156,7 +1346,7 @@ void ldst_unit::print(FILE *fout) const m_L1T->display_state(fout); } -void shader_core_ctx::display_pipeline(FILE *fout, int print_mem, int mask ) +void shader_core_ctx::display_pipeline(FILE *fout, int print_mem, int mask ) const { fprintf(fout, "=================================================\n"); fprintf(fout, "shader %u at cycle %Lu+%Lu (%u threads running)\n", m_sid, @@ -1211,31 +1401,31 @@ void shader_core_ctx::display_pipeline(FILE *fout, int print_mem, int mask ) fprintf(fout, "\n"); } -unsigned int shader_core_ctx::max_cta( class function_info *kernel ) +unsigned int shader_core_config::max_cta( const kernel_info_t &k ) const { - unsigned int padded_cta_size; - - 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); + unsigned threads_per_cta = k.threads_per_cta(); + const class function_info *kernel = k.entry(); + unsigned int padded_cta_size = threads_per_cta; + if (padded_cta_size%warp_size) + padded_cta_size = ((padded_cta_size/warp_size)+1)*(warp_size); //Limit by n_threads/shader - unsigned int result_thread = m_config->n_thread_per_shader / padded_cta_size; + unsigned int result_thread = n_thread_per_shader / padded_cta_size; const struct gpgpu_ptx_sim_kernel_info *kernel_info = ptx_sim_kernel_info(kernel); //Limit by shmem/shader unsigned int result_shmem = (unsigned)-1; if (kernel_info->smem > 0) - result_shmem = m_config->gpgpu_shmem_size / kernel_info->smem; + result_shmem = gpgpu_shmem_size / kernel_info->smem; //Limit by register count, rounded up to multiple of 4. unsigned int result_regs = (unsigned)-1; if (kernel_info->regs > 0) - result_regs = m_config->gpgpu_shader_registers / (padded_cta_size * ((kernel_info->regs+3)&~3)); + result_regs = gpgpu_shader_registers / (padded_cta_size * ((kernel_info->regs+3)&~3)); //Limit by CTA - unsigned int result_cta = m_config->max_cta_per_core; + unsigned int result_cta = max_cta_per_core; unsigned result = result_thread; result = gs_min2(result, result_shmem); @@ -1254,7 +1444,7 @@ unsigned int shader_core_ctx::max_cta( class function_info *kernel ) } if (result < 1) { - printf ("Error: max_cta_per_shader(\"sid=%u\") returning %d. Kernel requires more resources than shader has?\n", m_sid, result); + printf ("GPGPU-Sim uArch: ERROR ** Kernel requires more resources than shader has.\n"); abort(); } return result; @@ -1461,11 +1651,6 @@ void barrier_set_t::dump() const fflush(stdout); } -void shader_core_ctx::set_at_barrier( unsigned cta_id, unsigned warp_id ) -{ - m_barriers.warp_reaches_barrier(cta_id,warp_id); -} - void shader_core_ctx::warp_exit( unsigned warp_id ) { m_barriers.warp_exit( warp_id ); @@ -1492,11 +1677,6 @@ bool shader_core_ctx::warp_waiting_at_mem_barrier( unsigned warp_id ) return true; } -bool shader_core_ctx::warp_waiting_for_atomics( unsigned warp_id ) const -{ - return m_warp[warp_id].get_n_atomic()>0; -} - gpgpu_sim *shader_core_ctx::get_gpu() { return m_gpu; @@ -1562,7 +1742,7 @@ bool shd_warp_t::waiting() } else if ( m_shader->warp_waiting_at_mem_barrier(m_warp_id) ) { // waiting for memory barrier return true; - } else if ( m_shader->warp_waiting_for_atomics(m_warp_id) ) { + } else if ( m_n_atomic >0 ) { // waiting for atomic operation to complete at memory: // this stall is not required for accurate timing model, but rather we // stall here since if a call/return instruction occurs in the meantime @@ -1844,7 +2024,7 @@ simt_core_cluster::simt_core_cluster( class gpgpu_sim *gpu, unsigned cluster_id, const struct shader_core_config *config, const struct memory_config *mem_config, - struct shader_core_stats *stats ) + shader_core_stats *stats ) { m_cta_issue_next_core=0; m_cluster_id=cluster_id; @@ -1868,12 +2048,12 @@ void simt_core_cluster::reinit() m_core[i]->reinit(0,m_config->n_thread_per_shader,true); } -unsigned simt_core_cluster::max_cta( class function_info *kernel ) +unsigned simt_core_cluster::max_cta( const kernel_info_t &kernel ) { - return m_config->n_simt_cores_per_cluster * m_core[0]->max_cta(kernel); + return m_config->n_simt_cores_per_cluster * m_config->max_cta(kernel); } -int simt_core_cluster::get_not_completed() const +unsigned simt_core_cluster::get_not_completed() const { unsigned not_completed=0; for( unsigned i=0; i < m_config->n_simt_cores_per_cluster; i++ ) @@ -1889,15 +2069,18 @@ unsigned simt_core_cluster::get_n_active_cta() const return n; } -void simt_core_cluster::issue_block2core( class kernel_info_t &kernel ) +unsigned simt_core_cluster::issue_block2core( class kernel_info_t &kernel ) { + 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)%m_config->n_simt_cores_per_cluster; - if( m_core[core]->get_n_active_cta() < m_core[core]->max_cta(kernel.entry()) ) { + if( m_core[core]->get_n_active_cta() < m_config->max_cta(kernel) ) { m_core[core]->issue_block2core(kernel); + num_blocks_issued++; break; } } + return num_blocks_issued; } void simt_core_cluster::cache_flush() @@ -1968,12 +2151,7 @@ void simt_core_cluster::icnt_cycle() } } -void simt_core_cluster::mem_instruction_stats(const class warp_inst_t &inst) -{ - m_gpu->mem_instruction_stats(inst); -} - -void simt_core_cluster::get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc ) +void simt_core_cluster::get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc ) const { unsigned cid = sid_to_cid(sid); m_core[cid]->get_pdom_stack_top_info(tid,pc,rpc); diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 278fafc..ce04e01 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -279,9 +279,9 @@ public: void pdom_update_warp_mask(); unsigned get_active_mask() const; - void get_pdom_stack_top_info( unsigned *pc, unsigned *rpc ); + void get_pdom_stack_top_info( unsigned *pc, unsigned *rpc ) const; unsigned get_rp() const; - void print(FILE*fp) const; + void print(FILE*fp) const; private: unsigned m_warp_id; @@ -735,6 +735,7 @@ public: virtual void cycle() = 0; // accessors + virtual unsigned clock_multiplier() const { return 1; } virtual bool can_issue( const warp_inst_t & ) const { return m_dispatch_reg->empty(); } virtual bool stallable() const = 0; virtual void print( FILE *fp ) const @@ -837,16 +838,19 @@ public: Scoreboard *scoreboard, const shader_core_config *config, const memory_config *mem_config, - shader_core_stats *stats, + class shader_core_stats *stats, unsigned sid, unsigned tpc ); // modifiers - virtual void cycle(); + virtual void cycle(); + void fill( mem_fetch *mf ); void flush(); void writeback(); // accessors + virtual unsigned clock_multiplier() const; + virtual bool can_issue( const warp_inst_t &inst ) const { switch(inst.op) { @@ -908,59 +912,137 @@ struct shader_core_config : public core_config { void init() { + int ntok = sscanf(gpgpu_shader_core_pipeline_opt,"%d:%d", + &n_thread_per_shader, + &warp_size); + if(ntok != 2) { + printf("GPGPU-Sim uArch: error while parsing configuration string gpgpu_shader_core_pipeline_opt\n"); + abort(); + } max_warps_per_shader = n_thread_per_shader/warp_size; assert( !(n_thread_per_shader % warp_size) ); - max_sfu_latency = 32; max_sp_latency = 32; - m_L1I_config.init(); m_L1T_config.init(); m_L1C_config.init(); gpgpu_cache_texl1_linesize = m_L1T_config.get_line_sz(); gpgpu_cache_constl1_linesize = m_L1C_config.get_line_sz(); - m_valid = true; } + void reg_options(class OptionParser * opp ); + unsigned max_cta( const kernel_info_t &k ) const; + unsigned num_shader() const { return n_simt_clusters*n_simt_cores_per_cluster; } - bool gpgpu_perfect_mem; - enum divergence_support_t model; - unsigned n_thread_per_shader; - unsigned max_warps_per_shader; - unsigned max_cta_per_core; //Limit on number of concurrent CTAs in shader core - unsigned pdom_sched_type; +// data + char *gpgpu_shader_core_pipeline_opt; + bool gpgpu_perfect_mem; + enum divergence_support_t model; + unsigned n_thread_per_shader; + unsigned max_warps_per_shader; + unsigned max_cta_per_core; //Limit on number of concurrent CTAs in shader core + + cache_config m_L1I_config; + cache_config m_L1T_config; + cache_config m_L1C_config; + + bool gpgpu_dwf_reg_bankconflict; + int gpgpu_operand_collector_num_units_sp; + int gpgpu_operand_collector_num_units_sfu; + int gpgpu_operand_collector_num_units_mem; + //Shader core resources + 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; + + unsigned n_simt_cores_per_cluster; + unsigned n_simt_clusters; + unsigned n_simt_ejection_buffer_size; + unsigned ldst_unit_response_queue_size; + + unsigned mem2device(unsigned memid) const { return memid + n_simt_clusters; } +}; - cache_config m_L1I_config; - cache_config m_L1T_config; - cache_config m_L1C_config; +struct shader_core_stats_pod { + unsigned gpgpu_n_load_insn; + unsigned gpgpu_n_store_insn; + unsigned gpgpu_n_shmem_insn; + unsigned gpgpu_n_tex_insn; + unsigned gpgpu_n_const_insn; + unsigned gpgpu_n_param_insn; + unsigned gpgpu_n_shmem_bkconflict; + unsigned gpgpu_n_cache_bkconflict; + int gpgpu_n_intrawarp_mshr_merge; + unsigned gpgpu_n_cmem_portconflict; + unsigned gpu_stall_shd_mem_breakdown[N_MEM_STAGE_ACCESS_TYPE][N_MEM_STAGE_STALL_TYPE]; + unsigned gpu_reg_bank_conflict_stalls; + unsigned *shader_cycle_distro; + unsigned *last_shader_cycle_distro; + unsigned L1_write_miss; + unsigned L1_read_miss; + unsigned L1_texture_miss; + unsigned L1_const_miss; + unsigned L1_write_hit_on_miss; + unsigned L1_writeback; + unsigned long long gpu_sim_insn_no_ld_const; + unsigned long long gpu_completed_thread; + unsigned gpgpu_commit_pc_beyond_two; + unsigned gpu_stall_shd_mem; + unsigned gpu_stall_sh2icnt; + int *num_warps_issuable; + int *num_warps_issuable_pershader; - unsigned n_mshr_per_shader; - bool gpgpu_dwf_reg_bankconflict; - int gpgpu_operand_collector_num_units_sp; - int gpgpu_operand_collector_num_units_sfu; - int gpgpu_operand_collector_num_units_mem; - bool gpgpu_stall_on_use; - //Shader core resources - unsigned gpgpu_shmem_size; - unsigned gpgpu_shader_registers; - int gpgpu_warpdistro_shader; - int gpgpu_shmem_port_per_bank; - 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; + //memory access classification + int gpgpu_n_mem_read_local; + int gpgpu_n_mem_write_local; + int gpgpu_n_mem_texture; + int gpgpu_n_mem_const; + int gpgpu_n_mem_read_global; + int gpgpu_n_mem_write_global; + int gpgpu_n_mem_read_inst; + + unsigned made_write_mfs; + unsigned made_read_mfs; +}; + +class shader_core_stats : private shader_core_stats_pod { +public: + shader_core_stats( const shader_core_config *config ) + { + m_config = config; + shader_core_stats_pod *pod = this; + memset(pod,0,sizeof(shader_core_stats_pod)); + + num_warps_issuable = (int*) calloc(config->max_warps_per_shader+1, sizeof(int)); + num_warps_issuable_pershader = (int*) calloc(config->n_simt_clusters*config->n_simt_cores_per_cluster, sizeof(int)); + shader_cycle_distro = (unsigned int*) calloc(config->warp_size+3, sizeof(unsigned int)); + last_shader_cycle_distro = (unsigned int*) calloc(m_config->warp_size+3, sizeof(unsigned int)); + } + void new_grid() + { + gpu_sim_insn_no_ld_const = 0; + gpu_completed_thread = 0; + } - unsigned max_sp_latency; - unsigned max_sfu_latency; + void visualizer_print( gzFile visualizer_file ); - unsigned n_simt_cores_per_cluster; - unsigned n_simt_clusters; - unsigned n_simt_ejection_buffer_size; - unsigned ldst_unit_response_queue_size; + unsigned long long get_gpu_completed_thread() const { return gpu_completed_thread; } + void print( FILE *fout ) const; - unsigned mem2device(unsigned memid) const { return memid + n_simt_clusters; } +private: + const shader_core_config *m_config; + + friend class shader_core_ctx; + friend class ldst_unit; + friend class simt_core_cluster; }; class shader_core_ctx : public core_t @@ -972,17 +1054,16 @@ public: unsigned tpc_id, const struct shader_core_config *config, const struct memory_config *mem_config, - struct shader_core_stats *stats ); + shader_core_stats *stats ); void issue_block2core( class kernel_info_t &kernel ); - void get_pdom_stack_top_info( unsigned tid, unsigned *pc, unsigned *rpc ); + void get_pdom_stack_top_info( unsigned tid, unsigned *pc, unsigned *rpc ) const; bool ptx_thread_done( unsigned hw_thread_id ) const; class ptx_thread_info *get_thread_state( unsigned hw_thread_id ); + void mem_instruction_stats(const warp_inst_t &inst); - virtual void set_at_barrier( unsigned cta_id, unsigned warp_id ); virtual void warp_exit( unsigned warp_id ); virtual bool warp_waiting_at_barrier( unsigned warp_id ) const; - virtual bool warp_waiting_for_atomics( unsigned warp_id ) const; virtual class gpgpu_sim *get_gpu(); void set_at_memory_barrier( unsigned warp_id ); bool warp_waiting_at_mem_barrier( unsigned warp_id ); @@ -995,17 +1076,16 @@ public: void reinit(unsigned start_thread, unsigned end_thread, bool reset_not_completed ); void init_warps(unsigned cta_id, unsigned start_thread, unsigned end_thread); - unsigned max_cta( class function_info *kernel ); void cache_flush(); - void display_pdom_state(FILE *fout, int mask ); - void display_pipeline( FILE *fout, int print_mem, int mask3bit ); + void display_pdom_state(FILE *fout, int mask ) const; + void display_pipeline( FILE *fout, int print_mem, int mask3bit ) const; void register_cta_thread_exit(int cta_num ); bool fetch_unit_response_buffer_full() const; void accept_fetch_response( mem_fetch *mf ); bool ldst_unit_response_buffer_full(); void accept_ldst_unit_response( class mem_fetch * mf ); void store_ack( class mem_fetch *mf ); - void dump_istream_state( FILE *fout ); + class ptx_thread_info* get_functional_thread( unsigned tid ) { return m_thread[tid].m_functional_model_thread_state; } std::list<unsigned> get_regs_written( const inst_t &fvt ) const; const shader_core_config *get_config() const { return m_config; } @@ -1020,8 +1100,9 @@ public: unsigned get_n_active_cta() const { return m_n_active_cta; } void inc_store_req( unsigned warp_id) { m_warp[warp_id].inc_store_req(); } void dec_inst_in_pipeline( unsigned warp_id ) { m_warp[warp_id].dec_inst_in_pipeline(); } - + private: + void dump_istream_state( FILE *fout ) const; address_type next_pc( int tid ) const; @@ -1047,9 +1128,9 @@ private: class gpgpu_sim *m_gpu; // statistics - struct shader_core_stats *m_stats; // pointer to single object shared by all shader cores in GPU + shader_core_stats *m_stats; unsigned int m_num_sim_insn; // number of instructions committed by this shader core - unsigned int m_n_diverge; // number of divergence occurred in this shader + unsigned int m_n_diverge; // number of divergence occurred in this shader // CTA scheduling / hardware thread allocation int m_n_active_cta; // number of Cooperative Thread Arrays (blocks) currently running on this shader. @@ -1092,30 +1173,28 @@ public: unsigned cluster_id, const struct shader_core_config *config, const struct memory_config *mem_config, - struct shader_core_stats *stats ); + shader_core_stats *stats ); void core_cycle(); void icnt_cycle(); void reinit(); - unsigned max_cta( class function_info *kernel ); - int get_not_completed() const; - unsigned get_n_active_cta() const; - void issue_block2core( class kernel_info_t &kernel ); + unsigned issue_block2core( class kernel_info_t &kernel ); void cache_flush(); - bool icnt_injection_buffer_full(unsigned size, bool write); void icnt_inject_request_packet(class mem_fetch *mf); - void mem_instruction_stats(const class warp_inst_t &inst); - void get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc ); + void get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc ) const; + unsigned max_cta( const kernel_info_t &kernel ); + unsigned get_not_completed() const; + unsigned get_n_active_cta() const; gpgpu_sim *get_gpu() { return m_gpu; } void display_pipeline( unsigned sid, FILE *fout, int print_mem, int mask ); private: - unsigned sid_to_cid( unsigned sid ) { return sid % m_config->n_simt_cores_per_cluster; } - unsigned cid_to_sid( unsigned cid ) { return m_cluster_id*m_config->n_simt_cores_per_cluster + cid; } + unsigned sid_to_cid( unsigned sid ) const { return sid % m_config->n_simt_cores_per_cluster; } + unsigned cid_to_sid( unsigned cid ) const { return m_cluster_id*m_config->n_simt_cores_per_cluster + cid; } unsigned m_cluster_id; gpgpu_sim *m_gpu; @@ -1129,19 +1208,20 @@ private: class shader_memory_interface : public mem_fetch_interface { public: - shader_memory_interface( simt_core_cluster *port ) { m_port=port; } + shader_memory_interface( shader_core_ctx *core, simt_core_cluster *cluster ) { m_core=core; m_cluster=cluster; } virtual bool full( unsigned size, bool write ) const { - return m_port->icnt_injection_buffer_full(size,write); + return m_cluster->icnt_injection_buffer_full(size,write); } virtual void push(mem_fetch *mf) { if( !mf->get_inst().empty() ) - m_port->mem_instruction_stats(mf->get_inst()); // not I$-fetch - m_port->icnt_inject_request_packet(mf); + m_core->mem_instruction_stats(mf->get_inst()); // not I$-fetch + m_cluster->icnt_inject_request_packet(mf); } private: - simt_core_cluster *m_port; + shader_core_ctx *m_core; + simt_core_cluster *m_cluster; }; #endif /* SHADER_H */ diff --git a/src/gpgpu-sim/stats.h b/src/gpgpu-sim/stats.h index 0abdb22..4b9f668 100644 --- a/src/gpgpu-sim/stats.h +++ b/src/gpgpu-sim/stats.h @@ -66,8 +66,6 @@ #ifndef STATS_INCLUDED #define STATS_INCLUDED - - enum mem_stage_access_type { C_MEM, T_MEM, @@ -90,50 +88,5 @@ enum mem_stage_stall_type { N_MEM_STAGE_STALL_TYPE }; -struct shader_core_stats -{ - unsigned int gpgpu_n_load_insn; - unsigned int gpgpu_n_store_insn; - unsigned int gpgpu_n_shmem_insn; - unsigned int gpgpu_n_tex_insn; - unsigned int gpgpu_n_const_insn; - unsigned int gpgpu_n_param_insn; - unsigned int gpgpu_n_shmem_bkconflict; - unsigned int gpgpu_n_cache_bkconflict; - int gpgpu_n_intrawarp_mshr_merge; - unsigned int gpgpu_n_cmem_portconflict; - unsigned int gpu_stall_shd_mem_breakdown[N_MEM_STAGE_ACCESS_TYPE][N_MEM_STAGE_STALL_TYPE]; - unsigned int gpu_reg_bank_conflict_stalls; - unsigned int *shader_cycle_distro; - unsigned int L1_write_miss; - unsigned int L1_read_miss; - unsigned int L1_texture_miss; - unsigned int L1_const_miss; - unsigned int L1_write_hit_on_miss; - unsigned int L1_writeback; - int *num_warps_issuable; - int *num_warps_issuable_pershader; - unsigned long long gpu_sim_insn_no_ld_const; - unsigned long long gpu_completed_thread; - unsigned int gpgpu_commit_pc_beyond_two; - unsigned int gpu_stall_by_MSHRwb; - unsigned int gpu_stall_shd_mem; - unsigned int gpu_stall_sh2icnt; - - //memory access classification - int gpgpu_n_mem_read_local; - int gpgpu_n_mem_write_local; - int gpgpu_n_mem_texture; - int gpgpu_n_mem_const; - int gpgpu_n_mem_read_global; - int gpgpu_n_mem_write_global; - int gpgpu_n_mem_read_inst; - - int n_pdom_sc_orig_stat; - int n_pdom_sc_single_stat; - - unsigned made_write_mfs; - unsigned made_read_mfs; -}; #endif diff --git a/src/gpgpu-sim/visualizer.cc b/src/gpgpu-sim/visualizer.cc index 730e0c9..a6f836c 100644 --- a/src/gpgpu-sim/visualizer.cc +++ b/src/gpgpu-sim/visualizer.cc @@ -75,153 +75,47 @@ static void time_vector_print_interval2gzfile(gzFile outfile); -bool g_visualizer_enabled; -char *g_visualizer_filename; -int g_visualizer_zlevel; - -void visualizer_options(option_parser_t opp) -{ - option_parser_register(opp, "-visualizer_enabled", OPT_BOOL, - &g_visualizer_enabled, "Turn on visualizer output (1=On, 0=Off)", - "1"); - - option_parser_register(opp, "-visualizer_outputfile", OPT_CSTR, - &g_visualizer_filename, "Specifies the output log file for visualizer", - NULL); - - option_parser_register(opp, "-visualizer_zlevel", OPT_INT32, - &g_visualizer_zlevel, "Compression level of the visualizer output log (0=no comp, 9=highest)", - "6"); - -} - void gpgpu_sim::visualizer_printstat() { gzFile visualizer_file = NULL; // gzFile is basically a pointer to a struct, so it is fine to initialize it as NULL - if ( !g_visualizer_enabled ) + if ( !m_config.g_visualizer_enabled ) return; - // initialize file name if it is not set - if ( g_visualizer_filename == NULL ) { - time_t curr_time; - time(&curr_time); - char *date = ctime(&curr_time); - char *s = date; - while (*s) { - if (*s == ' ' || *s == '\t' || *s == ':') *s = '-'; - if (*s == '\n' || *s == '\r' ) *s = 0; - s++; - } - char buf[1024]; - snprintf(buf,1024,"gpgpusim_visualizer__%s.log.gz",date); - g_visualizer_filename = strdup(buf); - } // clean the content of the visualizer log if it is the first time, otherwise attach at the end static bool visualizer_first_printstat = true; - visualizer_file = gzopen(g_visualizer_filename, (visualizer_first_printstat)? "w" : "a"); + + visualizer_file = gzopen(m_config.g_visualizer_filename, (visualizer_first_printstat)? "w" : "a"); if (visualizer_file == NULL) { printf("error - could not open visualizer trace file.\n"); exit(1); } - gzsetparams(visualizer_file, g_visualizer_zlevel, Z_DEFAULT_STRATEGY); + gzsetparams(visualizer_file, m_config.g_visualizer_zlevel, Z_DEFAULT_STRATEGY); visualizer_first_printstat = false; - - /* - // instruction count per shader core - gzprintf(visualizer_file, "shaderinsncount: "); - for (unsigned i=0;i<m_n_shader;i++) - gzprintf(visualizer_file, "%u ",m_sc[i]->get_num_sim_insn()); - gzprintf(visualizer_file, "\n"); - - // warp divergence per shader core - gzprintf(visualizer_file, "shaderwarpdiv: "); - for (unsigned i=0;i<m_n_shader;i++) - gzprintf(visualizer_file, "%u ", m_sc[i]->get_n_diverge()); - gzprintf(visualizer_file, "\n"); - */ - + cflog_visualizer_gzprint(visualizer_file); shader_CTA_count_visualizer_gzprint(visualizer_file); // per shader core cache miss rate -/* - gzprintf(visualizer_file, "CacheMissRate_GlobalLocalL1_All: "); - for (unsigned i=0;i<m_n_shader;i++) - gzprintf(visualizer_file, "%0.4f ", m_sc[i]->L1_windowed_cache_miss_rate(0)); - gzprintf(visualizer_file, "\n"); - gzprintf(visualizer_file, "CacheMissRate_TextureL1_All: "); - for (unsigned i=0;i<m_n_shader;i++) - gzprintf(visualizer_file, "%0.4f ", m_sc[i]->L1tex_windowed_cache_miss_rate(0)); - gzprintf(visualizer_file, "\n"); - gzprintf(visualizer_file, "CacheMissRate_ConstL1_All: "); - for (unsigned i=0;i<m_n_shader;i++) - gzprintf(visualizer_file, "%0.4f ", m_sc[i]->L1const_windowed_cache_miss_rate(0)); - gzprintf(visualizer_file, "\n"); - gzprintf(visualizer_file, "CacheMissRate_GlobalLocalL1_noMgHt: "); - for (unsigned i=0;i<m_n_shader;i++) - gzprintf(visualizer_file, "%0.4f ", m_sc[i]->L1_windowed_cache_miss_rate(1)); - gzprintf(visualizer_file, "\n"); - gzprintf(visualizer_file, "CacheMissRate_TextureL1_noMgHt: "); - for (unsigned i=0;i<m_n_shader;i++) - gzprintf(visualizer_file, "%0.4f ", m_sc[i]->L1tex_windowed_cache_miss_rate(1)); - gzprintf(visualizer_file, "\n"); - gzprintf(visualizer_file, "CacheMissRate_ConstL1_noMgHt: "); - for (unsigned i=0;i<m_n_shader;i++) - gzprintf(visualizer_file, "%0.4f ", m_sc[i]->L1const_windowed_cache_miss_rate(1)); - gzprintf(visualizer_file, "\n"); - // reset for next interval - for (unsigned i=0;i<m_n_shader;i++) - m_sc[i]->new_cache_window(); -*/ for (unsigned i=0;i<m_memory_config->m_n_mem;i++) m_memory_partition_unit[i]->visualizer_print(visualizer_file); + m_shader_stats->visualizer_print(visualizer_file); - // overall cache miss rates - gzprintf(visualizer_file, "Lonetexturemiss: %d\n", m_shader_stats->L1_texture_miss); - gzprintf(visualizer_file, "Loneconstmiss: %d\n", m_shader_stats->L1_const_miss); - gzprintf(visualizer_file, "Lonereadmiss: %d\n", m_shader_stats->L1_read_miss); - gzprintf(visualizer_file, "Lonewritemiss: %d\n", m_shader_stats->L1_write_miss); gzprintf(visualizer_file, "Ltwowritemiss: %d\n", m_memory_stats->L2_write_miss); gzprintf(visualizer_file, "Ltwowritehit: %d\n", m_memory_stats->L2_write_hit); gzprintf(visualizer_file, "Ltworeadmiss: %d\n", m_memory_stats->L2_read_miss); gzprintf(visualizer_file, "Ltworeadhit: %d\n", m_memory_stats->L2_read_hit); // latency stats - if (m_memory_stats->num_mfs) { + if (m_memory_stats->num_mfs) gzprintf(visualizer_file, "averagemflatency: %lld\n", m_memory_stats->mf_total_lat/m_memory_stats->num_mfs); - } // other parameters for graphing gzprintf(visualizer_file, "globalcyclecount: %lld\n", gpu_sim_cycle); gzprintf(visualizer_file, "globalinsncount: %lld\n", gpu_sim_insn); gzprintf(visualizer_file, "globaltotinsncount: %lld\n", gpu_tot_sim_insn); - gzprintf(visualizer_file, "gpucompletedthreads: %lld\n", m_shader_stats->gpu_completed_thread); - gzprintf(visualizer_file, "gpgpu_n_cache_bkconflict: %d\n", m_shader_stats->gpgpu_n_cache_bkconflict); - gzprintf(visualizer_file, "gpgpu_n_shmem_bkconflict: %d\n", m_shader_stats->gpgpu_n_shmem_bkconflict); - gzprintf(visualizer_file, "gpu_stall_by_MSHRwb: %d\n", m_shader_stats->gpu_stall_by_MSHRwb); - // warp divergence breakdown - static unsigned int *last_shader_cycle_distro = NULL; - if (!last_shader_cycle_distro) - last_shader_cycle_distro = (unsigned int*) calloc(m_shader_config->warp_size + 3, sizeof(unsigned int)); time_vector_print_interval2gzfile(visualizer_file); - gzprintf(visualizer_file, "WarpDivergenceBreakdown:"); - unsigned int total=0; - unsigned int cf = (m_shader_config->gpgpu_warpdistro_shader==-1)?num_shader():1; - gzprintf(visualizer_file, " %d", (m_shader_stats->shader_cycle_distro[0] - last_shader_cycle_distro[0]) / cf ); - gzprintf(visualizer_file, " %d", (m_shader_stats->shader_cycle_distro[2] - last_shader_cycle_distro[2]) / cf ); - for (unsigned i=0; i<m_shader_config->warp_size+3; i++) { - if ( i>=3 ) { - total += (m_shader_stats->shader_cycle_distro[i] - last_shader_cycle_distro[i]); - if ( ((i-3) % (m_shader_config->warp_size/8)) == ((m_shader_config->warp_size/8)-1) ) { - gzprintf(visualizer_file, " %d", total / cf ); - total=0; - } - } - last_shader_cycle_distro[i] = m_shader_stats->shader_cycle_distro[i]; - } - gzprintf(visualizer_file,"\n"); gzclose(visualizer_file); } diff --git a/src/gpgpu-sim/visualizer.h b/src/gpgpu-sim/visualizer.h index 8c74d53..35f51f0 100644 --- a/src/gpgpu-sim/visualizer.h +++ b/src/gpgpu-sim/visualizer.h @@ -65,8 +65,6 @@ #include <stdio.h> #include <zlib.h> -void visualizer_options(class OptionParser *opp); -void visualizer_printstat( class shader_core_ctx **sc, unsigned n_shader, class dram_t **dram, unsigned n_mem ); void time_vector_create(int size); void time_vector_print(void); void time_vector_update(unsigned int uid,int slot ,long int cycle,int type); |
