summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Aamodt <[email protected]>2010-10-24 00:36:19 -0800
committerTor Aamodt <[email protected]>2010-10-24 00:36:19 -0800
commit6eee7514ea8b72fbecd761c50ccfd3394edf2307 (patch)
tree1260a88984124f960251dba47142e950f4367be2
parent4da926e61569a069bac229e8ba649e600fc78a04 (diff)
1. adding top level configuration class and making shader and memory configuration
components of this class. 2. clock memory pipeline no. subwarp times for each shader clock and increase rob-size for texture cache (trying to improve correlation, currently at 0.9218) 3. start to modify shader stats to add back features for visualizer (warp divergence distribution kind of working again) passing cuda 3.1 regression and ptxplus correlation tests [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 7909]
-rw-r--r--aerialvision/guiclasses.py5
-rw-r--r--configs/QuadroFX5800/gpgpusim.config4
-rw-r--r--libcuda/cuda_runtime_api.cc10
-rw-r--r--libopencl/opencl_runtime_api.cc2
-rw-r--r--src/abstract_hardware_model.cc45
-rw-r--r--src/abstract_hardware_model.h71
-rw-r--r--src/cuda-sim/cuda-sim.cc37
-rw-r--r--src/cuda-sim/cuda-sim.h3
-rw-r--r--src/cuda-sim/ptx_ir.cc4
-rw-r--r--src/cuda-sim/ptx_ir.h3
-rw-r--r--src/cuda-sim/ptx_sim.h1
-rw-r--r--src/debug.cc2
-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
-rw-r--r--src/gpgpusim_entrypoint.cc38
-rw-r--r--src/intersim/interconnect_interface.cpp3
-rw-r--r--src/intersim/interconnect_interface.h3
31 files changed, 884 insertions, 914 deletions
diff --git a/aerialvision/guiclasses.py b/aerialvision/guiclasses.py
index 260b229..7e2379b 100644
--- a/aerialvision/guiclasses.py
+++ b/aerialvision/guiclasses.py
@@ -1042,8 +1042,9 @@ class graphManager:
if yAxis == 'WarpDivergenceBreakdown':
Legendname = []
- Legendname.append('Fetch Stalled')
- Legendname.append('W0')
+ Legendname.append('Idle')
+ Legendname.append('Data Hazard')
+ Legendname.append('Stall')
for c in range(2, numRows):
Legendname.append('W' + `4*(c-2)+1` + ':' + `4*(c-1)`)
BarSequence = range(0,numRows)
diff --git a/configs/QuadroFX5800/gpgpusim.config b/configs/QuadroFX5800/gpgpusim.config
index 3d7d218..e16fdd6 100644
--- a/configs/QuadroFX5800/gpgpusim.config
+++ b/configs/QuadroFX5800/gpgpusim.config
@@ -13,17 +13,15 @@
-gpgpu_shader_registers 16384
-gpgpu_shader_core_pipeline 1024:32:32
-gpgpu_shader_cta 8
--gpgpu_pdom_sched_type 8
-gpgpu_simd_model 1
# memory stage behaviour
-gpgpu_cache:il1 4:256:4:L:R:f,A:2:32,4
--gpgpu_tex_cache:l1 8:32:20:L:R:m,F:128:4,16:2
+-gpgpu_tex_cache:l1 8:32:20:L:R:m,F:128:4,32:2
-gpgpu_const_cache:l1 64:64:2:L:R:f,A:2:32,4
-gpgpu_cache:dl2 64:32:8:L:R:m,A:16:4,4
-gpgpu_shmem_warp_parts 2
--gpgpu_shmem_port_per_bank 2
# interconnection
-network_mode 1
diff --git a/libcuda/cuda_runtime_api.cc b/libcuda/cuda_runtime_api.cc
index 93f7512..1990076 100644
--- a/libcuda/cuda_runtime_api.cc
+++ b/libcuda/cuda_runtime_api.cc
@@ -183,7 +183,7 @@ void register_ptx_function( const char *name, function_info *impl )
struct _cuda_device_id {
_cuda_device_id(gpgpu_sim* gpu) {m_id = 0; m_next = NULL; m_gpgpu=gpu;}
struct _cuda_device_id *next() { return m_next; }
- unsigned num_shader() const { return m_gpgpu->num_shader(); }
+ unsigned num_shader() const { return m_gpgpu->get_config().num_shader(); }
int num_devices() const {
if( m_next == NULL ) return 1;
else return 1 + m_next->num_devices();
@@ -282,7 +282,7 @@ class _cuda_device_id *GPGPUSim_Init()
prop->warpSize = the_gpu->wrp_size();
prop->clockRate = the_gpu->shader_clock();
#if (CUDART_VERSION >= 2010)
- prop->multiProcessorCount = the_gpu->num_shader();
+ prop->multiProcessorCount = the_gpu->get_config().num_shader();
#endif
the_gpu->set_prop(prop);
the_device = new _cuda_device_id(the_gpu);
@@ -1103,7 +1103,7 @@ void** CUDARTAPI __cudaRegisterFatBinary( void *fatCubin )
unsigned max_capability=0;
unsigned selected_capability=0;
bool found=false;
- unsigned forced_max_capability = context->get_device()->get_gpgpu()->get_forced_max_capability();
+ unsigned forced_max_capability = context->get_device()->get_gpgpu()->get_config().get_forced_max_capability();
while( info->ptx[num_ptx_versions].gpuProfileName != NULL ) {
unsigned capability=0;
sscanf(info->ptx[num_ptx_versions].gpuProfileName,"compute_%u",&capability);
@@ -1129,9 +1129,9 @@ void** CUDARTAPI __cudaRegisterFatBinary( void *fatCubin )
info->ident, info->ptx[selected_capability].gpuProfileName );
symbol_table *symtab;
const char *ptx = info->ptx[selected_capability].ptx;
- if(context->get_device()->get_gpgpu()->convert_to_ptxplus() ) {
+ if(context->get_device()->get_gpgpu()->get_config().convert_to_ptxplus() ) {
char *ptxplus_str = gpgpu_ptx_sim_convert_ptx_to_ptxplus(ptx, info->cubin[selected_capability].cubin, source_num++,
- context->get_device()->get_gpgpu()->saved_converted_ptxplus());
+ context->get_device()->get_gpgpu()->get_config().saved_converted_ptxplus());
symtab=gpgpu_ptx_sim_load_ptx_from_string(ptxplus_str,source_num);
context->add_binary(symtab,fat_cubin_handle);
gpgpu_ptxinfo_load_from_string(ptx,source_num);
diff --git a/libopencl/opencl_runtime_api.cc b/libopencl/opencl_runtime_api.cc
index cca2b8d..c3f5e8a 100644
--- a/libopencl/opencl_runtime_api.cc
+++ b/libopencl/opencl_runtime_api.cc
@@ -1053,7 +1053,7 @@ clGetDeviceInfo(cl_device_id device,
switch( param_name ) {
case CL_DEVICE_NAME: CL_STRING_CASE( "GPGPU-Sim" ); break;
case CL_DEVICE_GLOBAL_MEM_SIZE: CL_ULONG_CASE( 1024*1024*1024 ); break;
- case CL_DEVICE_MAX_COMPUTE_UNITS: CL_INT_CASE( device->the_device()->num_shader() ); break;
+ case CL_DEVICE_MAX_COMPUTE_UNITS: CL_INT_CASE( device->the_device()->get_config().num_shader() ); break;
case CL_DEVICE_MAX_CLOCK_FREQUENCY: CL_INT_CASE( device->the_device()->shader_clock() ); break;
case CL_DEVICE_VENDOR:CL_STRING_CASE("GPGPU-Sim.org"); break;
case CL_DRIVER_VERSION: CL_STRING_CASE("1.0"); break;
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index dfe4b36..7acd9bb 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -1,5 +1,6 @@
#include "abstract_hardware_model.h"
#include "cuda-sim/memory.h"
+#include "option_parser.h"
#include <algorithm>
unsigned mem_access_t::sm_next_access_uid = 0;
@@ -14,7 +15,40 @@ void move_warp( warp_inst_t *&dst, warp_inst_t *&src )
src->clear();
}
-gpgpu_t::gpgpu_t()
+
+void gpgpu_functional_sim_config::reg_options(class OptionParser * opp)
+{
+ 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_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");
+}
+
+void gpgpu_functional_sim_config::ptx_set_tex_cache_linesize(unsigned linesize)
+{
+ m_texcache_linesize = linesize;
+}
+
+gpgpu_t::gpgpu_t( const gpgpu_functional_sim_config &config )
+ : m_function_model_config(config)
{
m_global_mem = new memory_space_impl<8192>("global",64*1024);
m_param_mem = new memory_space_impl<8192>("param",64*1024);
@@ -22,6 +56,9 @@ gpgpu_t::gpgpu_t()
m_surf_mem = new memory_space_impl<8192>("surf",64*1024);
m_dev_malloc=GLOBAL_HEAP_START;
+
+ if(m_function_model_config.get_ptx_inst_debug_to_file() != 0)
+ ptx_inst_debug_file = fopen(m_function_model_config.get_ptx_inst_debug_file(), "w");
}
address_type line_size_based_tag_func(new_addr_type address, new_addr_type line_size)
@@ -75,9 +112,9 @@ void warp_inst_t::generate_mem_accesses()
switch( space.get_type() ) {
case shared_space: {
- unsigned subwarp_size = m_config->warp_size / m_config->shmem_warp_parts;
+ unsigned subwarp_size = m_config->warp_size / m_config->mem_warp_parts;
unsigned total_accesses=0;
- for( unsigned subwarp=0; subwarp < m_config->shmem_warp_parts; subwarp++ ) {
+ for( unsigned subwarp=0; subwarp < m_config->mem_warp_parts; subwarp++ ) {
// data structures used per part warp
std::map<unsigned,std::map<new_addr_type,unsigned> > bank_accs; // bank -> word address -> access count
@@ -87,6 +124,8 @@ void warp_inst_t::generate_mem_accesses()
if( !active(thread) )
continue;
new_addr_type addr = m_per_scalar_thread[thread].memreqaddr;
+ //FIXME: deferred allocation of shared memory should not accumulate across kernel launches
+ //assert( addr < m_config->gpgpu_shmem_size );
unsigned bank = m_config->shmem_bank_func(addr);
new_addr_type word = line_size_based_tag_func(addr,m_config->WORD_SIZE);
bank_accs[bank][word]++;
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index 804cf23..bc73fbc 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -105,6 +105,7 @@ public:
}
class function_info *entry() { return m_kernel_entry; }
+ const class function_info *entry() const { return m_kernel_entry; }
size_t num_blocks() const
{
@@ -154,7 +155,11 @@ private:
};
struct core_config {
- core_config() { m_valid = false; }
+ core_config()
+ {
+ m_valid = false;
+ num_shmem_bank=16;
+ }
virtual void init() = 0;
bool m_valid;
@@ -165,12 +170,13 @@ struct core_config {
// shared memory bank conflict checking parameters
static const address_type WORD_SIZE=4;
- int num_shmem_bank;
+ unsigned num_shmem_bank;
unsigned shmem_bank_func(address_type addr) const
{
return ((addr/WORD_SIZE) % num_shmem_bank);
}
- unsigned shmem_warp_parts;
+ unsigned mem_warp_parts;
+ unsigned gpgpu_shmem_size;
// texture and constant cache line sizes (used to determine number of memory accesses)
unsigned gpgpu_cache_texl1_linesize;
@@ -180,10 +186,8 @@ struct core_config {
class core_t {
public:
virtual ~core_t() {}
- virtual void set_at_barrier( unsigned cta_id, unsigned warp_id ) = 0;
virtual void warp_exit( unsigned warp_id ) = 0;
virtual bool warp_waiting_at_barrier( unsigned warp_id ) const = 0;
- virtual bool warp_waiting_for_atomics( unsigned warp_id ) const = 0;
virtual class gpgpu_sim *get_gpu() = 0;
};
@@ -250,9 +254,38 @@ struct textureReference {
#endif
+class gpgpu_functional_sim_config
+{
+public:
+ void reg_options(class OptionParser * opp);
+
+ void ptx_set_tex_cache_linesize(unsigned linesize);
+
+ 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; }
+
+ int get_ptx_inst_debug_to_file() const { return g_ptx_inst_debug_to_file; }
+ const char* get_ptx_inst_debug_file() const { return g_ptx_inst_debug_file; }
+ int get_ptx_inst_debug_thread_uid() const { return g_ptx_inst_debug_thread_uid; }
+ unsigned get_texcache_linesize() const { return m_texcache_linesize; }
+
+private:
+ // PTX options
+ int m_ptx_convert_to_ptxplus;
+ int m_ptx_save_converted_ptxplus;
+ unsigned m_ptx_force_max_capability;
+
+ int g_ptx_inst_debug_to_file;
+ char* g_ptx_inst_debug_file;
+ int g_ptx_inst_debug_thread_uid;
+
+ unsigned m_texcache_linesize;
+};
+
class gpgpu_t {
public:
- gpgpu_t();
+ gpgpu_t( const gpgpu_functional_sim_config &config );
void* gpu_malloc( size_t size );
void* gpu_mallocarray( size_t count );
void gpu_memset( size_t dst_start_addr, int c, size_t count );
@@ -268,7 +301,6 @@ public:
void gpgpu_ptx_sim_bindTextureToArray(const struct textureReference* texref, const struct cudaArray* array);
void gpgpu_ptx_sim_bindNameToTexture(const char* name, const struct textureReference* texref);
const char* gpgpu_ptx_sim_findNamefromTexture(const struct textureReference* texref);
- unsigned ptx_set_tex_cache_linesize(unsigned linesize);
const struct textureReference* get_texref(const std::string &texname) const
{
@@ -289,18 +321,23 @@ public:
return t->second;
}
-protected:
- class memory_space *m_global_mem;
- class memory_space *m_tex_mem;
- class memory_space *m_surf_mem;
- class memory_space *m_param_mem;
+ const gpgpu_functional_sim_config &get_config() const { return m_function_model_config; }
+ FILE* get_ptx_inst_debug_file() { return ptx_inst_debug_file; }
- unsigned long long m_dev_malloc;
+protected:
+ const gpgpu_functional_sim_config &m_function_model_config;
+ FILE* ptx_inst_debug_file;
- std::map<std::string, const struct textureReference*> m_NameToTextureRef;
- std::map<const struct textureReference*,const struct cudaArray*> m_TextureRefToCudaArray;
- std::map<const struct textureReference*, const struct textureInfo*> m_TextureRefToTexureInfo;
- unsigned int m_texcache_linesize;
+ class memory_space *m_global_mem;
+ class memory_space *m_tex_mem;
+ class memory_space *m_surf_mem;
+ class memory_space *m_param_mem;
+
+ unsigned long long m_dev_malloc;
+
+ std::map<std::string, const struct textureReference*> m_NameToTextureRef;
+ std::map<const struct textureReference*,const struct cudaArray*> m_TextureRefToCudaArray;
+ std::map<const struct textureReference*, const struct textureInfo*> m_TextureRefToTexureInfo;
};
struct gpgpu_ptx_sim_kernel_info
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc
index d429dc3..1967b2f 100644
--- a/src/cuda-sim/cuda-sim.cc
+++ b/src/cuda-sim/cuda-sim.cc
@@ -92,7 +92,6 @@ int g_debug_execution = 0;
int g_debug_thread_uid = 0;
addr_t g_debug_pc = 0xBEEF1518;
// Output debug information to file options
-FILE* ptx_inst_debug_file;
unsigned g_ptx_sim_num_insn = 0;
unsigned gpgpu_param_num_shaders = 0;
@@ -140,9 +139,9 @@ void gpgpu_t::gpgpu_ptx_sim_bindTextureToArray(const struct textureReference* te
int r;
printf("GPGPU-Sim PTX: texel size = %d\n", texel_size);
- printf("GPGPU-Sim PTX: texture cache linesize = %d\n", m_texcache_linesize);
+ printf("GPGPU-Sim PTX: texture cache linesize = %d\n", m_function_model_config.get_texcache_linesize());
//first determine base Tx size for given linesize
- switch (m_texcache_linesize) {
+ switch (m_function_model_config.get_texcache_linesize()) {
case 16:
Tx = 4;
break;
@@ -159,7 +158,7 @@ void gpgpu_t::gpgpu_ptx_sim_bindTextureToArray(const struct textureReference* te
Tx = 16;
break;
default:
- printf("GPGPU-Sim PTX: Line size of %d bytes currently not supported.\n", m_texcache_linesize);
+ printf("GPGPU-Sim PTX: Line size of %d bytes currently not supported.\n", m_function_model_config.get_texcache_linesize());
assert(0);
break;
}
@@ -170,7 +169,7 @@ void gpgpu_t::gpgpu_ptx_sim_bindTextureToArray(const struct textureReference* te
r = r >> 2;
}
//by now, got the correct Tx size, calculate correct Ty size
- Ty = m_texcache_linesize/(Tx*texel_size);
+ Ty = m_function_model_config.get_texcache_linesize()/(Tx*texel_size);
printf("GPGPU-Sim PTX: Tx = %d; Ty = %d, Tx_numbits = %d, Ty_numbits = %d\n", Tx, Ty, intLOGB2(Tx), intLOGB2(Ty));
printf("GPGPU-Sim PTX: Texel size = %d bytes; texel_size_numbits = %d\n", texel_size, intLOGB2(texel_size));
@@ -850,7 +849,7 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id )
printf("attempted to execute instruction on a thread that is already done.\n");
assert(0);
}
- if ( g_debug_execution >= 6 || g_ptx_inst_debug_to_file) {
+ if ( g_debug_execution >= 6 || m_gpu->get_config().get_ptx_inst_debug_to_file()) {
if ( (g_debug_thread_uid==0) || (get_uid() == (unsigned)g_debug_thread_uid) ) {
clear_modifiedregs();
enable_debug_trace();
@@ -889,17 +888,19 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id )
exit_impl(pI,this);
}
+ const gpgpu_functional_sim_config &config = m_gpu->get_config();
+
// Output instruction information to file and stdout
- if( g_ptx_inst_debug_to_file != 0 &&
- (g_ptx_inst_debug_thread_uid == 0 || g_ptx_inst_debug_thread_uid == get_uid()) ) {
+ if( config.get_ptx_inst_debug_to_file() != 0 &&
+ (config.get_ptx_inst_debug_thread_uid() == 0 || config.get_ptx_inst_debug_thread_uid() == get_uid()) ) {
dim3 ctaid = get_ctaid();
dim3 tid = get_tid();
- fprintf(ptx_inst_debug_file,
+ fprintf(m_gpu->get_ptx_inst_debug_file(),
"[thd=%u] : (%s:%u - %s)\n",
get_uid(),
pI->source_file(), pI->source_line(), pI->get_source() );
//fprintf(ptx_inst_debug_file, "has memory read=%d, has memory write=%d\n", pI->has_memory_read(), pI->has_memory_write());
- fflush(ptx_inst_debug_file);
+ fflush(m_gpu->get_ptx_inst_debug_file());
}
if ( ptx_debug_exec_dump_cond<5>(get_uid(), pc) ) {
@@ -965,10 +966,10 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id )
}
// Output register information to file and stdout
- if( g_ptx_inst_debug_to_file != 0 &&
- (g_ptx_inst_debug_thread_uid == 0 || g_ptx_inst_debug_thread_uid == get_uid()) ) {
- dump_modifiedregs(ptx_inst_debug_file);
- dump_regs(ptx_inst_debug_file);
+ if( config.get_ptx_inst_debug_to_file()!=0 &&
+ (config.get_ptx_inst_debug_thread_uid()==0||config.get_ptx_inst_debug_thread_uid()==get_uid()) ) {
+ dump_modifiedregs(m_gpu->get_ptx_inst_debug_file());
+ dump_regs(m_gpu->get_ptx_inst_debug_file());
}
if ( g_debug_execution >= 6 ) {
@@ -1031,7 +1032,7 @@ void set_param_gpgpu_num_shaders(int num_shaders)
gpgpu_param_num_shaders = num_shaders;
}
-const struct gpgpu_ptx_sim_kernel_info* ptx_sim_kernel_info(function_info *kernel)
+const struct gpgpu_ptx_sim_kernel_info* ptx_sim_kernel_info(const function_info *kernel)
{
return kernel->get_kernel_info();
}
@@ -1468,12 +1469,6 @@ void gpgpu_cuda_ptx_sim_main_func( kernel_info_t kernel, dim3 gridDim, dim3 bloc
fflush(stdout);
}
-unsigned gpgpu_t::ptx_set_tex_cache_linesize(unsigned linesize)
-{
- m_texcache_linesize = linesize;
- return 0;
-}
-
unsigned translate_pc_to_ptxlineno(unsigned pc)
{
// this function assumes that the kernel fits inside a single PTX file
diff --git a/src/cuda-sim/cuda-sim.h b/src/cuda-sim/cuda-sim.h
index b095afb..0e97b97 100644
--- a/src/cuda-sim/cuda-sim.h
+++ b/src/cuda-sim/cuda-sim.h
@@ -18,7 +18,6 @@ extern int g_debug_thread_uid;
extern void ** g_inst_classification_stat;
extern void ** g_inst_op_classification_stat;
extern int g_ptx_kernel_count; // used for classification stat collection purposes
-extern FILE* ptx_inst_debug_file;
extern class kernel_info_t gpgpu_opencl_ptx_sim_init_grid(class function_info *entry,
@@ -45,7 +44,7 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel,
unsigned hw_warp_id,
gpgpu_t *gpu );
const warp_inst_t *ptx_fetch_inst( address_type pc );
-const struct gpgpu_ptx_sim_kernel_info* ptx_sim_kernel_info(class function_info *kernel);
+const struct gpgpu_ptx_sim_kernel_info* ptx_sim_kernel_info(const class function_info *kernel);
void ptx_print_insn( address_type pc, FILE *fp );
void set_param_gpgpu_num_shaders(int num_shaders);
unsigned int get_converge_point(unsigned int pc, void *thd);
diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc
index fee0056..50167b8 100644
--- a/src/cuda-sim/ptx_ir.cc
+++ b/src/cuda-sim/ptx_ir.cc
@@ -118,8 +118,8 @@ symbol_table::symbol_table( const char *scope_name, unsigned entry_point, symbol
{
m_scope_name = std::string(scope_name);
m_reg_allocator=0;
- m_shared_next = 0x100;
- m_const_next = 0x100;
+ m_shared_next = 0;
+ m_const_next = 0;
m_global_next = 0x100;
m_local_next = 0;
m_parent = parent;
diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h
index a8f9a7b..3d65712 100644
--- a/src/cuda-sim/ptx_ir.h
+++ b/src/cuda-sim/ptx_ir.h
@@ -1159,7 +1159,8 @@ public:
void param_to_shared( memory_space *shared_mem, symbol_table *symtab );
void list_param( FILE *fout ) const;
- const struct gpgpu_ptx_sim_kernel_info* get_kernel_info () {
+ const struct gpgpu_ptx_sim_kernel_info* get_kernel_info () const
+ {
return &m_kernel_info;
}
diff --git a/src/cuda-sim/ptx_sim.h b/src/cuda-sim/ptx_sim.h
index 298122e..d60955b 100644
--- a/src/cuda-sim/ptx_sim.h
+++ b/src/cuda-sim/ptx_sim.h
@@ -430,6 +430,7 @@ public:
memory_space *get_tex_memory() { return m_gpu->get_tex_memory(); }
memory_space *get_surf_memory() { return m_gpu->get_surf_memory(); }
memory_space *get_param_memory() { return m_gpu->get_param_memory(); }
+ const gpgpu_functional_sim_config &get_config() const { return m_gpu->get_config(); }
public:
addr_t m_last_effective_address;
diff --git a/src/debug.cc b/src/debug.cc
index 49cae96..9484123 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -37,8 +37,6 @@ void hit_watchpoint( unsigned watchpoint_num, ptx_thread_info *thd, const ptx_in
/// interactive debugger
-extern gpgpu_sim g_the_gpu;
-
void gpgpu_sim::gpgpu_debug()
{
bool done=true;
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);
diff --git a/src/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc
index f6dea90..8579f08 100644
--- a/src/gpgpusim_entrypoint.cc
+++ b/src/gpgpusim_entrypoint.cc
@@ -87,44 +87,44 @@ sem_t g_sim_signal_finish;
time_t g_simulation_starttime;
pthread_t g_simulation_thread;
-gpgpu_sim g_the_gpu;
+gpgpu_sim_config g_the_gpu_config;
+gpgpu_sim *g_the_gpu;
static void print_simulation_time();
void *gpgpu_sim_thread(void*)
{
+ kernel_info_t *kernel = NULL;
do {
sem_wait(&g_sim_signal_start);
- g_the_gpu.next_grid();
- g_the_gpu.run_gpu_sim();
- print_simulation_time();
+ kernel = g_the_gpu->next_grid();
+ if( kernel ) {
+ g_the_gpu_config.set_max_cta(*kernel);
+ g_the_gpu->run_gpu_sim();
+ print_simulation_time();
+ }
sem_post(&g_sim_signal_finish);
- } while(1);
+ } while(kernel);
return NULL;
}
gpgpu_sim *gpgpu_ptx_sim_init_perf()
{
+ srand(1);
print_splash();
read_sim_environment_variables();
read_parser_environment_variables();
option_parser_t opp = option_parser_create();
+
icnt_reg_options(opp);
- g_the_gpu.reg_options(opp); // register GPU microrachitecture options
+ g_the_gpu_config.reg_options(opp); // register GPU microrachitecture options
ptx_reg_options(opp);
option_parser_cmdline(opp, sg_argc, sg_argv); // parse configuration options
-
- srand(1);
-
- // Open instructions debug output file for writing
- if(g_ptx_inst_debug_to_file != 0) {
- ptx_inst_debug_file = fopen(g_ptx_inst_debug_file, "w");
- }
-
fprintf(stdout, "GPGPU-Sim: Configuration options:\n\n");
option_parser_print(opp, stdout);
+ g_the_gpu_config.init();
- g_the_gpu.init_gpu();
+ g_the_gpu = new gpgpu_sim(g_the_gpu_config);
g_simulation_starttime = time((time_t *)NULL);
@@ -132,7 +132,7 @@ gpgpu_sim *gpgpu_ptx_sim_init_perf()
sem_init(&g_sim_signal_finish,0,0);
pthread_create(&g_simulation_thread,NULL,gpgpu_sim_thread,NULL);
- return &g_the_gpu;
+ return g_the_gpu;
}
void print_simulation_time()
@@ -149,7 +149,7 @@ void print_simulation_time()
fflush(stderr);
printf("\n\ngpgpu_simulation_time = %u days, %u hrs, %u min, %u sec (%u sec)\n",
(unsigned)d, (unsigned)h, (unsigned)m, (unsigned)s, (unsigned)difference );
- printf("gpgpu_simulation_rate = %u (inst/sec)\n", (unsigned)(g_the_gpu.gpu_tot_sim_insn / difference) );
+ printf("gpgpu_simulation_rate = %u (inst/sec)\n", (unsigned)(g_the_gpu->gpu_tot_sim_insn / difference) );
printf("gpgpu_simulation_rate = %u (cycle/sec)\n", (unsigned)(gpu_tot_sim_cycle / difference) );
fflush(stdout);
}
@@ -159,7 +159,7 @@ int gpgpu_cuda_ptx_sim_main_perf( kernel_info_t grid,
struct dim3 blockDim,
gpgpu_ptx_sim_arg_list_t grid_params )
{
- g_the_gpu.launch(grid);
+ g_the_gpu->launch(grid);
sem_post(&g_sim_signal_start);
sem_wait(&g_sim_signal_finish);
return 0;
@@ -170,7 +170,7 @@ int gpgpu_opencl_ptx_sim_main_perf( kernel_info_t grid,
struct dim3 blockDim,
gpgpu_ptx_sim_arg_list_t grid_params )
{
- g_the_gpu.launch(grid);
+ g_the_gpu->launch(grid);
sem_post(&g_sim_signal_start);
sem_wait(&g_sim_signal_finish);
return 0;
diff --git a/src/intersim/interconnect_interface.cpp b/src/intersim/interconnect_interface.cpp
index 40cf00d..3059b44 100644
--- a/src/intersim/interconnect_interface.cpp
+++ b/src/intersim/interconnect_interface.cpp
@@ -395,8 +395,7 @@ extern int DISPLAY_PAIR_LATENCY ;
void init_interconnect (char* config_file,
unsigned int n_shader,
- unsigned int n_mem,
- struct shader_core_config *shader_config )
+ unsigned int n_mem )
{
_n_shader = n_shader;
_n_mem = n_mem;
diff --git a/src/intersim/interconnect_interface.h b/src/intersim/interconnect_interface.h
index 9003fc6..07f6580 100644
--- a/src/intersim/interconnect_interface.h
+++ b/src/intersim/interconnect_interface.h
@@ -19,8 +19,7 @@ void interconnect_push ( unsigned int input, unsigned int output,
void* interconnect_pop(unsigned int output);
void init_interconnect (char* config_file,
unsigned int n_shader,
- unsigned int n_mem,
- struct shader_core_config *shader_config);
+ unsigned int n_mem);
void advance_interconnect();
unsigned interconnect_busy();
void interconnect_stats() ;