summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim')
-rw-r--r--src/gpgpu-sim/addrdec.cc3
-rw-r--r--src/gpgpu-sim/addrdec.h1
-rw-r--r--src/gpgpu-sim/dram.cc18
-rw-r--r--src/gpgpu-sim/dram.h4
-rw-r--r--src/gpgpu-sim/dram_sched.cc4
-rw-r--r--src/gpgpu-sim/gpu-sim.cc661
-rw-r--r--src/gpgpu-sim/gpu-sim.h151
-rw-r--r--src/gpgpu-sim/icnt_wrapper.cc5
-rw-r--r--src/gpgpu-sim/icnt_wrapper.h2
-rw-r--r--src/gpgpu-sim/l2cache.cc15
-rw-r--r--src/gpgpu-sim/l2cache.h2
-rw-r--r--src/gpgpu-sim/shader.cc320
-rw-r--r--src/gpgpu-sim/shader.h212
-rw-r--r--src/gpgpu-sim/stats.h47
-rw-r--r--src/gpgpu-sim/visualizer.cc120
-rw-r--r--src/gpgpu-sim/visualizer.h2
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);