summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortgrogers <[email protected]>2019-05-19 09:35:48 -0400
committertgrogers <[email protected]>2019-05-19 09:35:48 -0400
commit206ccbe8c0f712c802f8919497ca70bff1aa6a1e (patch)
tree82ef1ef2631a0c8c32c2ce44319e96b944c52730 /src
parent8c45f47e1b683d9904956659340a394321c6682d (diff)
parent8fb484e4120a08e896f53424e9f4f46710966970 (diff)
Merge branch 'dev' of github.com:purdue-aalp/gpgpu-sim_distribution into dev
Diffstat (limited to 'src')
-rw-r--r--src/abstract_hardware_model.cc26
-rw-r--r--src/abstract_hardware_model.h52
-rw-r--r--src/cuda-sim/cuda-sim.cc16
-rw-r--r--src/cuda-sim/cuda-sim.h2
-rw-r--r--src/cuda-sim/cuda_device_runtime.cc5
-rw-r--r--src/cuda-sim/instructions.cc13
-rw-r--r--src/cuda-sim/ptx.l1
-rw-r--r--src/cuda-sim/ptx_loader.cc34
-rw-r--r--src/cuda-sim/ptx_sim.cc8
-rw-r--r--src/cuda-sim/ptxinfo.l35
-rw-r--r--src/cuda-sim/ptxinfo.y15
-rw-r--r--src/gpgpu-sim/addrdec.cc29
-rw-r--r--src/gpgpu-sim/addrdec.h5
-rw-r--r--src/gpgpu-sim/dram.cc82
-rw-r--r--src/gpgpu-sim/dram.h66
-rw-r--r--src/gpgpu-sim/dram_sched.cc14
-rw-r--r--src/gpgpu-sim/gpu-cache.cc29
-rw-r--r--src/gpgpu-sim/gpu-cache.h63
-rw-r--r--src/gpgpu-sim/gpu-sim.cc76
-rw-r--r--src/gpgpu-sim/gpu-sim.h35
-rw-r--r--src/gpgpu-sim/icnt_wrapper.cc90
-rw-r--r--src/gpgpu-sim/icnt_wrapper.h5
-rw-r--r--src/gpgpu-sim/l2cache.cc56
-rw-r--r--src/gpgpu-sim/l2cache.h13
-rw-r--r--src/gpgpu-sim/l2cache_trace.h4
-rw-r--r--src/gpgpu-sim/local_interconnect.cc301
-rw-r--r--src/gpgpu-sim/local_interconnect.h127
-rw-r--r--src/gpgpu-sim/mem_fetch.cc5
-rw-r--r--src/gpgpu-sim/mem_fetch.h1
-rw-r--r--src/gpgpu-sim/mem_latency_stat.cc13
-rw-r--r--src/gpgpu-sim/mem_latency_stat.h4
-rw-r--r--src/gpgpu-sim/scoreboard.cc4
-rw-r--r--src/gpgpu-sim/scoreboard.h4
-rw-r--r--src/gpgpu-sim/shader.cc175
-rw-r--r--src/gpgpu-sim/shader.h36
-rw-r--r--src/gpgpu-sim/shader_trace.h4
-rw-r--r--src/gpgpusim_entrypoint.cc8
-rw-r--r--src/stream_manager.cc2
-rw-r--r--src/trace.h14
39 files changed, 1131 insertions, 341 deletions
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index 307df40..63b139e 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -88,8 +88,6 @@ void checkpoint::load_global_mem(class memory_space *temp_mem, char * f1name)
fclose ( fp2 );
}
-
-
void checkpoint::store_global_mem(class memory_space * mem, char *fname, char * format)
{
@@ -192,9 +190,17 @@ gpgpu_t::gpgpu_t( const gpgpu_functional_sim_config &config )
checkpoint_CTA_t = m_function_model_config.get_checkpoint_CTA_t();
checkpoint_insn_Y = m_function_model_config.get_checkpoint_insn_Y();
+ // initialize texture mappings to empty
+ m_NameToTextureInfo.clear();
+ m_NameToCudaArray.clear();
+ m_TextureRefToName.clear();
+ m_NameToAttribute.clear();
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");
+
+ gpu_sim_cycle=0;
+ gpu_tot_sim_cycle=0;
}
address_type line_size_based_tag_func(new_addr_type address, new_addr_type line_size)
@@ -688,7 +694,10 @@ unsigned g_kernel_launch_latency;
unsigned kernel_info_t::m_next_uid = 1;
-kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info *entry )
+/*A snapshot of the texture mappings needs to be stored in the kernel's info as
+kernels should use the texture bindings seen at the time of launch and textures
+ can be bound/unbound asynchronously with respect to streams. */
+kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info *entry, std::map<std::string, const struct cudaArray*> nameToCudaArray, std::map<std::string, const struct textureInfo*> nameToTextureInfo)
{
m_kernel_entry=entry;
m_grid_dim=gridDim;
@@ -708,6 +717,8 @@ kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info *
m_launch_latency = g_kernel_launch_latency;
volta_cache_config_set=false;
+ m_NameToCudaArray = nameToCudaArray;
+ m_NameToTextureInfo = nameToTextureInfo;
}
kernel_info_t::~kernel_info_t()
@@ -822,10 +833,11 @@ void kernel_info_t::destroy_cta_streams() {
m_cta_streams.clear();
}
-simt_stack::simt_stack( unsigned wid, unsigned warpSize)
+simt_stack::simt_stack( unsigned wid, unsigned warpSize, class gpgpu_sim * gpu)
{
m_warp_id=wid;
m_warp_size = warpSize;
+ m_gpu=gpu;
reset();
}
@@ -1025,7 +1037,7 @@ void simt_stack::update( simt_mask_t &thread_done, addr_vector_t &next_pc, addre
simt_stack_entry new_stack_entry;
new_stack_entry.m_pc = tmp_next_pc;
new_stack_entry.m_active_mask = tmp_active_mask;
- new_stack_entry.m_branch_div_cycle = gpu_sim_cycle+gpu_tot_sim_cycle;
+ new_stack_entry.m_branch_div_cycle = m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle;
new_stack_entry.m_type = STACK_ENTRY_TYPE_CALL;
m_stack.push_back(new_stack_entry);
return;
@@ -1057,7 +1069,7 @@ void simt_stack::update( simt_mask_t &thread_done, addr_vector_t &next_pc, addre
new_recvg_pc = recvg_pc;
if (new_recvg_pc != top_recvg_pc) {
m_stack.back().m_pc = new_recvg_pc;
- m_stack.back().m_branch_div_cycle = gpu_sim_cycle+gpu_tot_sim_cycle;
+ m_stack.back().m_branch_div_cycle = m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle;
m_stack.push_back(simt_stack_entry());
}
@@ -1149,7 +1161,7 @@ void core_t::initilizeSIMTStack(unsigned warp_count, unsigned warp_size)
{
m_simt_stack = new simt_stack*[warp_count];
for (unsigned i = 0; i < warp_count; ++i)
- m_simt_stack[i] = new simt_stack(i,warp_size);
+ m_simt_stack[i] = new simt_stack(i,warp_size,m_gpu);
m_warp_size = warp_size;
m_warp_count = warp_count;
}
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index 28a22e0..1735c2f 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -212,7 +212,7 @@ public:
// m_num_cores_running=0;
// m_param_mem=NULL;
// }
- kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info *entry );
+ kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info *entry, std::map<std::string, const struct cudaArray*> nameToCudaArray, std::map<std::string, const struct textureInfo*> nameToTextureInfo);
~kernel_info_t();
void inc_running() { m_num_cores_running++; }
@@ -275,6 +275,23 @@ public:
std::list<class ptx_thread_info *> &active_threads() { return m_active_threads; }
class memory_space *get_param_memory() { return m_param_mem; }
+
+ //The following functions access texture bindings present at the kernel's launch
+
+ const struct cudaArray* get_texarray( const std::string &texname ) const
+ {
+ std::map<std::string,const struct cudaArray*>::const_iterator t=m_NameToCudaArray.find(texname);
+ assert(t != m_NameToCudaArray.end());
+ return t->second;
+ }
+
+ const struct textureInfo* get_texinfo( const std::string &texname ) const
+ {
+ std::map<std::string, const struct textureInfo*>::const_iterator t=m_NameToTextureInfo.find(texname);
+ assert(t != m_NameToTextureInfo.end());
+ return t->second;
+ }
+
private:
kernel_info_t( const kernel_info_t & ); // disable copy constructor
void operator=( const kernel_info_t & ); // disable copy operator
@@ -283,6 +300,10 @@ private:
unsigned m_uid;
static unsigned m_next_uid;
+
+ //These maps contain the snapshot of the texture mappings at kernel launch
+ std::map<std::string, const struct cudaArray*> m_NameToCudaArray;
+ std::map<std::string, const struct textureInfo*> m_NameToTextureInfo;
dim3 m_grid_dim;
dim3 m_block_dim;
@@ -365,6 +386,8 @@ struct core_config {
unsigned gpgpu_max_insn_issue_per_warp;
bool gmem_skip_L1D; // on = global memory access always skip the L1 cache
+
+ bool adaptive_volta_cache_config;
};
// bounded stack that implements simt reconvergence using pdom mechanism from MICRO'07 paper
@@ -376,7 +399,7 @@ typedef std::vector<address_type> addr_vector_t;
class simt_stack {
public:
- simt_stack( unsigned wid, unsigned warpSize);
+ simt_stack( unsigned wid, unsigned warpSize, class gpgpu_sim * gpu);
void reset();
void launch( address_type start_pc, const simt_mask_t &active_mask );
@@ -393,6 +416,7 @@ protected:
unsigned m_warp_id;
unsigned m_warp_size;
+
enum stack_entry_type {
STACK_ENTRY_TYPE_NORMAL = 0,
STACK_ENTRY_TYPE_CALL
@@ -410,6 +434,8 @@ protected:
};
std::deque<simt_stack_entry> m_stack;
+
+ class gpgpu_sim * m_gpu;
};
#define GLOBAL_HEAP_START 0xC0000000
@@ -548,6 +574,12 @@ public:
int resume_CTA;
int checkpoint_CTA_t;
int checkpoint_insn_Y;
+
+ //Move some cycle core stats here instead of being global
+ unsigned long long gpu_sim_cycle;
+ unsigned long long gpu_tot_sim_cycle;
+
+
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 );
@@ -580,8 +612,8 @@ public:
const struct textureInfo* get_texinfo( const std::string &texname ) const
{
- std::map<std::string, const struct textureInfo*>::const_iterator t=m_NameToTexureInfo.find(texname);
- assert(t != m_NameToTexureInfo.end());
+ std::map<std::string, const struct textureInfo*>::const_iterator t=m_NameToTextureInfo.find(texname);
+ assert(t != m_NameToTextureInfo.end());
return t->second;
}
@@ -594,6 +626,10 @@ public:
const gpgpu_functional_sim_config &get_config() const { return m_function_model_config; }
FILE* get_ptx_inst_debug_file() { return ptx_inst_debug_file; }
+
+ // These maps return the current texture mappings for the GPU at any given time.
+ std::map<std::string, const struct cudaArray*> getNameArrayMapping() {return m_NameToCudaArray;}
+ std::map<std::string, const struct textureInfo*> getNameInfoMapping() {return m_NameToTextureInfo;}
protected:
const gpgpu_functional_sim_config &m_function_model_config;
@@ -604,11 +640,11 @@ protected:
class memory_space *m_surf_mem;
unsigned long long m_dev_malloc;
-
+ // These maps contain the current texture mappings for the GPU at any given time.
std::map<std::string, std::set<const struct textureReference*> > m_NameToTextureRef;
std::map<const struct textureReference*, std::string> m_TextureRefToName;
std::map<std::string, const struct cudaArray*> m_NameToCudaArray;
- std::map<std::string, const struct textureInfo*> m_NameToTexureInfo;
+ std::map<std::string, const struct textureInfo*> m_NameToTextureInfo;
std::map<std::string, const struct textureReferenceAttr*> m_NameToAttribute;
};
@@ -808,8 +844,8 @@ public:
class mem_fetch_allocator {
public:
- virtual mem_fetch *alloc( new_addr_type addr, mem_access_type type, unsigned size, bool wr ) const = 0;
- virtual mem_fetch *alloc( const class warp_inst_t &inst, const mem_access_t &access ) const = 0;
+ virtual mem_fetch *alloc( new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle ) const = 0;
+ virtual mem_fetch *alloc( const class warp_inst_t &inst, const mem_access_t &access, unsigned long long cycle ) const = 0;
};
// the maximum number of destination, source, or address uarch operands in a instruction
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc
index ec68b5b..f7bb9cc 100644
--- a/src/cuda-sim/cuda-sim.cc
+++ b/src/cuda-sim/cuda-sim.cc
@@ -218,7 +218,7 @@ void gpgpu_t::gpgpu_ptx_sim_bindTextureToArray(const struct textureReference* te
texInfo->Ty_numbits = intLOGB2(Ty);
texInfo->texel_size = texel_size;
texInfo->texel_size_numbits = intLOGB2(texel_size);
- m_NameToTexureInfo[texname] = texInfo;
+ m_NameToTextureInfo[texname] = texInfo;
}
void gpgpu_t::gpgpu_ptx_sim_unbindTexture(const struct textureReference* texref)
@@ -226,7 +226,7 @@ void gpgpu_t::gpgpu_ptx_sim_unbindTexture(const struct textureReference* texref)
//assumes bind-use-unbind-bind-use-unbind pattern
std::string texname = gpgpu_ptx_sim_findNamefromTexture(texref);
m_NameToCudaArray.erase(texname);
- m_NameToTexureInfo.erase(texname);
+ m_NameToTextureInfo.erase(texname);
}
unsigned g_assemble_code_next_pc=0;
@@ -1507,7 +1507,15 @@ static unsigned get_tex_datasize( const ptx_instruction *pI, ptx_thread_info *th
std::string texname = src1.name();
gpgpu_t *gpu = thread->get_gpu();
- const struct textureInfo* texInfo = gpu->get_texinfo(texname);
+ /*
+ For programs with many streams, textures can be bound and unbound
+ asynchronously. This means we need to use the kernel's "snapshot" of
+ the state of the texture mappings when it was launched (so that we
+ don't try to access the incorrect texture mapping if it's been updated,
+ or that we don't access a mapping that has been unbound).
+ */
+ kernel_info_t& k = thread->get_kernel();
+ const struct textureInfo* texInfo = k.get_texinfo(texname);
unsigned data_size = texInfo->texel_size;
return data_size;
@@ -1918,7 +1926,7 @@ kernel_info_t *gpgpu_opencl_ptx_sim_init_grid(class function_info *entry,
struct dim3 blockDim,
gpgpu_t *gpu )
{
- kernel_info_t *result = new kernel_info_t(gridDim,blockDim,entry);
+ kernel_info_t *result = new kernel_info_t(gridDim,blockDim,entry,gpu->getNameArrayMapping(),gpu->getNameInfoMapping());
unsigned argcount=args.size();
unsigned argn=1;
for( gpgpu_ptx_sim_arg_list_t::iterator a = args.begin(); a != args.end(); a++ ) {
diff --git a/src/cuda-sim/cuda-sim.h b/src/cuda-sim/cuda-sim.h
index abd32f9..e690356 100644
--- a/src/cuda-sim/cuda-sim.h
+++ b/src/cuda-sim/cuda-sim.h
@@ -47,6 +47,8 @@ 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 char *opcode_latency_int, *opcode_latency_fp, *opcode_latency_dp,*opcode_latency_sfu,*opcode_latency_tensor;
+
void ptx_opcocde_latency_options (option_parser_t opp);
extern class kernel_info_t *gpgpu_opencl_ptx_sim_init_grid(class function_info *entry,
diff --git a/src/cuda-sim/cuda_device_runtime.cc b/src/cuda-sim/cuda_device_runtime.cc
index b399133..86e8147 100644
--- a/src/cuda-sim/cuda_device_runtime.cc
+++ b/src/cuda-sim/cuda_device_runtime.cc
@@ -198,8 +198,9 @@ void gpgpusim_cuda_launchDeviceV2(const ptx_instruction * pI, ptx_thread_info *
memory_space *device_kernel_param_mem;
//create child kernel_info_t and index it with parameter_buffer address
- device_grid = new kernel_info_t(config.grid_dim, config.block_dim, device_kernel_entry);
- device_grid->launch_cycle = gpu_sim_cycle + gpu_tot_sim_cycle;
+ gpgpu_t* gpu=thread->get_gpu();
+ device_grid = new kernel_info_t(config.grid_dim, config.block_dim, device_kernel_entry, gpu->getNameArrayMapping(), gpu->getNameInfoMapping());
+ device_grid->launch_cycle = gpu->gpu_sim_cycle + gpu->gpu_tot_sim_cycle;
kernel_info_t & parent_grid = thread->get_kernel();
DEV_RUNTIME_REPORT("child kernel launched by " << parent_grid.name() << ", cta (" <<
thread->get_ctaid().x << ", " << thread->get_ctaid().y << ", " << thread->get_ctaid().z <<
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc
index c85654c..11001d7 100644
--- a/src/cuda-sim/instructions.cc
+++ b/src/cuda-sim/instructions.cc
@@ -5258,11 +5258,18 @@ void tex_impl( const ptx_instruction *pI, ptx_thread_info *thread )
if (!ptx_tex_regs) ptx_tex_regs = new ptx_reg_t[4];
unsigned nelem = src2.get_vect_nelem();
thread->get_vector_operand_values(src2, ptx_tex_regs, nelem); //ptx_reg should be 4 entry vector type...coordinates into texture
-
+ /*
+ For programs with many streams, textures can be bound and unbound
+ asynchronously. This means we need to use the kernel's "snapshot" of
+ the state of the texture mappings when it was launched (so that we
+ don't try to access the incorrect texture mapping if it's been updated,
+ or that we don't access a mapping that has been unbound).
+ */
gpgpu_t *gpu = thread->get_gpu();
+ kernel_info_t &k = thread->get_kernel();
const struct textureReference* texref = gpu->get_texref(texname);
- const struct cudaArray* cuArray = gpu->get_texarray(texname);
- const struct textureInfo* texInfo = gpu->get_texinfo(texname);
+ const struct cudaArray* cuArray = k.get_texarray(texname);
+ const struct textureInfo* texInfo = k.get_texinfo(texname);
const struct textureReferenceAttr* texAttr = gpu->get_texattr(texname);
//assume always 2D f32 input
diff --git a/src/cuda-sim/ptx.l b/src/cuda-sim/ptx.l
index d4bf631..3232361 100644
--- a/src/cuda-sim/ptx.l
+++ b/src/cuda-sim/ptx.l
@@ -61,6 +61,7 @@ addc TC; ptx_lval.int_value = ADDC_OP; return OPCODE;
and TC; ptx_lval.int_value = AND_OP; return OPCODE;
andn TC; ptx_lval.int_value = ANDN_OP; return OPCODE;
atom TC; ptx_lval.int_value = ATOM_OP; return OPCODE;
+bar.warp TC; ptx_lval.int_value = NOP_OP; return OPCODE;
bar TC; ptx_lval.int_value = BAR_OP; return OPCODE;
bfe TC; ptx_lval.int_value = BFE_OP; return OPCODE;
bfi TC; ptx_lval.int_value = BFI_OP; return OPCODE;
diff --git a/src/cuda-sim/ptx_loader.cc b/src/cuda-sim/ptx_loader.cc
index 8c6f361..da7c32d 100644
--- a/src/cuda-sim/ptx_loader.cc
+++ b/src/cuda-sim/ptx_loader.cc
@@ -50,9 +50,12 @@ extern int ptx__scan_string(const char*);
extern std::map<unsigned,const char*> get_duplicate();
const char *g_ptxinfo_filename;
-extern int ptxinfo_parse();
-extern int ptxinfo_debug;
-extern FILE *ptxinfo_in;
+
+typedef void * yyscan_t;
+extern int ptxinfo_lex_init(yyscan_t* scanner);
+extern void ptxinfo_set_in (FILE * _in_str ,yyscan_t yyscanner );
+extern int ptxinfo_parse(yyscan_t scanner);
+extern int ptxinfo_lex_destroy(yyscan_t scanner);
static bool g_save_embedded_ptx;
static int g_occupancy_sm_number;
@@ -347,8 +350,13 @@ void gpgpu_ptx_info_load_from_filename( const char *filename, unsigned sm_versio
}
g_ptxinfo_filename = strdup(ptxas_filename.c_str());
+ FILE *ptxinfo_in;
ptxinfo_in = fopen(g_ptxinfo_filename,"r");
- ptxinfo_parse();
+ yyscan_t scanner;
+ ptxinfo_lex_init(&scanner);
+ ptxinfo_set_in(ptxinfo_in, scanner);
+ ptxinfo_parse(scanner);
+ ptxinfo_lex_destroy(scanner);
fclose(ptxinfo_in);
}
@@ -410,9 +418,15 @@ void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num
if( result != 0 ) {
// 65280 = duplicate errors
if (result == 65280) {
+ FILE *ptxinfo_in;
ptxinfo_in = fopen(tempfile_ptxinfo,"r");
g_ptxinfo_filename = tempfile_ptxinfo;
- ptxinfo_parse();
+ yyscan_t scanner;
+ ptxinfo_lex_init(&scanner);
+ ptxinfo_set_in(ptxinfo_in, scanner);
+ ptxinfo_parse(scanner);
+ ptxinfo_lex_destroy(scanner);
+ fclose(ptxinfo_in);
fix_duplicate_errors(fname2);
snprintf(commandline,1024,"$CUDA_INSTALL_PATH/bin/ptxas %s -v %s --output-file /dev/null 2> %s",
@@ -495,9 +509,15 @@ void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num
g_ptxinfo_filename = final_tempfile_ptxinfo;
else
g_ptxinfo_filename = tempfile_ptxinfo;
+ FILE *ptxinfo_in;
ptxinfo_in = fopen(g_ptxinfo_filename,"r");
- ptxinfo_parse();
+ yyscan_t scanner;
+ ptxinfo_lex_init(&scanner);
+ ptxinfo_set_in(ptxinfo_in, scanner);
+ ptxinfo_parse(scanner);
+ ptxinfo_lex_destroy(scanner);
+ fclose(ptxinfo_in);
snprintf(commandline,1024,"rm -f *info");
if( system(commandline) != 0 ) {
@@ -515,4 +535,4 @@ void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num
exit(1);
}
}
-} \ No newline at end of file
+}
diff --git a/src/cuda-sim/ptx_sim.cc b/src/cuda-sim/ptx_sim.cc
index 820287d..8ad651e 100644
--- a/src/cuda-sim/ptx_sim.cc
+++ b/src/cuda-sim/ptx_sim.cc
@@ -222,7 +222,7 @@ void ptx_thread_info::set_done()
{
assert( !m_at_barrier );
m_thread_done = true;
- m_cycle_done = gpu_sim_cycle;
+ m_cycle_done = m_gpu->gpu_sim_cycle;
}
unsigned ptx_thread_info::get_builtin( int builtin_id, unsigned dim_mod )
@@ -230,15 +230,15 @@ unsigned ptx_thread_info::get_builtin( int builtin_id, unsigned dim_mod )
assert( m_valid );
switch ((builtin_id&0xFFFF)) {
case CLOCK_REG:
- return (unsigned)(gpu_sim_cycle + gpu_tot_sim_cycle);
+ return (unsigned)(m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
case CLOCK64_REG:
abort(); // change return value to unsigned long long?
// GPGPUSim clock is 4 times slower - multiply by 4
- return (gpu_sim_cycle + gpu_tot_sim_cycle)*4;
+ return (m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle)*4;
case HALFCLOCK_ID:
// GPGPUSim clock is 4 times slower - multiply by 4
// Hardware clock counter is incremented at half the shader clock frequency - divide by 2 (Henry '10)
- return (gpu_sim_cycle + gpu_tot_sim_cycle)*2;
+ return (m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle)*2;
case CTAID_REG:
assert( dim_mod < 3 );
if( dim_mod == 0 ) return m_ctaid.x;
diff --git a/src/cuda-sim/ptxinfo.l b/src/cuda-sim/ptxinfo.l
index 33c2748..a190e6d 100644
--- a/src/cuda-sim/ptxinfo.l
+++ b/src/cuda-sim/ptxinfo.l
@@ -31,17 +31,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%option noyywrap
%option yylineno
%option prefix="ptxinfo_"
+
+%option bison-bridge
+%option reentrant
+
%{
#include "ptxinfo.tab.h"
#include <string.h>
#define LINEBUF_SIZE 1024
-char ptxinfo_linebuf[LINEBUF_SIZE];
-unsigned ptxinfo_col = 0;
-#define TC if( (ptxinfo_lineno == 1) && ((ptxinfo_col + strlen(ptxinfo_text)) < LINEBUF_SIZE) ) { \
- strncpy(ptxinfo_linebuf+ptxinfo_col,ptxinfo_text,strlen(ptxinfo_text)); \
+#define TC if( (yylineno == 1) && (yylval->col + strlen(yytext) < LINEBUF_SIZE) ) { \
+ strncpy(yylval->linebuf+yylval->col,yytext,strlen(yytext)); \
} \
- ptxinfo_col+=strlen(ptxinfo_text);
+ yylval->col+=strlen(yytext);
%}
%%
@@ -61,12 +63,12 @@ unsigned ptxinfo_col = 0;
"for" TC; return FOR;
"textures" TC; return TEXTURES;
"error : Duplicate definition of" TC; return DUPLICATE;
-"function" TC; ptxinfo_lval.string_value = strdup(yytext); return FUNCTION;
-"variable" TC; ptxinfo_lval.string_value = strdup(yytext); return VARIABLE;
+"function" TC; yylval->string_value = strdup(yytext); return FUNCTION;
+"variable" TC; yylval->string_value = strdup(yytext); return VARIABLE;
"fatal : Ptx assembly aborted due to errors" TC; return FATAL;
-[_A-Za-z$%][_0-9A-Za-z$]* TC; ptxinfo_lval.string_value = strdup(yytext); return IDENTIFIER;
-[-]{0,1}[0-9]+ TC; ptxinfo_lval.int_value = atoi(yytext); return INT_OPERAND;
+[_A-Za-z$%][_0-9A-Za-z$]* TC; yylval->string_value = strdup(yytext); return IDENTIFIER;
+[-]{0,1}[0-9]+ TC; yylval->int_value = atoi(yytext); return INT_OPERAND;
"+" TC; return PLUS;
"," TC; return COMMA;
@@ -78,7 +80,7 @@ unsigned ptxinfo_col = 0;
" " TC;
"\t" TC;
-\n.* ptxinfo_col=0; strncpy(ptxinfo_linebuf, yytext + 1, 1024); yyless( 1 );
+\n.* yylval->col=0; strncpy(yylval->linebuf, yytext + 1, 1024); yyless( 1 );
%%
@@ -86,18 +88,19 @@ extern int g_ptxinfo_error_detected;
extern const char *g_filename;
extern const char *g_ptxinfo_filename;
-int ptxinfo_error( const char *s )
+int ptxinfo_error(yyscan_t yyscanner, const char* msg)
{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
int i;
g_ptxinfo_error_detected = 1;
fflush(stdout);
printf("GPGPU-Sim: ERROR while parsing output of ptxas (used to capture resource usage information)\n");
- if( s != NULL )
- printf("GPGPU-Sim: %s (%s:%u) Syntax error:\n\n", g_filename, g_ptxinfo_filename, ptxinfo_lineno );
- printf(" %s\n", ptxinfo_linebuf );
+ if( msg != NULL )
+ printf("GPGPU-Sim: %s (%s:%u) Syntax error:\n\n", g_filename, g_ptxinfo_filename, yylineno );
+ printf(" %s\n", yylval->linebuf );
printf(" ");
- for( i=0; i < ptxinfo_col-1; i++ ) {
- if( ptxinfo_linebuf[i] == '\t' ) printf("\t");
+ for( i=0; i < yylval->col-1; i++ ) {
+ if( yylval->linebuf[i] == '\t' ) printf("\t");
else printf(" ");
}
diff --git a/src/cuda-sim/ptxinfo.y b/src/cuda-sim/ptxinfo.y
index d241d8c..eed304c 100644
--- a/src/cuda-sim/ptxinfo.y
+++ b/src/cuda-sim/ptxinfo.y
@@ -27,9 +27,20 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+%{
+typedef void * yyscan_t;
+%}
+
+%define api.pure full
+%parse-param {yyscan_t scanner}
+%lex-param {yyscan_t scanner}
+
%union {
+#define LINEBUF_SIZE 1024
int int_value;
char * string_value;
+ char linebuf[LINEBUF_SIZE];
+ unsigned col;
}
%token <int_value> INT_OPERAND
@@ -66,7 +77,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static unsigned g_declared;
static unsigned g_system;
- int ptxinfo_lex(void);
+ int ptxinfo_lex(YYSTYPE * yylval_param, yyscan_t yyscanner);
+ void yyerror(yyscan_t yyscanner, const char* msg);
void ptxinfo_addinfo();
void ptxinfo_function(const char *fname );
void ptxinfo_regs( unsigned nregs );
@@ -74,7 +86,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
void ptxinfo_gmem( unsigned declared, unsigned system );
void ptxinfo_smem( unsigned declared, unsigned system );
void ptxinfo_cmem( unsigned nbytes, unsigned bank );
- int ptxinfo_error(const char*);
void ptxinfo_linenum( unsigned );
void ptxinfo_dup_type( const char* );
%}
diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc
index 8651869..ca88ec9 100644
--- a/src/gpgpu-sim/addrdec.cc
+++ b/src/gpgpu-sim/addrdec.cc
@@ -165,6 +165,27 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_
assert(tlx->chip < m_n_channel);
break;
}
+ case RANDOM:
+ {
+ new_addr_type chip_address = (addr>>ADDR_CHIP_S);
+ tr1_hash_map<new_addr_type,unsigned>::const_iterator got = address_random_interleaving.find (chip_address);
+ if ( got == address_random_interleaving.end() ) {
+ unsigned new_chip_id = rand() % (m_n_channel*m_n_sub_partition_in_channel);
+ address_random_interleaving[chip_address] = new_chip_id;
+ tlx->chip = new_chip_id/m_n_sub_partition_in_channel;
+ tlx->sub_partition = new_chip_id;
+ }
+ else {
+ unsigned new_chip_id = got->second;
+ tlx->chip = new_chip_id/m_n_sub_partition_in_channel;
+ tlx->sub_partition = new_chip_id;
+ }
+
+ assert(tlx->chip < m_n_channel);
+ assert(tlx->sub_partition < m_n_channel*m_n_sub_partition_in_channel);
+ return;
+ break;
+ }
case CUSTOM:
/* No custom set function implemented */
//Do you custom index here
@@ -175,9 +196,9 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_
}
// combine the chip address and the lower bits of DRAM bank address to form the subpartition ID
- unsigned sub_partition_addr_mask = m_n_sub_partition_in_channel - 1;
+ unsigned sub_partition_addr_mask = m_n_sub_partition_in_channel - 1;
tlx->sub_partition = tlx->chip * m_n_sub_partition_in_channel
- + (tlx->bk & sub_partition_addr_mask);
+ + (tlx->bk & sub_partition_addr_mask);
}
void linear_to_raw_address_translation::addrdec_parseoption(const char *option)
@@ -396,6 +417,10 @@ void linear_to_raw_address_translation::init(unsigned int n_channel, unsigned in
if (run_test) {
sweep_test();
}
+
+ if(memory_partition_indexing == RANDOM)
+ srand (1);
+
}
#include "../tr1_hash_map.h"
diff --git a/src/gpgpu-sim/addrdec.h b/src/gpgpu-sim/addrdec.h
index bdc5fec..a5333fb 100644
--- a/src/gpgpu-sim/addrdec.h
+++ b/src/gpgpu-sim/addrdec.h
@@ -40,6 +40,7 @@ enum partition_index_function{
BITWISE_PERMUTATION,
IPOLY,
PAE,
+ RANDOM,
CUSTOM
};
@@ -55,6 +56,7 @@ struct addrdec_t {
unsigned sub_partition;
};
+
class linear_to_raw_address_translation {
public:
linear_to_raw_address_translation();
@@ -62,7 +64,7 @@ public:
void init(unsigned int n_channel, unsigned int n_sub_partition_in_channel);
// accessors
- void addrdec_tlx(new_addr_type addr, addrdec_t *tlx) const;
+ void addrdec_tlx(new_addr_type addr, addrdec_t *tlx) const;
new_addr_type partition_address( new_addr_type addr ) const;
private:
@@ -92,6 +94,7 @@ private:
unsigned int gap;
int m_n_channel;
int m_n_sub_partition_in_channel;
+
};
#endif
diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc
index 6c11b43..5e36d4b 100644
--- a/src/gpgpu-sim/dram.cc
+++ b/src/gpgpu-sim/dram.cc
@@ -42,12 +42,13 @@ template class fifo_pipeline<mem_fetch>;
template class fifo_pipeline<dram_req_t>;
dram_t::dram_t( unsigned int partition_id, const struct memory_config *config, memory_stats_t *stats,
- memory_partition_unit *mp )
+ memory_partition_unit *mp, gpgpu_sim* gpu )
{
id = partition_id;
m_memory_partition_unit = mp;
m_stats = stats;
m_config = config;
+ m_gpu = gpu;
//rowblp
access_num=0;
@@ -191,11 +192,12 @@ unsigned int dram_t::queue_limit() const
}
-dram_req_t::dram_req_t( class mem_fetch *mf, unsigned banks, unsigned dram_bnk_indexing_policy)
+dram_req_t::dram_req_t( class mem_fetch *mf, unsigned banks, unsigned dram_bnk_indexing_policy, class gpgpu_sim* gpu)
{
txbytes = 0;
dqbytes = 0;
data = mf;
+ m_gpu = gpu;
const addrdec_t &tlx = mf->get_tlx_addr();
@@ -226,9 +228,9 @@ dram_req_t::dram_req_t( class mem_fetch *mf, unsigned banks, unsigned dram_bnk_i
col = tlx.col;
nbytes = mf->get_data_size();
- timestamp = gpu_tot_sim_cycle + gpu_sim_cycle;
+ timestamp = m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle;
addr = mf->get_addr();
- insertion_time = (unsigned) gpu_sim_cycle;
+ insertion_time = (unsigned) m_gpu->gpu_sim_cycle;
rw = data->get_is_write()?WRITE:READ;
}
@@ -236,9 +238,9 @@ void dram_t::push( class mem_fetch *data )
{
assert(id == data->get_tlx_addr().chip); // Ensure request is in correct memory partition
- dram_req_t *mrq = new dram_req_t(data,m_config->nbk,m_config->dram_bnk_indexing_policy);
+ dram_req_t *mrq = new dram_req_t(data,m_config->nbk,m_config->dram_bnk_indexing_policy,m_memory_partition_unit->get_mgpu());
- data->set_status(IN_PARTITION_MC_INTERFACE_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ data->set_status(IN_PARTITION_MC_INTERFACE_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
mrqq->push(mrq);
// stats...
@@ -259,7 +261,7 @@ void dram_t::scheduler_fifo()
if (!mrqq->empty()) {
unsigned int bkn;
dram_req_t *head_mrqq = mrqq->top();
- head_mrqq->data->set_status(IN_PARTITION_MC_BANK_ARB_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ head_mrqq->data->set_status(IN_PARTITION_MC_BANK_ARB_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
bkn = head_mrqq->bk;
if (!bk[bkn]->mrq)
bk[bkn]->mrq = mrqq->pop();
@@ -283,7 +285,7 @@ void dram_t::cycle()
if (cmd->dqbytes >= cmd->nbytes) {
mem_fetch *data = cmd->data;
- data->set_status(IN_PARTITION_MC_RETURNQ,gpu_sim_cycle+gpu_tot_sim_cycle);
+ data->set_status(IN_PARTITION_MC_RETURNQ,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
if( data->get_access_type() != L1_WRBK_ACC && data->get_access_type() != L2_WRBK_ACC ) {
data->set_reply();
returnq->push(data);
@@ -566,7 +568,7 @@ bool dram_t::issue_col_command(int j)
bool issued = false;
unsigned grp = get_bankgrp_number(j);
if (bk[j]->mrq) { //if currently servicing a memory request
- bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,gpu_sim_cycle+gpu_tot_sim_cycle);
+ bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
// correct row activated for a READ
if ( !issued && !CCDc && !bk[j]->RCDc &&
!(bkgrp[grp]->CCDLc) &&
@@ -654,7 +656,7 @@ bool dram_t::issue_row_command(int j)
bool issued = false;
unsigned grp = get_bankgrp_number(j);
if (bk[j]->mrq) { //if currently servicing a memory request
- bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,gpu_sim_cycle+gpu_tot_sim_cycle);
+ bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
// bank is idle
//else
if ( !issued && !RRDc &&
@@ -723,10 +725,10 @@ void dram_t::print( FILE* simFile) const
id, m_config->nbk, m_config->busW, m_config->BL, m_config->CL );
fprintf(simFile,"tRRD=%d tCCD=%d, tRCD=%d tRAS=%d tRP=%d tRC=%d\n",
m_config->tRRD, m_config->tCCD, m_config->tRCD, m_config->tRAS, m_config->tRP, m_config->tRC );
- fprintf(simFile,"n_cmd=%d n_nop=%d n_act=%d n_pre=%d n_ref_event=%d n_req=%d n_rd=%d n_rd_L2_A=%d n_write=%d n_wr_bk=%d bw_util=%.4g\n",
+ fprintf(simFile,"n_cmd=%llu n_nop=%llu n_act=%llu n_pre=%llu n_ref_event=%llu n_req=%llu n_rd=%llu n_rd_L2_A=%llu n_write=%llu n_wr_bk=%llu bw_util=%.4g\n",
n_cmd, n_nop, n_act, n_pre, n_ref, n_req, n_rd, n_rd_L2_A, n_wr, n_wr_WB,
(float)bwutil/n_cmd);
- fprintf(simFile,"n_activity=%d dram_eff=%.4g\n",
+ fprintf(simFile,"n_activity=%llu dram_eff=%.4g\n",
n_activity, (float)bwutil/n_activity);
for (i=0;i<m_config->nbk;i++) {
fprintf(simFile, "bk%d: %da %di ",i,bk[i]->n_access,bk[i]->n_idle);
@@ -745,39 +747,39 @@ void dram_t::print( FILE* simFile) const
printf("\nBW Util details:\n");
printf("bwutil = %.6f \n", (float)bwutil/n_cmd);
- printf("total_CMD = %d \n", n_cmd);
- printf("util_bw = %d \n", util_bw);
- printf("Wasted_Col = %d \n", wasted_bw_col);
- printf("Wasted_Row = %d \n", wasted_bw_row);
- printf("Idle = %d \n", idle_bw);
+ printf("total_CMD = %llu \n", n_cmd);
+ printf("util_bw = %llu \n", util_bw);
+ printf("Wasted_Col = %llu \n", wasted_bw_col);
+ printf("Wasted_Row = %llu \n", wasted_bw_row);
+ printf("Idle = %llu \n", idle_bw);
printf("\nBW Util Bottlenecks: \n");
- printf("RCDc_limit = %d \n", RCDc_limit);
- printf("RCDWRc_limit = %d \n", RCDWRc_limit);
- printf("WTRc_limit = %d \n", WTRc_limit);
- printf("RTWc_limit = %d \n", RTWc_limit);
- printf("CCDLc_limit = %d \n", CCDLc_limit);
- printf("rwq = %d \n", rwq_limit);
- printf("CCDLc_limit_alone = %d \n", CCDLc_limit_alone);
- printf("WTRc_limit_alone = %d \n", WTRc_limit_alone);
- printf("RTWc_limit_alone = %d \n", RTWc_limit_alone);
+ printf("RCDc_limit = %llu \n", RCDc_limit);
+ printf("RCDWRc_limit = %llu \n", RCDWRc_limit);
+ printf("WTRc_limit = %llu \n", WTRc_limit);
+ printf("RTWc_limit = %llu \n", RTWc_limit);
+ printf("CCDLc_limit = %llu \n", CCDLc_limit);
+ printf("rwq = %llu \n", rwq_limit);
+ printf("CCDLc_limit_alone = %llu \n", CCDLc_limit_alone);
+ printf("WTRc_limit_alone = %llu \n", WTRc_limit_alone);
+ printf("RTWc_limit_alone = %llu \n", RTWc_limit_alone);
printf("\nCommands details: \n");
- printf("total_CMD = %d \n", n_cmd);
- printf("n_nop = %d \n", n_nop);
- printf("Read = %d \n", n_rd);
- printf("Write = %d \n",n_wr);
- printf("L2_Alloc = %d \n", n_rd_L2_A);
- printf("L2_WB = %d \n", n_wr_WB);
- printf("n_act = %d \n", n_act);
- printf("n_pre = %d \n", n_pre);
- printf("n_ref = %d \n", n_ref);
- printf("n_req = %d \n", n_req );
- printf("total_req = %d \n", n_rd+n_wr+n_rd_L2_A+n_wr_WB);
+ printf("total_CMD = %llu \n", n_cmd);
+ printf("n_nop = %llu \n", n_nop);
+ printf("Read = %llu \n", n_rd);
+ printf("Write = %llu \n",n_wr);
+ printf("L2_Alloc = %llu \n", n_rd_L2_A);
+ printf("L2_WB = %llu \n", n_wr_WB);
+ printf("n_act = %llu \n", n_act);
+ printf("n_pre = %llu \n", n_pre);
+ printf("n_ref = %llu \n", n_ref);
+ printf("n_req = %llu \n", n_req );
+ printf("total_req = %llu \n", n_rd+n_wr+n_rd_L2_A+n_wr_WB);
printf("\nDual Bus Interface Util: \n");
- printf("issued_total_row = %lu \n", issued_total_row);
- printf("issued_total_col = %lu \n", issued_total_col);
+ printf("issued_total_row = %llu \n", issued_total_row);
+ printf("issued_total_col = %llu \n", issued_total_col);
printf("Row_Bus_Util = %.6f \n", (float)issued_total_row / n_cmd);
printf("CoL_Bus_Util = %.6f \n", (float)issued_total_col / n_cmd);
printf("Either_Row_CoL_Bus_Util = %.6f \n", (float)issued_total / n_cmd);
@@ -815,7 +817,7 @@ void dram_t::visualize() const
void dram_t::print_stat( FILE* simFile )
{
- fprintf(simFile,"DRAM (%d): n_cmd=%d n_nop=%d n_act=%d n_pre=%d n_ref=%d n_req=%d n_rd=%d n_write=%d bw_util=%.4g ",
+ fprintf(simFile,"DRAM (%llu): n_cmd=%llu n_nop=%llu n_act=%llu n_pre=%llu n_ref=%llu n_req=%llu n_rd=%llu n_write=%llu bw_util=%.4g ",
id, n_cmd, n_nop, n_act, n_pre, n_ref, n_req, n_rd, n_wr,
(float)bwutil/n_cmd);
fprintf(simFile, "mrqq: %d %.4g mrqsmax=%d ", max_mrqs, (float)ave_mrqs/n_cmd, max_mrqs_temp);
diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h
index bee5b7b..7a3a2da 100644
--- a/src/gpgpu-sim/dram.h
+++ b/src/gpgpu-sim/dram.h
@@ -48,7 +48,7 @@
class dram_req_t {
public:
- dram_req_t( class mem_fetch *data , unsigned banks, unsigned dram_bnk_indexing_policy);
+ dram_req_t( class mem_fetch *data , unsigned banks, unsigned dram_bnk_indexing_policy, class gpgpu_sim* gpu);
unsigned int row;
unsigned int col;
@@ -62,6 +62,7 @@ public:
unsigned long long int addr;
unsigned int insertion_time;
class mem_fetch * data;
+ class gpgpu_sim * m_gpu;
};
struct bankgrp_t
@@ -110,7 +111,7 @@ class dram_t
{
public:
dram_t( unsigned int parition_id, const struct memory_config *config, class memory_stats_t *stats,
- class memory_partition_unit *mp );
+ class memory_partition_unit *mp, class gpgpu_sim* gpu );
bool full(bool is_write) const;
void print( FILE* simFile ) const;
@@ -129,6 +130,7 @@ public:
void dram_log (int task);
class memory_partition_unit *m_memory_partition_unit;
+ class gpgpu_sim* m_gpu;
unsigned int id;
// Power Model
@@ -178,39 +180,39 @@ private:
unsigned int dram_eff_bins[10];
unsigned int last_n_cmd, last_n_activity, last_bwutil;
- unsigned int n_cmd;
- unsigned int n_activity;
- unsigned int n_nop;
- unsigned int n_act;
- unsigned int n_pre;
- unsigned int n_ref;
- unsigned int n_rd;
- unsigned int n_rd_L2_A;
- unsigned int n_wr;
- unsigned int n_wr_WB;
- unsigned int n_req;
- unsigned int max_mrqs_temp;
+ unsigned long long n_cmd;
+ unsigned long long n_activity;
+ unsigned long long n_nop;
+ unsigned long long n_act;
+ unsigned long long n_pre;
+ unsigned long long n_ref;
+ unsigned long long n_rd;
+ unsigned long long n_rd_L2_A;
+ unsigned long long n_wr;
+ unsigned long long n_wr_WB;
+ unsigned long long n_req;
+ unsigned long long max_mrqs_temp;
- //some statistics to collect to see where BW is wasted?
- unsigned wasted_bw_row;
- unsigned wasted_bw_col;
- unsigned util_bw;
- unsigned idle_bw;
- unsigned RCDc_limit;
- unsigned CCDLc_limit;
- unsigned CCDLc_limit_alone;
- unsigned CCDc_limit;
- unsigned WTRc_limit;
- unsigned WTRc_limit_alone;
- unsigned RCDWRc_limit;
- unsigned RTWc_limit;
- unsigned RTWc_limit_alone;
- unsigned rwq_limit;
+ //some statistics to see where BW is wasted?
+ unsigned long long wasted_bw_row;
+ unsigned long long wasted_bw_col;
+ unsigned long long util_bw;
+ unsigned long long idle_bw;
+ unsigned long long RCDc_limit;
+ unsigned long long CCDLc_limit;
+ unsigned long long CCDLc_limit_alone;
+ unsigned long long CCDc_limit;
+ unsigned long long WTRc_limit;
+ unsigned long long WTRc_limit_alone;
+ unsigned long long RCDWRc_limit;
+ unsigned long long RTWc_limit;
+ unsigned long long RTWc_limit_alone;
+ unsigned long long rwq_limit;
//row locality, BLP and other statistics
- unsigned long access_num;
- unsigned long read_num;
- unsigned long write_num;
+ unsigned long long access_num;
+ unsigned long long read_num;
+ unsigned long long write_num;
unsigned long long hits_num;
unsigned long long hits_read_num;
unsigned long long hits_write_num;
diff --git a/src/gpgpu-sim/dram_sched.cc b/src/gpgpu-sim/dram_sched.cc
index ff50050..6ee6271 100644
--- a/src/gpgpu-sim/dram_sched.cc
+++ b/src/gpgpu-sim/dram_sched.cc
@@ -84,13 +84,13 @@ void frfcfs_scheduler::add_req( dram_req_t *req )
void frfcfs_scheduler::data_collection(unsigned int bank)
{
- if (gpu_sim_cycle > row_service_timestamp[bank]) {
- curr_row_service_time[bank] = gpu_sim_cycle - row_service_timestamp[bank];
+ if (m_dram->m_gpu->gpu_sim_cycle > row_service_timestamp[bank]) {
+ curr_row_service_time[bank] = m_dram->m_gpu->gpu_sim_cycle - row_service_timestamp[bank];
if (curr_row_service_time[bank] > m_stats->max_servicetime2samerow[m_dram->id][bank])
m_stats->max_servicetime2samerow[m_dram->id][bank] = curr_row_service_time[bank];
}
curr_row_service_time[bank] = 0;
- row_service_timestamp[bank] = gpu_sim_cycle;
+ row_service_timestamp[bank] = m_dram->m_gpu->gpu_sim_cycle;
if (m_stats->concurrent_row_access[m_dram->id][bank] > m_stats->max_conc_access2samerow[m_dram->id][bank]) {
m_stats->max_conc_access2samerow[m_dram->id][bank] = m_stats->concurrent_row_access[m_dram->id][bank];
}
@@ -215,7 +215,7 @@ void dram_t::scheduler_frfcfs()
m_stats->total_n_reads++;
}
- req->data->set_status(IN_PARTITION_MC_INPUT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ req->data->set_status(IN_PARTITION_MC_INPUT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
sched->add_req(req);
}
@@ -228,14 +228,14 @@ void dram_t::scheduler_frfcfs()
req = sched->schedule(b, bk[b]->curr_row);
if ( req ) {
- req->data->set_status(IN_PARTITION_MC_BANK_ARB_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ req->data->set_status(IN_PARTITION_MC_BANK_ARB_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
prio = (prio+1)%m_config->nbk;
bk[b]->mrq = req;
if (m_config->gpgpu_memlatency_stat) {
- mrq_latency = gpu_sim_cycle + gpu_tot_sim_cycle - bk[b]->mrq->timestamp;
+ mrq_latency = m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle - bk[b]->mrq->timestamp;
m_stats->tot_mrq_latency += mrq_latency;
m_stats->tot_mrq_num++;
- bk[b]->mrq->timestamp = gpu_tot_sim_cycle + gpu_sim_cycle;
+ bk[b]->mrq->timestamp =m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle;
m_stats->mrq_lat_table[LOGB2(mrq_latency)]++;
if (mrq_latency > m_stats->max_mrq_latency) {
m_stats->max_mrq_latency = mrq_latency;
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc
index ba81440..62849f8 100644
--- a/src/gpgpu-sim/gpu-cache.cc
+++ b/src/gpgpu-sim/gpu-cache.cc
@@ -26,6 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "gpu-cache.h"
+#include "gpu-sim.h"
#include "stat-tool.h"
#include <assert.h>
@@ -256,7 +257,7 @@ enum cache_request_status tag_array::probe( new_addr_type addr, unsigned &idx, m
unsigned invalid_line = (unsigned)-1;
unsigned valid_line = (unsigned)-1;
- unsigned valid_timestamp = (unsigned)-1;
+ unsigned long long valid_timestamp = (unsigned)-1;
bool all_reserved = true;
@@ -654,7 +655,7 @@ enum cache_request_status cache_stats::select_stats_status(enum cache_request_st
return access;
}
-unsigned &cache_stats::operator()(int access_type, int access_outcome, bool fail_outcome){
+unsigned long long &cache_stats::operator()(int access_type, int access_outcome, bool fail_outcome){
///
/// Simple method to read/modify the stat corresponding to (access_type, access_outcome)
/// Used overloaded () to avoid the need for separate read/write member functions
@@ -673,7 +674,7 @@ unsigned &cache_stats::operator()(int access_type, int access_outcome, bool fail
}
}
-unsigned cache_stats::operator()(int access_type, int access_outcome, bool fail_outcome) const{
+unsigned long long cache_stats::operator()(int access_type, int access_outcome, bool fail_outcome) const{
///
/// Const accessor into m_stats.
///
@@ -740,7 +741,7 @@ void cache_stats::print_stats(FILE *fout, const char *cache_name) const{
std::string m_cache_name = cache_name;
for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
- fprintf(fout, "\t%s[%s][%s] = %u\n",
+ fprintf(fout, "\t%s[%s][%s] = %llu\n",
m_cache_name.c_str(),
mem_access_type_str((enum mem_access_type)type),
cache_request_status_str((enum cache_request_status)status),
@@ -751,7 +752,7 @@ void cache_stats::print_stats(FILE *fout, const char *cache_name) const{
}
for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
if(total_access[type] > 0)
- fprintf(fout, "\t%s[%s][%s] = %u\n",
+ fprintf(fout, "\t%s[%s][%s] = %llu\n",
m_cache_name.c_str(),
mem_access_type_str((enum mem_access_type)type),
"TOTAL_ACCESS",
@@ -788,13 +789,13 @@ void cache_sub_stats::print_port_stats(FILE *fout, const char *cache_name) const
fprintf(fout, "%s_fill_port_util = %.3f\n", cache_name, fill_port_util);
}
-unsigned cache_stats::get_stats(enum mem_access_type *access_type, unsigned num_access_type, enum cache_request_status *access_status, unsigned num_access_status) const{
+unsigned long long cache_stats::get_stats(enum mem_access_type *access_type, unsigned num_access_type, enum cache_request_status *access_status, unsigned num_access_status) const{
///
/// Returns a sum of the stats corresponding to each "access_type" and "access_status" pair.
/// "access_type" is an array of "num_access_type" mem_access_types.
/// "access_status" is an array of "num_access_status" cache_request_statuses.
///
- unsigned total=0;
+ unsigned long long total=0;
for(unsigned type =0; type < num_access_type; ++type){
for(unsigned status=0; status < num_access_status; ++status){
if(!check_valid((int)access_type[type], (int)access_status[status]))
@@ -1183,7 +1184,8 @@ data_cache::wr_miss_wa_naive( new_addr_type addr,
mf->get_wid(),
mf->get_sid(),
mf->get_tpc(),
- mf->get_mem_config());
+ mf->get_mem_config(),
+ m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle);
bool do_miss = false;
bool wb = false;
@@ -1201,7 +1203,7 @@ data_cache::wr_miss_wa_naive( new_addr_type addr,
if( wb && (m_config.m_write_policy != WRITE_THROUGH) ) {
assert(status == MISS); //SECTOR_MISS and HIT_RESERVED should not send write back
mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr,
- m_wrbk_type,evicted.m_modified_size,true);
+ m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle);
send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events);
}
return MISS;
@@ -1245,7 +1247,7 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr,
// (already modified lower level)
if( wb && (m_config.m_write_policy != WRITE_THROUGH) ) {
mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr,
- m_wrbk_type,evicted.m_modified_size,true);
+ m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle);
send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events);
}
return MISS;
@@ -1297,6 +1299,7 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr,
mf->get_sid(),
mf->get_tpc(),
mf->get_mem_config(),
+ m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle,
NULL,
mf);
@@ -1320,7 +1323,7 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr,
// (already modified lower level)
if(wb && (m_config.m_write_policy != WRITE_THROUGH) ){
mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr,
- m_wrbk_type,evicted.m_modified_size,true);
+ m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle);
send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events);
}
return MISS;
@@ -1373,7 +1376,7 @@ data_cache::wr_miss_wa_lazy_fetch_on_read( new_addr_type addr,
// (already modified lower level)
if( wb && (m_config.m_write_policy != WRITE_THROUGH) ) {
mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr,
- m_wrbk_type,evicted.m_modified_size,true);
+ m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle);
send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events);
}
return MISS;
@@ -1458,7 +1461,7 @@ data_cache::rd_miss_base( new_addr_type addr,
// (already modified lower level)
if(wb && (m_config.m_write_policy != WRITE_THROUGH) ){
mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr,
- m_wrbk_type,evicted.m_modified_size,true);
+ m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle);
send_write_request(wb, WRITE_BACK_REQUEST_SENT, time, events);
}
return MISS;
diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h
index e663cf6..85e534e 100644
--- a/src/gpgpu-sim/gpu-cache.h
+++ b/src/gpgpu-sim/gpu-cache.h
@@ -119,9 +119,9 @@ struct cache_block_t {
virtual enum cache_block_state get_status( mem_access_sector_mask_t sector_mask) = 0;
virtual void set_status(enum cache_block_state m_status, mem_access_sector_mask_t sector_mask) = 0;
- virtual unsigned get_last_access_time() = 0;
- virtual void set_last_access_time(unsigned time, mem_access_sector_mask_t sector_mask) = 0;
- virtual unsigned get_alloc_time() = 0;
+ virtual unsigned long long get_last_access_time() = 0;
+ virtual void set_last_access_time(unsigned long long time, mem_access_sector_mask_t sector_mask) = 0;
+ virtual unsigned long long get_alloc_time() = 0;
virtual void set_ignore_on_fill(bool m_ignore, mem_access_sector_mask_t sector_mask) = 0;
virtual void set_modified_on_fill(bool m_modified, mem_access_sector_mask_t sector_mask) = 0;
virtual unsigned get_modified_size() = 0;
@@ -192,15 +192,15 @@ struct line_cache_block: public cache_block_t {
{
m_status = status;
}
- virtual unsigned get_last_access_time()
+ virtual unsigned long long get_last_access_time()
{
return m_last_access_time;
}
- virtual void set_last_access_time(unsigned time, mem_access_sector_mask_t sector_mask)
+ virtual void set_last_access_time(unsigned long long time, mem_access_sector_mask_t sector_mask)
{
m_last_access_time = time;
}
- virtual unsigned get_alloc_time()
+ virtual unsigned long long get_alloc_time()
{
return m_alloc_time;
}
@@ -229,9 +229,9 @@ struct line_cache_block: public cache_block_t {
private:
- unsigned m_alloc_time;
- unsigned m_last_access_time;
- unsigned m_fill_time;
+ unsigned long long m_alloc_time;
+ unsigned long long m_last_access_time;
+ unsigned long long m_fill_time;
cache_block_state m_status;
bool m_ignore_on_fill_status;
bool m_set_modified_on_fill;
@@ -364,12 +364,12 @@ struct sector_cache_block : public cache_block_t {
m_status[sidx] = status;
}
- virtual unsigned get_last_access_time()
+ virtual unsigned long long get_last_access_time()
{
return m_line_last_access_time;
}
- virtual void set_last_access_time(unsigned time, mem_access_sector_mask_t sector_mask)
+ virtual void set_last_access_time(unsigned long long time, mem_access_sector_mask_t sector_mask)
{
unsigned sidx = get_sector_index(sector_mask);
@@ -377,7 +377,7 @@ struct sector_cache_block : public cache_block_t {
m_line_last_access_time = time;
}
- virtual unsigned get_alloc_time()
+ virtual unsigned long long get_alloc_time()
{
return m_line_alloc_time;
}
@@ -915,10 +915,10 @@ private:
/// Simple struct to maintain cache accesses, misses, pending hits, and reservation fails.
///
struct cache_sub_stats{
- unsigned accesses;
- unsigned misses;
- unsigned pending_hits;
- unsigned res_fails;
+ unsigned long long accesses;
+ unsigned long long misses;
+ unsigned long long pending_hits;
+ unsigned long long res_fails;
unsigned long long port_available_cycles;
unsigned long long data_port_busy_cycles;
@@ -981,14 +981,14 @@ public:
void inc_stats(int access_type, int access_outcome);
void inc_fail_stats(int access_type, int fail_outcome);
enum cache_request_status select_stats_status(enum cache_request_status probe, enum cache_request_status access) const;
- unsigned &operator()(int access_type, int access_outcome, bool fail_outcome);
- unsigned operator()(int access_type, int access_outcome, bool fail_outcome) const;
+ unsigned long long &operator()(int access_type, int access_outcome, bool fail_outcome);
+ unsigned long long operator()(int access_type, int access_outcome, bool fail_outcome) const;
cache_stats operator+(const cache_stats &cs);
cache_stats &operator+=(const cache_stats &cs);
void print_stats(FILE *fout, const char *cache_name = "Cache_stats") const;
void print_fail_stats(FILE *fout, const char *cache_name = "Cache_fail_stats") const;
- unsigned get_stats(enum mem_access_type *access_type, unsigned num_access_type, enum cache_request_status *access_status, unsigned num_access_status) const;
+ unsigned long long get_stats(enum mem_access_type *access_type, unsigned num_access_type, enum cache_request_status *access_status, unsigned num_access_status) const;
void get_sub_stats(struct cache_sub_stats &css) const;
void sample_cache_port_utility(bool data_port_busy, bool fill_port_busy);
@@ -996,8 +996,8 @@ private:
bool check_valid(int type, int status) const;
bool check_fail_valid(int type, int fail) const;
- std::vector< std::vector<unsigned> > m_stats;
- std::vector< std::vector<unsigned> > m_fail_stats;
+ std::vector< std::vector<unsigned long long> > m_stats;
+ std::vector< std::vector<unsigned long long> > m_fail_stats;
unsigned long long m_cache_port_available_cycles;
unsigned long long m_cache_data_port_busy_cycles;
@@ -1212,12 +1212,13 @@ public:
data_cache( const char *name, cache_config &config,
int core_id, int type_id, mem_fetch_interface *memport,
mem_fetch_allocator *mfcreator, enum mem_fetch_status status,
- mem_access_type wr_alloc_type, mem_access_type wrbk_type )
+ mem_access_type wr_alloc_type, mem_access_type wrbk_type, class gpgpu_sim* gpu )
: baseline_cache(name,config,core_id,type_id,memport,status)
{
init( mfcreator );
m_wr_alloc_type = wr_alloc_type;
m_wrbk_type = wrbk_type;
+ m_gpu=gpu;
}
virtual ~data_cache() {}
@@ -1275,16 +1276,19 @@ protected:
enum mem_fetch_status status,
tag_array* new_tag_array,
mem_access_type wr_alloc_type,
- mem_access_type wrbk_type)
+ mem_access_type wrbk_type,
+ class gpgpu_sim* gpu )
: baseline_cache(name, config, core_id, type_id, memport,status, new_tag_array)
{
init( mfcreator );
m_wr_alloc_type = wr_alloc_type;
m_wrbk_type = wrbk_type;
+ m_gpu=gpu;
}
mem_access_type m_wr_alloc_type; // Specifies type of write allocate request (e.g., L1 or L2)
mem_access_type m_wrbk_type; // Specifies type of writeback request (e.g., L1 or L2)
+ class gpgpu_sim* m_gpu;
//! A general function that takes the result of a tag_array probe
// and performs the correspding functions based on the cache configuration
@@ -1441,8 +1445,8 @@ class l1_cache : public data_cache {
public:
l1_cache(const char *name, cache_config &config,
int core_id, int type_id, mem_fetch_interface *memport,
- mem_fetch_allocator *mfcreator, enum mem_fetch_status status )
- : data_cache(name,config,core_id,type_id,memport,mfcreator,status, L1_WR_ALLOC_R, L1_WRBK_ACC){}
+ mem_fetch_allocator *mfcreator, enum mem_fetch_status status, class gpgpu_sim* gpu )
+ : data_cache(name,config,core_id,type_id,memport,mfcreator,status, L1_WR_ALLOC_R, L1_WRBK_ACC, gpu){}
virtual ~l1_cache(){}
@@ -1460,10 +1464,11 @@ protected:
mem_fetch_interface *memport,
mem_fetch_allocator *mfcreator,
enum mem_fetch_status status,
- tag_array* new_tag_array )
+ tag_array* new_tag_array,
+ class gpgpu_sim* gpu)
: data_cache( name,
config,
- core_id,type_id,memport,mfcreator,status, new_tag_array, L1_WR_ALLOC_R, L1_WRBK_ACC ){}
+ core_id,type_id,memport,mfcreator,status, new_tag_array, L1_WR_ALLOC_R, L1_WRBK_ACC, gpu ){}
};
@@ -1473,8 +1478,8 @@ class l2_cache : public data_cache {
public:
l2_cache(const char *name, cache_config &config,
int core_id, int type_id, mem_fetch_interface *memport,
- mem_fetch_allocator *mfcreator, enum mem_fetch_status status )
- : data_cache(name,config,core_id,type_id,memport,mfcreator,status, L2_WR_ALLOC_R, L2_WRBK_ACC){}
+ mem_fetch_allocator *mfcreator, enum mem_fetch_status status, class gpgpu_sim* gpu )
+ : data_cache(name,config,core_id,type_id,memport,mfcreator,status, L2_WR_ALLOC_R, L2_WRBK_ACC, gpu){}
virtual ~l2_cache() {}
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index ec570bf..6f19640 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -82,22 +82,7 @@ class gpgpu_sim_wrapper {};
bool g_interactive_debugger_enabled=false;
-
-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_dramfull = 0;
-unsigned int gpu_stall_icnt2sh = 0;
-unsigned long long partiton_reqs_in_parallel = 0;
-unsigned long long partiton_reqs_in_parallel_total = 0;
-unsigned long long partiton_reqs_in_parallel_util = 0;
-unsigned long long partiton_reqs_in_parallel_util_total = 0;
-unsigned long long gpu_sim_cycle_parition_util = 0;
-unsigned long long gpu_tot_sim_cycle_parition_util = 0;
-unsigned long long partiton_replys_in_parallel = 0;
-unsigned long long partiton_replys_in_parallel_total = 0;
+tr1_hash_map<new_addr_type,unsigned> address_random_interleaving;
/* Clock Domains */
@@ -110,8 +95,6 @@ unsigned long long partiton_replys_in_parallel_total = 0;
#define MEM_LATENCY_STAT_IMPL
-
-
#include "mem_latency_stat.h"
void power_config::reg_options(class OptionParser * opp)
@@ -315,8 +298,8 @@ void shader_core_config::reg_options(class OptionParser * opp)
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, "-adpative_volta_cache_config", OPT_BOOL, &adpative_volta_cache_config,
- "adpative_volta_cache_config",
+ option_parser_register(opp, "-adaptive_volta_cache_config", OPT_BOOL, &adaptive_volta_cache_config,
+ "adaptive_volta_cache_config",
"0");
option_parser_register(opp, "-gpgpu_shmem_size", OPT_UINT32, &gpgpu_shmem_sizeDefault,
"Size of shared memory per shader core (default 16kB)",
@@ -476,6 +459,7 @@ void shader_core_config::reg_options(class OptionParser * opp)
option_parser_register(opp, "-gpgpu_concurrent_kernel_sm", OPT_BOOL, &gpgpu_concurrent_kernel_sm,
"Support concurrent kernels on a SM (default = disabled)",
"0");
+
}
void gpgpu_sim_config::reg_options(option_parser_t opp)
@@ -499,6 +483,12 @@ void gpgpu_sim_config::reg_options(option_parser_t opp)
option_parser_register(opp, "-liveness_message_freq", OPT_INT64, &liveness_message_freq,
"Minimum number of seconds between simulation liveness messages (0 = always print)",
"1");
+ option_parser_register(opp, "-gpgpu_compute_capability_major", OPT_UINT32, &gpgpu_compute_capability_major,
+ "Major compute capability version number",
+ "7");
+ option_parser_register(opp, "-gpgpu_compute_capability_minor", OPT_UINT32, &gpgpu_compute_capability_minor,
+ "Minor compute capability version number",
+ "0");
option_parser_register(opp, "-gpgpu_flush_l1_cache", OPT_BOOL, &gpgpu_flush_l1_cache,
"Flush L1 cache at the end of each kernel call",
"0");
@@ -532,6 +522,14 @@ void gpgpu_sim_config::reg_options(option_parser_t opp)
option_parser_register(opp, "-visualizer_zlevel", OPT_INT32,
&g_visualizer_zlevel, "Compression level of the visualizer output log (0=no comp, 9=highest)",
"6");
+ option_parser_register(opp, "-gpgpu_stack_size_limit", OPT_INT32, &stack_size_limit,
+ "GPU thread stack size", "1024" );
+ option_parser_register(opp, "-gpgpu_heap_size_limit", OPT_INT32, &heap_size_limit,
+ "GPU malloc heap size ", "8388608" );
+ option_parser_register(opp, "-gpgpu_runtime_sync_depth_limit", OPT_INT32, &runtime_sync_depth_limit,
+ "GPU device runtime synchronize depth", "2" );
+ option_parser_register(opp, "-gpgpu_runtime_pending_launch_count_limit", OPT_INT32, &runtime_pending_launch_count_limit,
+ "GPU device runtime pending launch count", "2048" );
option_parser_register(opp, "-trace_enabled", OPT_BOOL,
&Trace::enabled, "Turn on traces",
"0");
@@ -714,7 +712,7 @@ gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config )
#endif
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);
+ m_memory_stats = new memory_stats_t(m_config.num_shader(),m_shader_config,m_memory_config,this);
average_pipeline_duty_cycle = (float *)malloc(sizeof(float));
active_sms=(float *)malloc(sizeof(float));
m_power_stats = new power_stat_t(m_shader_config,average_pipeline_duty_cycle,active_sms,m_shader_stats,m_memory_config,m_memory_stats);
@@ -725,6 +723,16 @@ gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config )
m_total_cta_launched = 0;
gpu_deadlock = false;
+ gpu_stall_dramfull = 0;
+ gpu_stall_icnt2sh = 0;
+ partiton_reqs_in_parallel = 0;
+ partiton_reqs_in_parallel_total = 0;
+ partiton_reqs_in_parallel_util = 0;
+ partiton_reqs_in_parallel_util_total = 0;
+ gpu_sim_cycle_parition_util = 0;
+ gpu_tot_sim_cycle_parition_util = 0;
+ partiton_replys_in_parallel = 0;
+ partiton_replys_in_parallel_total = 0;
m_cluster = new simt_core_cluster*[m_shader_config->n_simt_clusters];
for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++)
@@ -733,7 +741,7 @@ gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config )
m_memory_partition_unit = new memory_partition_unit*[m_memory_config->m_n_mem];
m_memory_sub_partition = new memory_sub_partition*[m_memory_config->m_n_mem_sub_partition];
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[i] = new memory_partition_unit(i, m_memory_config, m_memory_stats, this);
for (unsigned p = 0; p < m_memory_config->m_n_sub_partition_per_memory_channel; p++) {
unsigned submpid = i * m_memory_config->m_n_sub_partition_per_memory_channel + p;
m_memory_sub_partition[submpid] = m_memory_partition_unit[i]->get_sub_partition(p);
@@ -794,6 +802,16 @@ void gpgpu_sim::set_prop( cudaDeviceProp *prop )
m_cuda_properties = prop;
}
+int gpgpu_sim::compute_capability_major() const
+{
+ return m_config.gpgpu_compute_capability_major;
+}
+
+int gpgpu_sim::compute_capability_minor() const
+{
+ return m_config.gpgpu_compute_capability_minor;
+}
+
const struct cudaDeviceProp *gpgpu_sim::get_prop() const
{
return m_cuda_properties;
@@ -1157,19 +1175,19 @@ void gpgpu_sim::gpu_print_stat()
m_memory_sub_partition[i]->accumulate_L2cache_stats(l2_stats);
m_memory_sub_partition[i]->get_L2cache_sub_stats(l2_css);
- fprintf( stdout, "L2_cache_bank[%d]: Access = %u, Miss = %u, Miss_rate = %.3lf, Pending_hits = %u, Reservation_fails = %u\n",
+ fprintf( stdout, "L2_cache_bank[%d]: Access = %llu, Miss = %llu, Miss_rate = %.3lf, Pending_hits = %llu, Reservation_fails = %llu\n",
i, l2_css.accesses, l2_css.misses, (double)l2_css.misses / (double)l2_css.accesses, l2_css.pending_hits, l2_css.res_fails);
total_l2_css += l2_css;
}
if (!m_memory_config->m_L2_config.disabled() && m_memory_config->m_L2_config.get_num_lines()) {
//L2c_print_cache_stat();
- printf("L2_total_cache_accesses = %u\n", total_l2_css.accesses);
- printf("L2_total_cache_misses = %u\n", total_l2_css.misses);
+ printf("L2_total_cache_accesses = %llu\n", total_l2_css.accesses);
+ printf("L2_total_cache_misses = %llu\n", total_l2_css.misses);
if(total_l2_css.accesses > 0)
printf("L2_total_cache_miss_rate = %.4lf\n", (double)total_l2_css.misses/(double)total_l2_css.accesses);
- printf("L2_total_cache_pending_hits = %u\n", total_l2_css.pending_hits);
- printf("L2_total_cache_reservation_fails = %u\n", total_l2_css.res_fails);
+ printf("L2_total_cache_pending_hits = %llu\n", total_l2_css.pending_hits);
+ printf("L2_total_cache_reservation_fails = %llu\n", total_l2_css.res_fails);
printf("L2_total_cache_breakdown:\n");
l2_stats.print_stats(stdout, "L2_cache_stats_breakdown");
printf("L2_total_cache_reservation_fail_breakdown:\n");
@@ -1477,7 +1495,7 @@ void shader_core_ctx::issue_block2core( kernel_info_t &kernel )
shader_CTA_count_log(m_sid, 1);
SHADER_DPRINTF(LIVENESS, "GPGPU-Sim uArch: cta:%2u, start_tid:%4u, end_tid:%4u, initialized @(%lld,%lld)\n",
- free_cta_hw_id, start_thread, end_thread, gpu_sim_cycle, gpu_tot_sim_cycle );
+ free_cta_hw_id, start_thread, end_thread, m_gpu->gpu_sim_cycle, m_gpu->gpu_tot_sim_cycle );
}
@@ -1694,7 +1712,7 @@ void gpgpu_sim::cycle()
for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) {
m_cluster[i]->get_current_occupancy(active, total);
}
- DPRINTF(LIVENESS, "uArch: inst.: %lld (ipc=%4.1f, occ=%0.4f\% [%llu / %llu]) sim_rate=%u (inst/sec) elapsed = %u:%u:%02u:%02u / %s",
+ DPRINTFG(LIVENESS, "uArch: inst.: %lld (ipc=%4.1f, occ=%0.4f\% [%llu / %llu]) sim_rate=%u (inst/sec) elapsed = %u:%u:%02u:%02u / %s",
gpu_tot_sim_insn + gpu_sim_insn,
(double)gpu_sim_insn/(double)gpu_sim_cycle,
float(active)/float(total) * 100, active, total,
diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h
index 6ce5524..5ea5765 100644
--- a/src/gpgpu-sim/gpu-sim.h
+++ b/src/gpgpu-sim/gpu-sim.h
@@ -62,9 +62,7 @@
#define SAMPLELOG 222
#define DUMPLOG 333
-
-
-
+extern tr1_hash_map<new_addr_type,unsigned> address_random_interleaving;
enum dram_ctrl_t {
DRAM_FIFO=0,
@@ -293,9 +291,6 @@ struct memory_config {
bool m_perf_sim_memcpy;
};
-// 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 power_config, public gpgpu_functional_sim_config {
@@ -337,6 +332,11 @@ public:
unsigned get_max_concurrent_kernel() const { return max_concurrent_kernel; }
unsigned checkpoint_option;
+ size_t stack_limit() const {return stack_size_limit; }
+ size_t heap_limit() const {return heap_size_limit; }
+ size_t sync_depth_limit() const {return runtime_sync_depth_limit; }
+ size_t pending_launch_count_limit() const {return runtime_pending_launch_count_limit;}
+
private:
void init_clock_domains(void );
@@ -377,8 +377,15 @@ private:
int gpu_stat_sample_freq;
int gpu_runtime_stat_flag;
+ // Device Limits
+ size_t stack_size_limit;
+ size_t heap_size_limit;
+ size_t runtime_sync_depth_limit;
+ size_t runtime_pending_launch_count_limit;
-
+ //gpu compute capability options
+ unsigned int gpgpu_compute_capability_major;
+ unsigned int gpgpu_compute_capability_minor;
unsigned long long liveness_message_freq;
friend class gpgpu_sim;
@@ -438,6 +445,8 @@ public:
int shared_mem_size() const;
int shared_mem_per_block() const;
+ int compute_capability_major() const;
+ int compute_capability_minor() const;
int num_registers_per_core() const;
int num_registers_per_block() const;
int wrp_size() const;
@@ -553,6 +562,18 @@ public:
occupancy_stats gpu_occupancy;
occupancy_stats gpu_tot_occupancy;
+ // performance counter for stalls due to congestion.
+ unsigned int gpu_stall_dramfull;
+ unsigned int gpu_stall_icnt2sh;
+ unsigned long long partiton_reqs_in_parallel;
+ unsigned long long partiton_reqs_in_parallel_total;
+ unsigned long long partiton_reqs_in_parallel_util;
+ unsigned long long partiton_reqs_in_parallel_util_total;
+ unsigned long long gpu_sim_cycle_parition_util;
+ unsigned long long gpu_tot_sim_cycle_parition_util;
+ unsigned long long partiton_replys_in_parallel;
+ unsigned long long partiton_replys_in_parallel_total;
+
FuncCache get_cache_config(std::string kernel_name);
void set_cache_config(std::string kernel_name, FuncCache cacheConfig );
diff --git a/src/gpgpu-sim/icnt_wrapper.cc b/src/gpgpu-sim/icnt_wrapper.cc
index ee58ece..6e0950c 100644
--- a/src/gpgpu-sim/icnt_wrapper.cc
+++ b/src/gpgpu-sim/icnt_wrapper.cc
@@ -29,6 +29,8 @@
#include <assert.h>
#include "../intersim2/globals.hpp"
#include "../intersim2/interconnect_interface.hpp"
+#include "local_interconnect.h"
+
icnt_create_p icnt_create;
icnt_init_p icnt_init;
@@ -42,9 +44,13 @@ icnt_display_overall_stats_p icnt_display_overall_stats;
icnt_display_state_p icnt_display_state;
icnt_get_flit_size_p icnt_get_flit_size;
-int g_network_mode;
+unsigned g_network_mode;
char* g_network_config_filename;
+
+struct inct_config g_inct_config;
+LocalInterconnect *g_localicnt_interface;
+
#include "../option_parser.h"
// Wrapper to intersim2 to accompany old icnt_wrapper
@@ -105,10 +111,78 @@ static unsigned intersim2_get_flit_size()
return g_icnt_interface->GetFlitSize();
}
+
+//////////////////////////////////////////////////////
+
+static void LocalInterconnect_create(unsigned int n_shader, unsigned int n_mem)
+{
+ g_localicnt_interface->CreateInterconnect(n_shader, n_mem);
+}
+
+static void LocalInterconnect_init()
+{
+ g_localicnt_interface->Init();
+}
+
+static bool LocalInterconnect_has_buffer(unsigned input, unsigned int size)
+{
+ return g_localicnt_interface->HasBuffer(input, size);
+}
+
+static void LocalInterconnect_push(unsigned input, unsigned output, void* data, unsigned int size)
+{
+ g_localicnt_interface->Push(input, output, data, size);
+}
+
+static void* LocalInterconnect_pop(unsigned output)
+{
+ return g_localicnt_interface->Pop(output);
+}
+
+static void LocalInterconnect_transfer()
+{
+ g_localicnt_interface->Advance();
+}
+
+static bool LocalInterconnect_busy()
+{
+ return g_localicnt_interface->Busy();
+}
+
+static void LocalInterconnect_display_stats()
+{
+ g_localicnt_interface->DisplayStats();
+}
+
+static void LocalInterconnect_display_overall_stats()
+{
+ g_localicnt_interface->DisplayOverallStats();
+}
+
+static void LocalInterconnect_display_state(FILE *fp)
+{
+ g_localicnt_interface->DisplayState(fp);
+}
+
+static unsigned LocalInterconnect_get_flit_size()
+{
+ return g_localicnt_interface->GetFlitSize();
+}
+
+
+///////////////////////////
+
void icnt_reg_options( class OptionParser * opp )
{
option_parser_register(opp, "-network_mode", OPT_INT32, &g_network_mode, "Interconnection network mode", "1");
option_parser_register(opp, "-inter_config_file", OPT_CSTR, &g_network_config_filename, "Interconnection network config file", "mesh");
+
+
+ //parameters for local xbar
+ option_parser_register(opp, "-inct_in_buffer_limit", OPT_UINT32, &g_inct_config.in_buffer_limit, "in_buffer_limit", "64");
+ option_parser_register(opp, "-inct_out_buffer_limit", OPT_UINT32, &g_inct_config.out_buffer_limit, "out_buffer_limit", "64");
+ option_parser_register(opp, "-inct_subnets", OPT_UINT32, &g_inct_config.subnets, "subnets", "2");
+
}
void icnt_wrapper_init()
@@ -129,6 +203,20 @@ void icnt_wrapper_init()
icnt_display_state = intersim2_display_state;
icnt_get_flit_size = intersim2_get_flit_size;
break;
+ case LOCAL_XBAR:
+ g_localicnt_interface = LocalInterconnect::New(g_inct_config);
+ icnt_create = LocalInterconnect_create;
+ icnt_init = LocalInterconnect_init;
+ icnt_has_buffer = LocalInterconnect_has_buffer;
+ icnt_push = LocalInterconnect_push;
+ icnt_pop = LocalInterconnect_pop;
+ icnt_transfer = LocalInterconnect_transfer;
+ icnt_busy = LocalInterconnect_busy;
+ icnt_display_stats = LocalInterconnect_display_stats;
+ icnt_display_overall_stats = LocalInterconnect_display_overall_stats;
+ icnt_display_state = LocalInterconnect_display_state;
+ icnt_get_flit_size = LocalInterconnect_get_flit_size;
+ break;
default:
assert(0);
break;
diff --git a/src/gpgpu-sim/icnt_wrapper.h b/src/gpgpu-sim/icnt_wrapper.h
index a4d123e..e1086f9 100644
--- a/src/gpgpu-sim/icnt_wrapper.h
+++ b/src/gpgpu-sim/icnt_wrapper.h
@@ -57,13 +57,16 @@ extern icnt_display_stats_p icnt_display_stats;
extern icnt_display_overall_stats_p icnt_display_overall_stats;
extern icnt_display_state_p icnt_display_state;
extern icnt_get_flit_size_p icnt_get_flit_size;
-extern int g_network_mode;
+extern unsigned g_network_mode;
enum network_mode {
INTERSIM = 1,
+ LOCAL_XBAR = 2,
N_NETWORK_MODE
};
+
+
void icnt_wrapper_init();
void icnt_reg_options( class OptionParser * opp );
diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc
index 25da107..526e999 100644
--- a/src/gpgpu-sim/l2cache.cc
+++ b/src/gpgpu-sim/l2cache.cc
@@ -46,7 +46,7 @@
#include "l2cache_trace.h"
-mem_fetch * partition_mf_allocator::alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr ) const
+mem_fetch * partition_mf_allocator::alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle ) const
{
assert( wr );
mem_access_t access( type, addr, size, wr );
@@ -56,22 +56,25 @@ mem_fetch * partition_mf_allocator::alloc(new_addr_type addr, mem_access_type ty
-1,
-1,
-1,
- m_memory_config );
+ m_memory_config,
+ cycle);
return mf;
}
memory_partition_unit::memory_partition_unit( unsigned partition_id,
const struct memory_config *config,
- class memory_stats_t *stats )
-: m_id(partition_id), m_config(config), m_stats(stats), m_arbitration_metadata(config)
+ class memory_stats_t *stats,
+ class gpgpu_sim* gpu)
+: m_id(partition_id), m_config(config), m_stats(stats), m_arbitration_metadata(config), m_gpu(gpu)
{
- m_dram = new dram_t(m_id,m_config,m_stats,this);
+ m_dram = new dram_t(m_id,m_config,m_stats,this,gpu);
m_sub_partition = new memory_sub_partition*[m_config->m_n_sub_partition_per_memory_channel];
for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel; p++) {
unsigned sub_partition_id = m_id * m_config->m_n_sub_partition_per_memory_channel + p;
- m_sub_partition[p] = new memory_sub_partition(sub_partition_id, m_config, stats);
+ m_sub_partition[p] = new memory_sub_partition(sub_partition_id, m_config, stats, gpu);
}
+
}
void memory_partition_unit::handle_memcpy_to_gpu( size_t addr, unsigned global_subpart_id, mem_access_sector_mask_t mask )
@@ -80,7 +83,7 @@ void memory_partition_unit::handle_memcpy_to_gpu( size_t addr, unsigned global_s
std::string mystring =
mask.to_string<char,std::string::traits_type,std::string::allocator_type>();
MEMPART_DPRINTF("Copy Engine Request Received For Address=%llx, local_subpart=%u, global_subpart=%u, sector_mask=%s \n", addr, p, global_subpart_id, mystring.c_str());
- m_sub_partition[p]->force_l2_tag_update(addr,gpu_sim_cycle+gpu_tot_sim_cycle, mask);
+ m_sub_partition[p]->force_l2_tag_update(addr,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle, mask);
}
memory_partition_unit::~memory_partition_unit()
@@ -218,7 +221,7 @@ void memory_partition_unit::dram_cycle()
delete mf_return;
} else {
m_sub_partition[dest_spid]->dram_L2_queue_push(mf_return);
- mf_return->set_status(IN_PARTITION_DRAM_TO_L2_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf_return->set_status(IN_PARTITION_DRAM_TO_L2_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
m_arbitration_metadata.return_credit(dest_spid);
MEMPART_DPRINTF("mem_fetch request %p return from dram to sub partition %d\n", mf_return, dest_spid);
}
@@ -247,9 +250,9 @@ void memory_partition_unit::dram_cycle()
MEMPART_DPRINTF("Issue mem_fetch request %p from sub partition %d to dram\n", mf, spid);
dram_delay_t d;
d.req = mf;
- d.ready_cycle = gpu_sim_cycle+gpu_tot_sim_cycle + m_config->dram_latency;
+ d.ready_cycle = m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle + m_config->dram_latency;
m_dram_latency_queue.push_back(d);
- mf->set_status(IN_PARTITION_DRAM_LATENCY_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_PARTITION_DRAM_LATENCY_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
m_arbitration_metadata.borrow_credit(spid);
break; // the DRAM should only accept one request per cycle
}
@@ -258,7 +261,7 @@ void memory_partition_unit::dram_cycle()
// DRAM latency queue
- if( !m_dram_latency_queue.empty() && ( (gpu_sim_cycle+gpu_tot_sim_cycle) >= m_dram_latency_queue.front().ready_cycle ) && !m_dram->full(m_dram_latency_queue.front().req->is_write()) ) {
+ if( !m_dram_latency_queue.empty() && ( (m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle) >= m_dram_latency_queue.front().ready_cycle ) && !m_dram->full(m_dram_latency_queue.front().req->is_write()) ) {
mem_fetch* mf = m_dram_latency_queue.front().req;
m_dram_latency_queue.pop_front();
m_dram->push(mf);
@@ -310,11 +313,13 @@ void memory_partition_unit::print( FILE *fp ) const
memory_sub_partition::memory_sub_partition( unsigned sub_partition_id,
const struct memory_config *config,
- class memory_stats_t *stats )
+ class memory_stats_t *stats,
+ class gpgpu_sim* gpu)
{
m_id = sub_partition_id;
m_config=config;
m_stats=stats;
+ m_gpu = gpu;
m_memcpy_cycle_offset = 0;
assert(m_id < m_config->m_n_mem_sub_partition);
@@ -325,7 +330,7 @@ memory_sub_partition::memory_sub_partition( unsigned sub_partition_id,
m_mf_allocator = new partition_mf_allocator(config);
if(!m_config->m_L2_config.disabled())
- m_L2cache = new l2_cache(L2c_name,m_config->m_L2_config,-1,-1,m_L2interface,m_mf_allocator,IN_PARTITION_L2_MISS_QUEUE);
+ m_L2cache = new l2_cache(L2c_name,m_config->m_L2_config,-1,-1,m_L2interface,m_mf_allocator,IN_PARTITION_L2_MISS_QUEUE, gpu);
unsigned int icnt_L2;
unsigned int L2_dram;
@@ -357,7 +362,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
mem_fetch *mf = m_L2cache->next_access();
if(mf->get_access_type() != L2_WR_ALLOC_R){ // Don't pass write allocate read request back to upper level cache
mf->set_reply();
- mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
m_L2_icnt_queue->push(mf);
}else{
if(m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE)
@@ -365,7 +370,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
mem_fetch* original_wr_mf = mf->get_original_wr_mf();
assert(original_wr_mf);
original_wr_mf->set_reply();
- original_wr_mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ original_wr_mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
m_L2_icnt_queue->push(original_wr_mf);
}
m_request_tracker.erase(mf);
@@ -379,13 +384,13 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
mem_fetch *mf = m_dram_L2_queue->top();
if ( !m_config->m_L2_config.disabled() && m_L2cache->waiting_for_fill(mf) ) {
if (m_L2cache->fill_port_free()) {
- mf->set_status(IN_PARTITION_L2_FILL_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
- m_L2cache->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle+m_memcpy_cycle_offset);
+ mf->set_status(IN_PARTITION_L2_FILL_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_L2cache->fill(mf,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle+m_memcpy_cycle_offset);
m_dram_L2_queue->pop();
}
} else if ( !m_L2_icnt_queue->full() ) {
if(mf->is_write() && mf->get_type() == WRITE_ACK)
- mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
m_L2_icnt_queue->push(mf);
m_dram_L2_queue->pop();
}
@@ -406,7 +411,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
bool port_free = m_L2cache->data_port_free();
if ( !output_full && port_free ) {
std::list<cache_event> events;
- enum cache_request_status status = m_L2cache->access(mf->get_addr(),mf,gpu_sim_cycle+gpu_tot_sim_cycle+m_memcpy_cycle_offset,events);
+ enum cache_request_status status = m_L2cache->access(mf->get_addr(),mf,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle+m_memcpy_cycle_offset,events);
bool write_sent = was_write_sent(events);
bool read_sent = was_read_sent(events);
MEM_SUBPART_DPRINTF("Probing L2 cache Address=%llx, status=%u\n", mf->get_addr(), status);
@@ -420,7 +425,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
delete mf;
} else {
mf->set_reply();
- mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
m_L2_icnt_queue->push(mf);
}
m_icnt_L2_queue->pop();
@@ -431,7 +436,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
} else if ( status != RESERVATION_FAIL ) {
if(mf->is_write() && (m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE || m_config->m_L2_config.m_write_alloc_policy == LAZY_FETCH_ON_READ) && !was_writeallocate_sent(events)) {
mf->set_reply();
- mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
m_L2_icnt_queue->push(mf);
}
// L2 cache accepted request
@@ -444,7 +449,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
}
} else {
// L2 is disabled or non-texture access to texture-only L2
- mf->set_status(IN_PARTITION_L2_TO_DRAM_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_PARTITION_L2_TO_DRAM_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
m_L2_dram_queue->push(mf);
m_icnt_L2_queue->pop();
}
@@ -455,7 +460,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle )
mem_fetch* mf = m_rop.front().req;
m_rop.pop();
m_icnt_L2_queue->push(mf);
- mf->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
}
}
@@ -635,6 +640,7 @@ std::vector<mem_fetch*> memory_sub_partition::breakdown_request_to_sector_reques
mf->get_sid(),
mf->get_tpc(),
mf->get_mem_config(),
+ m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle,
mf);
result.push_back(n_mf);
@@ -664,13 +670,13 @@ void memory_sub_partition::push( mem_fetch* m_req, unsigned long long cycle )
m_request_tracker.insert(req);
if( req->istexture() ) {
m_icnt_L2_queue->push(req);
- req->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ req->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
} else {
rop_delay_t r;
r.req = req;
r.ready_cycle = cycle + m_config->rop_latency;
m_rop.push(r);
- req->set_status(IN_PARTITION_ROP_DELAY,gpu_sim_cycle+gpu_tot_sim_cycle);
+ req->set_status(IN_PARTITION_ROP_DELAY,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
}
}
}
diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h
index 18c0a8b..c8a213c 100644
--- a/src/gpgpu-sim/l2cache.h
+++ b/src/gpgpu-sim/l2cache.h
@@ -42,12 +42,12 @@ public:
{
m_memory_config = config;
}
- virtual mem_fetch * alloc(const class warp_inst_t &inst, const mem_access_t &access) const
+ virtual mem_fetch * alloc(const class warp_inst_t &inst, const mem_access_t &access, unsigned long long cycle) const
{
abort();
return NULL;
}
- virtual mem_fetch * alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr) const;
+ virtual mem_fetch * alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle) const;
private:
const memory_config *m_memory_config;
};
@@ -58,7 +58,7 @@ private:
class memory_partition_unit
{
public:
- memory_partition_unit( unsigned partition_id, const 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, class gpgpu_sim* gpu );
~memory_partition_unit();
bool busy() const;
@@ -93,6 +93,8 @@ public:
unsigned get_mpid() const { return m_id; }
+ class gpgpu_sim* get_mgpu() const { return m_gpu; }
+
private:
unsigned m_id;
@@ -140,12 +142,14 @@ private:
class mem_fetch* req;
};
std::list<dram_delay_t> m_dram_latency_queue;
+
+ class gpgpu_sim* m_gpu;
};
class memory_sub_partition
{
public:
- memory_sub_partition( unsigned sub_partition_id, const struct memory_config *config, class memory_stats_t *stats );
+ memory_sub_partition( unsigned sub_partition_id, const struct memory_config *config, class memory_stats_t *stats, class gpgpu_sim* gpu );
~memory_sub_partition();
unsigned get_id() const { return m_id; }
@@ -192,6 +196,7 @@ private:
const struct memory_config *m_config;
class l2_cache *m_L2cache;
class L2interface *m_L2interface;
+ class gpgpu_sim* m_gpu;
partition_mf_allocator *m_mf_allocator;
// model delay of ROP units with a fixed latency
diff --git a/src/gpgpu-sim/l2cache_trace.h b/src/gpgpu-sim/l2cache_trace.h
index 2235cdc..d2dd948 100644
--- a/src/gpgpu-sim/l2cache_trace.h
+++ b/src/gpgpu-sim/l2cache_trace.h
@@ -42,7 +42,7 @@
#define MEMPART_DPRINTF(...) do {\
if (MEMPART_DTRACE(MEMORY_PARTITION_UNIT)) {\
printf( MEMPART_PRINT_STR,\
- gpu_sim_cycle + gpu_tot_sim_cycle,\
+ m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle,\
Trace::trace_streams_str[Trace::MEMORY_PARTITION_UNIT],\
get_mpid() );\
printf(__VA_ARGS__);\
@@ -52,7 +52,7 @@
#define MEM_SUBPART_DPRINTF(...) do {\
if (MEM_SUBPART_DTRACE(MEMORY_PARTITION_UNIT)) {\
printf( MEM_SUBPART_PRINT_STR,\
- gpu_sim_cycle + gpu_tot_sim_cycle,\
+ m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle,\
Trace::trace_streams_str[Trace::MEMORY_SUBPARTITION_UNIT],\
m_id );\
printf(__VA_ARGS__);\
diff --git a/src/gpgpu-sim/local_interconnect.cc b/src/gpgpu-sim/local_interconnect.cc
new file mode 100644
index 0000000..66d6648
--- /dev/null
+++ b/src/gpgpu-sim/local_interconnect.cc
@@ -0,0 +1,301 @@
+// Copyright (c) 2019, Mahmoud Khairy
+// Purdue University
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+// Neither the name of The University of British Columbia nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <cmath>
+#include <utility>
+#include <algorithm>
+
+#include "local_interconnect.h"
+#include "mem_fetch.h"
+
+xbar_router::xbar_router(unsigned router_id, enum Interconnect_type m_type, unsigned n_shader, unsigned n_mem, unsigned m_in_buffer_limit, unsigned m_out_buffer_limit)
+{
+ m_id=router_id;
+ router_type=m_type;
+ _n_mem = n_mem;
+ _n_shader = n_shader;
+ total_nodes = n_shader+n_mem;
+ in_buffers.resize(total_nodes);
+ out_buffers.resize(total_nodes);
+ next_node=0;
+ in_buffer_limit = m_in_buffer_limit;
+ out_buffer_limit = m_out_buffer_limit;
+ if(m_type == REQ_NET) {
+ active_in_buffers=n_shader;
+ active_out_buffers=n_mem;
+ }
+ else if(m_type == REPLY_NET) {
+ active_in_buffers=n_mem;
+ active_out_buffers=n_shader;
+ }
+
+ cycles = 0;
+ conflicts= 0;
+ out_buffer_full=0;
+ in_buffer_full=0;
+ out_buffer_util=0;
+ in_buffer_util=0;
+ packets_num=0;
+}
+
+
+xbar_router::~xbar_router()
+{
+
+}
+
+void xbar_router::Push(unsigned input_deviceID, unsigned output_deviceID, void* data, unsigned int size)
+{
+ assert(input_deviceID < total_nodes);
+ in_buffers[input_deviceID].push(Packet(data, output_deviceID));
+ packets_num++;
+}
+
+void* xbar_router::Pop(unsigned ouput_deviceID)
+{
+ assert(ouput_deviceID < total_nodes);
+ void* data = NULL;
+
+ if(!out_buffers[ouput_deviceID].empty()) {
+ data = out_buffers[ouput_deviceID].front().data;
+ out_buffers[ouput_deviceID].pop();
+ }
+
+ return data;
+}
+
+
+bool xbar_router::Has_Buffer_In(unsigned input_deviceID, unsigned size, bool update_counter){
+
+ assert(input_deviceID < total_nodes);
+
+ bool has_buffer = (in_buffers[input_deviceID].size() + size <= in_buffer_limit);
+ if(update_counter && !has_buffer)
+ in_buffer_full++;
+
+ return has_buffer;
+
+}
+
+bool xbar_router::Has_Buffer_Out(unsigned output_deviceID, unsigned size){
+ return (out_buffers[output_deviceID].size() + size <= out_buffer_limit);
+}
+
+void xbar_router::Advance() {
+ cycles++;
+
+ vector<bool> issued(total_nodes, false);
+
+ for(unsigned i=0; i<total_nodes; ++i){
+ unsigned node_id = (i+next_node)%total_nodes;
+
+ if(!in_buffers[node_id].empty()) {
+ Packet _packet = in_buffers[node_id].front();
+ //ensure that the outbuffer has space and not issued before in this cycle
+ if(Has_Buffer_Out(_packet.output_deviceID, 1)){
+ if(!issued[_packet.output_deviceID]) {
+ out_buffers[_packet.output_deviceID].push(_packet);
+ in_buffers[node_id].pop();
+ issued[_packet.output_deviceID]=true;
+ }
+ else
+ conflicts++;
+ }
+ else
+ out_buffer_full++;
+ }
+ }
+
+ next_node = (++next_node % total_nodes);
+
+ //collect some stats about buffer util
+ for(unsigned i=0; i<total_nodes; ++i){
+ in_buffer_util+=in_buffers[i].size();
+ out_buffer_util+=out_buffers[i].size();
+ }
+}
+
+bool xbar_router::Busy() const {
+
+ for(unsigned i=0; i<total_nodes; ++i){
+ if(!in_buffers[i].empty())
+ return true;
+
+ if(!out_buffers[i].empty())
+ return true;
+ }
+ return false;
+}
+
+
+////////////////////////////////////////////////////
+/////////////LocalInterconnect/////////////////////
+
+//assume all the packets are one flit
+#define LOCAL_INCT_FLIT_SIZE 40
+
+LocalInterconnect* LocalInterconnect::New(const struct inct_config& m_localinct_config)
+{
+
+ LocalInterconnect* icnt_interface = new LocalInterconnect(m_localinct_config);
+
+ return icnt_interface;
+}
+
+LocalInterconnect::LocalInterconnect(const struct inct_config& m_localinct_config): m_inct_config(m_localinct_config){
+ n_shader=0;
+ n_mem=0;
+ n_subnets = m_localinct_config.subnets;
+}
+
+LocalInterconnect::~LocalInterconnect(){
+ for (int i=0; i<m_inct_config.subnets; ++i) {
+ delete net[i];
+ }
+}
+
+void LocalInterconnect::CreateInterconnect(unsigned m_n_shader, unsigned m_n_mem){
+ n_shader = m_n_shader;
+ n_mem = m_n_mem;
+
+ net.resize(n_subnets);
+ for (unsigned i = 0; i < n_subnets; ++i) {
+ net[i] = new xbar_router( i, static_cast<Interconnect_type>(i), m_n_shader, m_n_mem, m_inct_config.in_buffer_limit, m_inct_config.out_buffer_limit );
+ }
+
+}
+
+
+void LocalInterconnect::Init() {
+ //empty
+ //there is nothing to do
+
+}
+
+void LocalInterconnect::Push(unsigned input_deviceID, unsigned output_deviceID, void* data, unsigned int size){
+
+ unsigned subnet;
+ if (n_subnets == 1) {
+ subnet = 0;
+ } else {
+ if (input_deviceID < n_shader ) {
+ subnet = 0;
+ } else {
+ subnet = 1;
+ }
+ }
+
+ // it should have free buffer
+ //assume all the packets have size of one
+ //no flits are implemented
+ assert(net[subnet]->Has_Buffer_In(input_deviceID, 1));
+
+ net[subnet]->Push(input_deviceID, output_deviceID, data, size);
+
+}
+
+void* LocalInterconnect::Pop(unsigned ouput_deviceID){
+
+ // 0-_n_shader-1 indicates reply(network 1), otherwise request(network 0)
+ int subnet = 0;
+ if (ouput_deviceID < n_shader)
+ subnet = 1;
+
+ return net[subnet]->Pop(ouput_deviceID);
+
+}
+
+void LocalInterconnect::Advance(){
+
+ for (unsigned i = 0; i < n_subnets; ++i) {
+ net[i]->Advance();
+ }
+
+}
+
+bool LocalInterconnect::Busy() const{
+
+ for (unsigned i = 0; i < n_subnets; ++i) {
+ if(net[i]->Busy())
+ return true;
+ }
+ return false;
+}
+
+bool LocalInterconnect::HasBuffer(unsigned deviceID, unsigned int size) const{
+
+ bool has_buffer = false;
+
+ if ((n_subnets>1) && deviceID >= n_shader) // deviceID is memory node
+ has_buffer = net[REPLY_NET]->Has_Buffer_In(deviceID, 1, true);
+ else
+ has_buffer = net[REQ_NET]->Has_Buffer_In(deviceID, 1, true);
+
+ return has_buffer;
+
+}
+
+void LocalInterconnect::DisplayStats() const{
+
+ cout<<"Req_Network_injected_packets_num = "<<net[REQ_NET]->packets_num<<endl;
+ cout<<"Req_Network_cycles = "<<net[REQ_NET]->cycles<<endl;
+ cout<<"Req_Network_injected_packets_per_cycle = "<<(float)(net[REQ_NET]->packets_num) / (net[REQ_NET]->cycles)<<endl;
+ cout<<"Req_Network_conflicts_per_cycle = "<<(float)(net[REQ_NET]->conflicts) / (net[REQ_NET]->cycles)<<endl;
+ cout<<"Req_Network_in_buffer_full_per_cycle = "<<(float)(net[REQ_NET]->in_buffer_full) / (net[REQ_NET]->cycles)<<endl;
+ cout<<"Req_Network_in_buffer_avg_util = "<<((float)(net[REQ_NET]->in_buffer_util) / (net[REQ_NET]->cycles) / net[REQ_NET]->active_in_buffers)<<endl;
+ cout<<"Req_Network_out_buffer_full_per_cycle = "<<(float)(net[REQ_NET]->out_buffer_full) / (net[REQ_NET]->cycles)<<endl;
+ cout<<"Req_Network_out_buffer_avg_util = "<<((float)(net[REQ_NET]->out_buffer_util) / (net[REQ_NET]->cycles) / net[REQ_NET]->active_out_buffers)<<endl;
+
+ cout<<endl;
+ cout<<"Reply_Network_injected_packets_num = "<<net[REPLY_NET]->packets_num<<endl;
+ cout<<"Reply_Network_cycles = "<<net[REPLY_NET]->cycles<<endl;
+ cout<<"Reply_Network_injected_packets_per_cycle = "<<(float)(net[REPLY_NET]->packets_num) / (net[REPLY_NET]->cycles)<<endl;
+ cout<<"Reply_Network_conflicts_per_cycle = "<<(float)(net[REPLY_NET]->conflicts) / (net[REPLY_NET]->cycles)<<endl;
+ cout<<"Reply_Network_in_buffer_full_per_cycle = "<<(float)(net[REPLY_NET]->in_buffer_full) / (net[REPLY_NET]->cycles)<<endl;
+ cout<<"Reply_Network_in_buffer_avg_util = "<<((float)(net[REPLY_NET]->in_buffer_util) / (net[REPLY_NET]->cycles) / net[REPLY_NET]->active_in_buffers)<<endl;
+ cout<<"Reply_Network_out_buffer_full_per_cycle = "<<(float)(net[REPLY_NET]->out_buffer_full) / (net[REPLY_NET]->cycles)<<endl;
+ cout<<"Reply_Network_out_buffer_avg_util= "<<((float)(net[REPLY_NET]->out_buffer_util) / (net[REPLY_NET]->cycles) / net[REPLY_NET]->active_out_buffers)<<endl;
+
+}
+
+void LocalInterconnect::DisplayOverallStats() const{
+
+}
+
+unsigned LocalInterconnect::GetFlitSize() const{
+ return LOCAL_INCT_FLIT_SIZE;
+}
+
+void LocalInterconnect::DisplayState(FILE* fp) const{
+
+ fprintf(fp, "GPGPU-Sim uArch: ICNT:Display State: Under implementation\n");
+}
+
diff --git a/src/gpgpu-sim/local_interconnect.h b/src/gpgpu-sim/local_interconnect.h
new file mode 100644
index 0000000..502c80d
--- /dev/null
+++ b/src/gpgpu-sim/local_interconnect.h
@@ -0,0 +1,127 @@
+// Copyright (c) 2019, Mahmoud Khairy
+// Purdue University
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+// Neither the name of The University of British Columbia nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef _LOCAL_INTERCONNECT_HPP_
+#define _LOCAL_INTERCONNECT_HPP_
+
+#include <vector>
+#include <queue>
+#include <iostream>
+#include <map>
+using namespace std;
+
+
+struct inct_config
+{
+
+ //config for local interconnect
+ unsigned in_buffer_limit;
+ unsigned out_buffer_limit;
+ unsigned subnets;
+};
+
+enum Interconnect_type {
+ REQ_NET=0,
+ REPLY_NET=1
+};
+class xbar_router {
+
+public:
+ xbar_router(unsigned router_id, enum Interconnect_type m_type, unsigned n_shader, unsigned n_mem, unsigned m_in_buffer_limit, unsigned m_out_buffer_limit);
+ ~xbar_router();
+ void Push(unsigned input_deviceID, unsigned output_deviceID, void* data, unsigned int size);
+ void* Pop(unsigned ouput_deviceID);
+ void Advance();
+ bool Busy() const;
+ bool Has_Buffer_In(unsigned input_deviceID, unsigned size, bool update_counter=false);
+ bool Has_Buffer_Out(unsigned output_deviceID, unsigned size);
+
+ //some stats
+ unsigned long long cycles;
+ unsigned long long conflicts;
+ unsigned long long out_buffer_full;
+ unsigned long long out_buffer_util;
+ unsigned long long in_buffer_full;
+ unsigned long long in_buffer_util;
+ unsigned long long packets_num;
+
+private:
+ struct Packet{
+ Packet(void* m_data, unsigned m_output_deviceID) {
+ data = m_data;
+ output_deviceID = m_output_deviceID;
+ }
+ void* data;
+ unsigned output_deviceID;
+ };
+ vector<queue<Packet> > in_buffers;
+ vector<queue<Packet> > out_buffers;
+ unsigned _n_shader, _n_mem, total_nodes;
+ unsigned in_buffer_limit, out_buffer_limit;
+ unsigned next_node;
+ unsigned m_id;
+ enum Interconnect_type router_type;
+ unsigned active_in_buffers,active_out_buffers;
+
+ friend class LocalInterconnect;
+
+};
+
+class LocalInterconnect {
+public:
+ LocalInterconnect(const struct inct_config& m_localinct_config);
+ ~LocalInterconnect();
+ static LocalInterconnect* New(const struct inct_config& m_inct_config);
+ void CreateInterconnect(unsigned n_shader, unsigned n_mem);
+
+ //node side functions
+ void Init();
+ void Push(unsigned input_deviceID, unsigned output_deviceID, void* data, unsigned int size);
+ void* Pop(unsigned ouput_deviceID);
+ void Advance();
+ bool Busy() const;
+ bool HasBuffer(unsigned deviceID, unsigned int size) const;
+ void DisplayStats() const;
+ void DisplayOverallStats() const;
+ unsigned GetFlitSize() const;
+
+ void DisplayState(FILE* fp) const;
+
+
+protected:
+
+ const inct_config& m_inct_config;
+
+ unsigned n_shader, n_mem;
+ unsigned n_subnets;
+ vector<xbar_router *> net;
+
+};
+
+#endif
+
+
diff --git a/src/gpgpu-sim/mem_fetch.cc b/src/gpgpu-sim/mem_fetch.cc
index a260a35..c9b0484 100644
--- a/src/gpgpu-sim/mem_fetch.cc
+++ b/src/gpgpu-sim/mem_fetch.cc
@@ -40,6 +40,7 @@ mem_fetch::mem_fetch( const mem_access_t &access,
unsigned sid,
unsigned tpc,
const struct memory_config *config,
+ unsigned long long cycle,
mem_fetch *m_original_mf,
mem_fetch *m_original_wr_mf)
@@ -58,10 +59,10 @@ mem_fetch::mem_fetch( const mem_access_t &access,
config->m_address_mapping.addrdec_tlx(access.get_addr(),&m_raw_addr);
m_partition_addr = config->m_address_mapping.partition_address(access.get_addr());
m_type = m_access.is_write()?WRITE_REQUEST:READ_REQUEST;
- m_timestamp = gpu_sim_cycle + gpu_tot_sim_cycle;
+ m_timestamp = cycle;
m_timestamp2 = 0;
m_status = MEM_FETCH_INITIALIZED;
- m_status_change = gpu_sim_cycle + gpu_tot_sim_cycle;
+ m_status_change = cycle;
m_mem_config = config;
icnt_flit_size = config->icnt_flit_size;
original_mf = m_original_mf;
diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h
index e5efffd..4eb3a52 100644
--- a/src/gpgpu-sim/mem_fetch.h
+++ b/src/gpgpu-sim/mem_fetch.h
@@ -56,6 +56,7 @@ public:
unsigned sid,
unsigned tpc,
const struct memory_config *config,
+ unsigned long long cycle,
mem_fetch *original_mf = NULL,
mem_fetch *original_wr_mf = NULL);
~mem_fetch();
diff --git a/src/gpgpu-sim/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc
index c5452b9..c7d20d1 100644
--- a/src/gpgpu-sim/mem_latency_stat.cc
+++ b/src/gpgpu-sim/mem_latency_stat.cc
@@ -42,7 +42,7 @@
#include <stdlib.h>
#include <stdio.h>
-memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_config *shader_config, const struct memory_config *mem_config )
+memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_config *shader_config, const struct memory_config *mem_config, const class gpgpu_sim* gpu )
{
assert( mem_config->m_valid );
assert( shader_config->m_valid );
@@ -67,6 +67,7 @@ memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_conf
m_n_shader=n_shader;
m_memory_config=mem_config;
+ m_gpu=gpu;
total_n_access=0;
total_n_reads=0;
total_n_writes=0;
@@ -141,7 +142,7 @@ memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_conf
unsigned memory_stats_t::memlatstat_done(mem_fetch *mf )
{
unsigned mf_latency;
- mf_latency = (gpu_sim_cycle+gpu_tot_sim_cycle) - mf->get_timestamp();
+ mf_latency = (m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle) - mf->get_timestamp();
mf_num_lat_pw++;
mf_tot_lat_pw += mf_latency;
unsigned idx = LOGB2(mf_latency);
@@ -161,7 +162,7 @@ void memory_stats_t::memlatstat_read_done(mem_fetch *mf)
if (mf_latency > mf_max_lat_table[mf->get_tlx_addr().chip][mf->get_tlx_addr().bk])
mf_max_lat_table[mf->get_tlx_addr().chip][mf->get_tlx_addr().bk] = mf_latency;
unsigned icnt2sh_latency;
- icnt2sh_latency = (gpu_tot_sim_cycle+gpu_sim_cycle) - mf->get_return_timestamp();
+ icnt2sh_latency = (m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle) - mf->get_return_timestamp();
tot_icnt2sh_latency += icnt2sh_latency;
icnt2sh_lat_table[LOGB2(icnt2sh_latency)]++;
if (icnt2sh_latency > max_icnt2sh_latency)
@@ -195,7 +196,7 @@ void memory_stats_t::memlatstat_icnt2mem_pop(mem_fetch *mf)
{
if (m_memory_config->gpgpu_memlatency_stat) {
unsigned icnt2mem_latency;
- icnt2mem_latency = (gpu_tot_sim_cycle+gpu_sim_cycle) - mf->get_timestamp();
+ icnt2mem_latency = (m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle) - mf->get_timestamp();
tot_icnt2mem_latency += icnt2mem_latency;
icnt2mem_lat_table[LOGB2(icnt2mem_latency)]++;
if (icnt2mem_latency > max_icnt2mem_latency)
@@ -366,7 +367,7 @@ void memory_stats_t::memlatstat_print( unsigned n_mem, unsigned gpu_mem_n_bk )
m = 0;
printf("\n");
}
- printf("total reads: %d\n", k);
+ printf("total dram reads = %d\n", k);
if (min_bank_accesses)
printf("bank skew: %d/%d = %4.2f\n", max_bank_accesses, min_bank_accesses, (float)max_bank_accesses/min_bank_accesses);
else
@@ -404,7 +405,7 @@ void memory_stats_t::memlatstat_print( unsigned n_mem, unsigned gpu_mem_n_bk )
m = 0;
printf("\n");
}
- printf("total reads: %d\n", k);
+ printf("total dram writes = %d\n", k);
if (min_bank_accesses)
printf("bank skew: %d/%d = %4.2f\n", max_bank_accesses, min_bank_accesses, (float)max_bank_accesses/min_bank_accesses);
else
diff --git a/src/gpgpu-sim/mem_latency_stat.h b/src/gpgpu-sim/mem_latency_stat.h
index 5b89202..b86740d 100644
--- a/src/gpgpu-sim/mem_latency_stat.h
+++ b/src/gpgpu-sim/mem_latency_stat.h
@@ -36,7 +36,8 @@ class memory_stats_t {
public:
memory_stats_t( unsigned n_shader,
const struct shader_core_config *shader_config,
- const struct memory_config *mem_config );
+ const struct memory_config *mem_config,
+ const class gpgpu_sim* gpu);
unsigned memlatstat_done( class mem_fetch *mf );
void memlatstat_read_done( class mem_fetch *mf );
@@ -51,6 +52,7 @@ public:
const struct shader_core_config *m_shader_config;
const struct memory_config *m_memory_config;
+ const class gpgpu_sim* m_gpu;
unsigned max_mrq_latency;
unsigned max_dq_latency;
diff --git a/src/gpgpu-sim/scoreboard.cc b/src/gpgpu-sim/scoreboard.cc
index ebec891..80f95c6 100644
--- a/src/gpgpu-sim/scoreboard.cc
+++ b/src/gpgpu-sim/scoreboard.cc
@@ -32,13 +32,15 @@
//Constructor
-Scoreboard::Scoreboard( unsigned sid, unsigned n_warps )
+Scoreboard::Scoreboard( unsigned sid, unsigned n_warps, class gpgpu_t* gpu )
: longopregs()
{
m_sid = sid;
//Initialize size of table
reg_table.resize(n_warps);
longopregs.resize(n_warps);
+
+ m_gpu = gpu;
}
// Print scoreboard contents
diff --git a/src/gpgpu-sim/scoreboard.h b/src/gpgpu-sim/scoreboard.h
index 4a76ea3..a4baa19 100644
--- a/src/gpgpu-sim/scoreboard.h
+++ b/src/gpgpu-sim/scoreboard.h
@@ -38,7 +38,7 @@
class Scoreboard {
public:
- Scoreboard( unsigned sid, unsigned n_warps );
+ Scoreboard( unsigned sid, unsigned n_warps, class gpgpu_t* gpu );
void reserveRegisters(const warp_inst_t *inst);
void releaseRegisters(const warp_inst_t *inst);
@@ -59,6 +59,8 @@ private:
std::vector< std::set<unsigned> > reg_table;
//Register that depend on a long operation (global, local or tex memory)
std::vector< std::set<unsigned> > longopregs;
+
+ class gpgpu_t* m_gpu;
};
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 3db988b..69b619a 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -133,7 +133,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
m_L1I = new read_only_cache( name,m_config->m_L1I_config,m_sid,get_shader_instruction_cache_id(),m_icnt,IN_L1I_MISS_QUEUE);
m_warp.resize(m_config->max_warps_per_shader, shd_warp_t(this, warp_size));
- m_scoreboard = new Scoreboard(m_sid, m_config->max_warps_per_shader);
+ m_scoreboard = new Scoreboard(m_sid, m_config->max_warps_per_shader, gpu);
//scedulers
//must currently occur after all inputs have been initialized.
@@ -767,7 +767,7 @@ void shader_core_ctx::fetch()
m_inst_fetch_buffer = ifetch_buffer_t(m_warp[mf->get_wid()].get_pc(), mf->get_access_size(), mf->get_wid());
assert( m_warp[mf->get_wid()].get_pc() == (mf->get_addr()-PROGRAM_MEM_START)); // Verify that we got the instruction we were expecting.
m_inst_fetch_buffer.m_valid = true;
- m_warp[mf->get_wid()].set_last_fetch(gpu_sim_cycle);
+ m_warp[mf->get_wid()].set_last_fetch(m_gpu->gpu_sim_cycle);
delete mf;
}
else {
@@ -815,17 +815,19 @@ void shader_core_ctx::fetch()
warp_id,
m_sid,
m_tpc,
- m_memory_config );
+ m_memory_config,
+ m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle
+ );
std::list<cache_event> events;
- enum cache_request_status status = m_L1I->access( (new_addr_type)ppc, mf, gpu_sim_cycle+gpu_tot_sim_cycle,events);
+ enum cache_request_status status = m_L1I->access( (new_addr_type)ppc, mf, m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle,events);
if( status == MISS ) {
m_last_warp_fetched=warp_id;
m_warp[warp_id].set_imiss_pending();
- m_warp[warp_id].set_last_fetch(gpu_sim_cycle);
+ m_warp[warp_id].set_last_fetch(m_gpu->gpu_sim_cycle);
} else if( status == HIT ) {
m_last_warp_fetched=warp_id;
m_inst_fetch_buffer = ifetch_buffer_t(pc,nbytes,warp_id);
- m_warp[warp_id].set_last_fetch(gpu_sim_cycle);
+ m_warp[warp_id].set_last_fetch(m_gpu->gpu_sim_cycle);
delete mf;
} else {
m_last_warp_fetched=warp_id;
@@ -859,7 +861,7 @@ void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t*
m_warp[warp_id].ibuffer_free();
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, m_warp[warp_id].get_dynamic_warp_id(), sch_id ); // dynamic instruction information
+ (*pipe_reg)->issue( active_mask, warp_id, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, m_warp[warp_id].get_dynamic_warp_id(), sch_id ); // dynamic instruction information
m_stats->shader_cycle_distro[2+(*pipe_reg)->active_count()]++;
func_exec_inst( **pipe_reg );
if( next_inst->op == BARRIER_OP ){
@@ -1514,7 +1516,7 @@ void shader_core_ctx::warp_inst_complete(const warp_inst_t &inst)
m_stats->m_num_sim_winsn[m_sid]++;
m_gpu->gpu_sim_insn += inst.active_count();
- inst.completed(gpu_tot_sim_cycle + gpu_sim_cycle);
+ inst.completed(m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle);
}
void shader_core_ctx::writeback()
@@ -1552,9 +1554,9 @@ void shader_core_ctx::writeback()
m_warp[warp_id].dec_inst_in_pipeline();
warp_inst_complete(*pipe_reg);
m_gpu->gpu_sim_insn_last_update_sid = m_sid;
- m_gpu->gpu_sim_insn_last_update = gpu_sim_cycle;
- m_last_inst_gpu_sim_cycle = gpu_sim_cycle;
- m_last_inst_gpu_tot_sim_cycle = gpu_tot_sim_cycle;
+ m_gpu->gpu_sim_insn_last_update = m_gpu->gpu_sim_cycle;
+ m_last_inst_gpu_sim_cycle = m_gpu->gpu_sim_cycle;
+ m_last_inst_gpu_tot_sim_cycle = m_gpu->gpu_tot_sim_cycle;
pipe_reg->clear();
preg = m_pipeline_reg[EX_WB].get_ready();
pipe_reg = (preg==NULL)? NULL:*preg;
@@ -1633,9 +1635,9 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue( cache_t *cache, war
return DATA_PORT_STALL;
//const mem_access_t &access = inst.accessq_back();
- mem_fetch *mf = m_mf_allocator->alloc(inst,inst.accessq_back());
+ mem_fetch *mf = m_mf_allocator->alloc(inst,inst.accessq_back(),m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
std::list<cache_event> events;
- enum cache_request_status status = cache->access(mf->get_addr(),mf,gpu_sim_cycle+gpu_tot_sim_cycle,events);
+ enum cache_request_status status = cache->access(mf->get_addr(),mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle,events);
return process_cache_access( cache, mf->get_addr(), inst, events, mf, status );
}
@@ -1645,7 +1647,7 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue_l1cache( l1_cache *c
if( inst.accessq_empty() )
return result;
- mem_fetch *mf = m_mf_allocator->alloc(inst,inst.accessq_back());
+ mem_fetch *mf = m_mf_allocator->alloc(inst,inst.accessq_back(),m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
if(m_config->m_L1D_config.l1_latency > 0)
{
@@ -1675,7 +1677,7 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue_l1cache( l1_cache *c
else
{
std::list<cache_event> events;
- enum cache_request_status status = cache->access(mf->get_addr(),mf,gpu_sim_cycle+gpu_tot_sim_cycle,events);
+ enum cache_request_status status = cache->access(mf->get_addr(),mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle,events);
return process_cache_access( cache, mf->get_addr(), inst, events, mf, status );
}
}
@@ -1687,7 +1689,7 @@ void ldst_unit::L1_latency_queue_cycle()
{
mem_fetch* mf_next = l1_latency_queue[0];
std::list<cache_event> events;
- enum cache_request_status status = m_L1D->access(mf_next->get_addr(),mf_next,gpu_sim_cycle+gpu_tot_sim_cycle,events);
+ enum cache_request_status status = m_L1D->access(mf_next->get_addr(),mf_next,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle,events);
bool write_sent = was_write_sent(events);
bool read_sent = was_read_sent(events);
@@ -1804,7 +1806,7 @@ bool ldst_unit::memory_cycle( warp_inst_t &inst, mem_stage_stall_type &stall_rea
if( m_icnt->full(size, inst.is_store() || inst.isatomic()) ) {
stall_cond = ICNT_RC_FAIL;
} else {
- mem_fetch *mf = m_mf_allocator->alloc(inst,access);
+ mem_fetch *mf = m_mf_allocator->alloc(inst,access,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
m_icnt->push(mf);
inst.accessq_pop_back();
//inst.clear_active( access.get_warp_mask() );
@@ -1840,7 +1842,7 @@ bool ldst_unit::response_buffer_full() const
void ldst_unit::fill( mem_fetch *mf )
{
- mf->set_status(IN_SHADER_LDST_RESPONSE_FIFO,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_SHADER_LDST_RESPONSE_FIFO,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
m_response_fifo.push_back(mf);
}
@@ -1893,6 +1895,17 @@ void tensor_core::issue( register_set& source_reg )
pipelined_simd_unit::issue(source_reg);
}
+unsigned pipelined_simd_unit::get_active_lanes_in_pipeline(){
+ active_mask_t active_lanes;
+ active_lanes.reset();
+ if(m_core->get_gpu()->get_config().g_power_simulation_enabled){
+ for( unsigned stage=0; (stage+1)<m_pipeline_depth; stage++ ){
+ if( !m_pipeline_reg[stage]->empty() )
+ active_lanes|=m_pipeline_reg[stage]->get_active_mask();
+ }
+ }
+ return active_lanes.count();
+}
void ldst_unit::active_lanes_in_pipeline(){
unsigned active_count=pipelined_simd_unit::get_active_lanes_in_pipeline();
@@ -1946,13 +1959,13 @@ sp_unit::sp_unit( register_set* result_port, const shader_core_config *config,sh
}
dp_unit::dp_unit( register_set* result_port, const shader_core_config *config,shader_core_ctx *core)
- : pipelined_simd_unit(result_port,config,config->max_sfu_latency,core)
+ : pipelined_simd_unit(result_port,config,config->max_dp_latency,core)
{
m_name = "DP ";
}
int_unit::int_unit( register_set* result_port, const shader_core_config *config,shader_core_ctx *core)
- : pipelined_simd_unit(result_port,config,config->max_sp_latency,core)
+ : pipelined_simd_unit(result_port,config,config->max_int_latency,core)
{
m_name = "INT ";
}
@@ -1993,19 +2006,25 @@ pipelined_simd_unit::pipelined_simd_unit( register_set* result_port, const shade
for( unsigned i=0; i < m_pipeline_depth; i++ )
m_pipeline_reg[i] = new warp_inst_t( config );
m_core=core;
+ active_insts_in_pipeline=0;
}
void pipelined_simd_unit::cycle()
{
if( !m_pipeline_reg[0]->empty() ){
m_result_port->move_in(m_pipeline_reg[0]);
+ assert(active_insts_in_pipeline > 0);
+ active_insts_in_pipeline--;
+ }
+ if(active_insts_in_pipeline){
+ for( unsigned stage=0; (stage+1)<m_pipeline_depth; stage++ )
+ move_warp(m_pipeline_reg[stage], m_pipeline_reg[stage+1]);
}
- for( unsigned stage=0; (stage+1)<m_pipeline_depth; stage++ )
- move_warp(m_pipeline_reg[stage], m_pipeline_reg[stage+1]);
if( !m_dispatch_reg->empty() ) {
if( !m_dispatch_reg->dispatch_delay()){
int start_stage = m_dispatch_reg->latency - m_dispatch_reg->initiation_interval;
move_warp(m_pipeline_reg[start_stage],m_dispatch_reg);
+ active_insts_in_pipeline++;
}
}
occupied >>=1;
@@ -2098,7 +2117,8 @@ ldst_unit::ldst_unit( mem_fetch_interface *icnt,
get_shader_normal_cache_id(),
m_icnt,
m_mf_allocator,
- IN_L1D_MISS_QUEUE );
+ IN_L1D_MISS_QUEUE,
+ core->get_gpu());
if(m_config->m_L1D_config.l1_latency > 0)
{
@@ -2185,8 +2205,8 @@ void ldst_unit::writeback()
m_core->warp_inst_complete(m_next_wb);
}
m_next_wb.clear();
- m_last_inst_gpu_sim_cycle = gpu_sim_cycle;
- m_last_inst_gpu_tot_sim_cycle = gpu_tot_sim_cycle;
+ m_last_inst_gpu_sim_cycle = m_core->get_gpu()->gpu_sim_cycle;
+ m_last_inst_gpu_tot_sim_cycle = m_core->get_gpu()->gpu_tot_sim_cycle;
}
}
@@ -2294,13 +2314,13 @@ void ldst_unit::cycle()
mem_fetch *mf = m_response_fifo.front();
if (mf->get_access_type() == TEXTURE_ACC_R) {
if (m_L1T->fill_port_free()) {
- m_L1T->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle);
+ m_L1T->fill(mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
m_response_fifo.pop_front();
}
} else if (mf->get_access_type() == CONST_ACC_R) {
if (m_L1C->fill_port_free()) {
- mf->set_status(IN_SHADER_FETCHED,gpu_sim_cycle+gpu_tot_sim_cycle);
- m_L1C->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_SHADER_FETCHED,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
+ m_L1C->fill(mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
m_response_fifo.pop_front();
}
} else {
@@ -2320,13 +2340,13 @@ void ldst_unit::cycle()
}
if( bypassL1D ) {
if ( m_next_global == NULL ) {
- mf->set_status(IN_SHADER_FETCHED,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_SHADER_FETCHED,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
m_response_fifo.pop_front();
m_next_global = mf;
}
} else {
if (m_L1D->fill_port_free()) {
- m_L1D->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle);
+ m_L1D->fill(mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle);
m_response_fifo.pop_front();
}
}
@@ -2415,7 +2435,7 @@ void shader_core_ctx::register_cta_thread_exit( unsigned cta_num, kernel_info_t
shader_CTA_count_unlog(m_sid, 1);
SHADER_DPRINTF(LIVENESS, "GPGPU-Sim uArch: Finished CTA #%d (%lld,%lld), %u CTAs running\n",
- cta_num, gpu_sim_cycle, gpu_tot_sim_cycle, m_n_active_cta);
+ cta_num, m_gpu->gpu_sim_cycle, m_gpu->gpu_tot_sim_cycle, m_n_active_cta);
if( m_n_active_cta == 0 ) {
SHADER_DPRINTF(LIVENESS, "GPGPU-Sim uArch: Empty (last released kernel %u \'%s\').\n",
@@ -2525,13 +2545,13 @@ void gpgpu_sim::shader_print_cache_stats( FILE *fout ) const{
m_cluster[i]->get_L1I_sub_stats(css);
total_css += css;
}
- fprintf(fout, "\tL1I_total_cache_accesses = %u\n", total_css.accesses);
- fprintf(fout, "\tL1I_total_cache_misses = %u\n", total_css.misses);
+ fprintf(fout, "\tL1I_total_cache_accesses = %llu\n", total_css.accesses);
+ fprintf(fout, "\tL1I_total_cache_misses = %llu\n", total_css.misses);
if(total_css.accesses > 0){
fprintf(fout, "\tL1I_total_cache_miss_rate = %.4lf\n", (double)total_css.misses / (double)total_css.accesses);
}
- fprintf(fout, "\tL1I_total_cache_pending_hits = %u\n", total_css.pending_hits);
- fprintf(fout, "\tL1I_total_cache_reservation_fails = %u\n", total_css.res_fails);
+ fprintf(fout, "\tL1I_total_cache_pending_hits = %llu\n", total_css.pending_hits);
+ fprintf(fout, "\tL1I_total_cache_reservation_fails = %llu\n", total_css.res_fails);
}
// L1D
@@ -2542,18 +2562,18 @@ void gpgpu_sim::shader_print_cache_stats( FILE *fout ) const{
for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++){
m_cluster[i]->get_L1D_sub_stats(css);
- fprintf( stdout, "\tL1D_cache_core[%d]: Access = %d, Miss = %d, Miss_rate = %.3lf, Pending_hits = %u, Reservation_fails = %u\n",
+ fprintf( stdout, "\tL1D_cache_core[%d]: Access = %llu, Miss = %llu, Miss_rate = %.3lf, Pending_hits = %llu, Reservation_fails = %llu\n",
i, css.accesses, css.misses, (double)css.misses / (double)css.accesses, css.pending_hits, css.res_fails);
total_css += css;
}
- fprintf(fout, "\tL1D_total_cache_accesses = %u\n", total_css.accesses);
- fprintf(fout, "\tL1D_total_cache_misses = %u\n", total_css.misses);
+ fprintf(fout, "\tL1D_total_cache_accesses = %llu\n", total_css.accesses);
+ fprintf(fout, "\tL1D_total_cache_misses = %llu\n", total_css.misses);
if(total_css.accesses > 0){
fprintf(fout, "\tL1D_total_cache_miss_rate = %.4lf\n", (double)total_css.misses / (double)total_css.accesses);
}
- fprintf(fout, "\tL1D_total_cache_pending_hits = %u\n", total_css.pending_hits);
- fprintf(fout, "\tL1D_total_cache_reservation_fails = %u\n", total_css.res_fails);
+ fprintf(fout, "\tL1D_total_cache_pending_hits = %llu\n", total_css.pending_hits);
+ fprintf(fout, "\tL1D_total_cache_reservation_fails = %llu\n", total_css.res_fails);
total_css.print_port_stats(fout, "\tL1D_cache");
}
@@ -2566,13 +2586,13 @@ void gpgpu_sim::shader_print_cache_stats( FILE *fout ) const{
m_cluster[i]->get_L1C_sub_stats(css);
total_css += css;
}
- fprintf(fout, "\tL1C_total_cache_accesses = %u\n", total_css.accesses);
- fprintf(fout, "\tL1C_total_cache_misses = %u\n", total_css.misses);
+ fprintf(fout, "\tL1C_total_cache_accesses = %llu\n", total_css.accesses);
+ fprintf(fout, "\tL1C_total_cache_misses = %llu\n", total_css.misses);
if(total_css.accesses > 0){
fprintf(fout, "\tL1C_total_cache_miss_rate = %.4lf\n", (double)total_css.misses / (double)total_css.accesses);
}
- fprintf(fout, "\tL1C_total_cache_pending_hits = %u\n", total_css.pending_hits);
- fprintf(fout, "\tL1C_total_cache_reservation_fails = %u\n", total_css.res_fails);
+ fprintf(fout, "\tL1C_total_cache_pending_hits = %llu\n", total_css.pending_hits);
+ fprintf(fout, "\tL1C_total_cache_reservation_fails = %llu\n", total_css.res_fails);
}
// L1T
@@ -2584,13 +2604,13 @@ void gpgpu_sim::shader_print_cache_stats( FILE *fout ) const{
m_cluster[i]->get_L1T_sub_stats(css);
total_css += css;
}
- fprintf(fout, "\tL1T_total_cache_accesses = %u\n", total_css.accesses);
- fprintf(fout, "\tL1T_total_cache_misses = %u\n", total_css.misses);
+ fprintf(fout, "\tL1T_total_cache_accesses = %llu\n", total_css.accesses);
+ fprintf(fout, "\tL1T_total_cache_misses = %llu\n", total_css.misses);
if(total_css.accesses > 0){
fprintf(fout, "\tL1T_total_cache_miss_rate = %.4lf\n", (double)total_css.misses / (double)total_css.accesses);
}
- fprintf(fout, "\tL1T_total_cache_pending_hits = %u\n", total_css.pending_hits);
- fprintf(fout, "\tL1T_total_cache_reservation_fails = %u\n", total_css.res_fails);
+ fprintf(fout, "\tL1T_total_cache_pending_hits = %llu\n", total_css.pending_hits);
+ fprintf(fout, "\tL1T_total_cache_reservation_fails = %llu\n", total_css.res_fails);
}
}
@@ -2806,7 +2826,7 @@ void shader_core_ctx::display_pipeline(FILE *fout, int print_mem, int mask ) con
{
fprintf(fout, "=================================================\n");
fprintf(fout, "shader %u at cycle %Lu+%Lu (%u threads running)\n", m_sid,
- gpu_tot_sim_cycle, gpu_sim_cycle, m_not_completed);
+ m_gpu->gpu_tot_sim_cycle, m_gpu->gpu_sim_cycle, m_not_completed);
fprintf(fout, "=================================================\n");
dump_warp_state(fout);
@@ -2949,7 +2969,7 @@ unsigned int shader_core_config::max_cta( const kernel_info_t &k ) const
abort();
}
- if(adpative_volta_cache_config && !k.volta_cache_config_set) {
+ if(adaptive_volta_cache_config && !k.volta_cache_config_set) {
//For Volta, we assign the remaining shared memory to L1 cache
//For more info, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x
unsigned total_shmed = kernel_info->smem * result;
@@ -2981,8 +3001,53 @@ unsigned int shader_core_config::max_cta( const kernel_info_t &k ) const
return result;
}
+void shader_core_config::set_pipeline_latency() {
+
+ //calculate the max latency based on the input
+
+ unsigned int_latency[5];
+ unsigned fp_latency[5];
+ unsigned dp_latency[5];
+ unsigned sfu_latency;
+ unsigned tensor_latency;
+
+ /*
+ * [0] ADD,SUB
+ * [1] MAX,Min
+ * [2] MUL
+ * [3] MAD
+ * [4] DIV
+ */
+ sscanf(opcode_latency_int, "%u,%u,%u,%u,%u",
+ &int_latency[0],&int_latency[1],&int_latency[2],
+ &int_latency[3],&int_latency[4]);
+ sscanf(opcode_latency_fp, "%u,%u,%u,%u,%u",
+ &fp_latency[0],&fp_latency[1],&fp_latency[2],
+ &fp_latency[3],&fp_latency[4]);
+ sscanf(opcode_latency_dp, "%u,%u,%u,%u,%u",
+ &dp_latency[0],&dp_latency[1],&dp_latency[2],
+ &dp_latency[3],&dp_latency[4]);
+ sscanf(opcode_latency_sfu, "%u",
+ &sfu_latency);
+ sscanf(opcode_latency_tensor, "%u",
+ &tensor_latency);
+
+ //all div operation are executed on sfu
+ //assume that the max latency are dp div or normal sfu_latency
+ max_sfu_latency = std::max(dp_latency[4],sfu_latency);
+ //assume that the max operation has the max latency
+ max_sp_latency = fp_latency[1];
+ max_int_latency = int_latency[1];
+ max_dp_latency = dp_latency[1];
+ max_tensor_core_latency = tensor_latency;
+
+}
+
void shader_core_ctx::cycle()
{
+ if(!isactive() && get_not_completed() == 0)
+ return;
+
m_stats->shader_cycles[m_sid]++;
writeback();
execute();
@@ -3159,7 +3224,7 @@ void barrier_set_t::warp_reaches_barrier(unsigned cta_id,unsigned warp_id,warp_i
cta_to_warp_t::iterator w=m_cta_to_warps.find(cta_id);
if( w == m_cta_to_warps.end() ) { // cta is active
- printf("ERROR ** cta_id %u not found in barrier set on cycle %llu+%llu...\n", cta_id, gpu_tot_sim_cycle, gpu_sim_cycle );
+ printf("ERROR ** cta_id %u not found in barrier set on cycle %llu+%llu...\n", cta_id, m_shader->get_gpu()->gpu_tot_sim_cycle, m_shader->get_gpu()->gpu_sim_cycle );
dump();
abort();
}
@@ -3332,8 +3397,8 @@ bool shader_core_ctx::fetch_unit_response_buffer_full() const
void shader_core_ctx::accept_fetch_response( mem_fetch *mf )
{
- mf->set_status(IN_SHADER_FETCHED,gpu_sim_cycle+gpu_tot_sim_cycle);
- m_L1I->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_SHADER_FETCHED,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_L1I->fill(mf,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
}
bool shader_core_ctx::ldst_unit_response_buffer_full() const
@@ -3895,7 +3960,7 @@ void simt_core_cluster::icnt_inject_request_packet(class mem_fetch *mf)
}
m_stats->m_outgoing_traffic_stats->record_traffic(mf, packet_size);
unsigned destination = mf->get_sub_partition_id();
- mf->set_status(IN_ICNT_TO_MEM,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_ICNT_TO_MEM,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
if (!mf->get_is_write() && !mf->isatomic())
::icnt_push(m_cluster_id, m_config->mem2device(destination), (void*)mf, mf->get_ctrl_size() );
else
@@ -3934,7 +3999,7 @@ void simt_core_cluster::icnt_cycle()
// - For write-ack, the packet only has control metadata
unsigned int packet_size = (mf->get_is_write())? mf->get_ctrl_size() : mf->size();
m_stats->m_incoming_traffic_stats->record_traffic(mf, packet_size);
- mf->set_status(IN_CLUSTER_TO_SHADER_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
+ mf->set_status(IN_CLUSTER_TO_SHADER_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
//m_memory_stats->memlatstat_read_done(mf,m_shader_config->max_warps_per_shader);
m_response_fifo.push_back(mf);
m_stats->n_mem_to_simt[m_cluster_id] += mf->get_num_flits(false);
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index 9abd223..fde87b6 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -55,7 +55,6 @@
#include "traffic_breakdown.h"
-
#define NO_OP_FLAG 0xFF
/* READ_PACKET_SIZE:
@@ -1073,16 +1072,8 @@ public:
//modifiers
virtual void cycle();
virtual void issue( register_set& source_reg );
- virtual unsigned get_active_lanes_in_pipeline()
- {
- active_mask_t active_lanes;
- active_lanes.reset();
- for( unsigned stage=0; (stage+1)<m_pipeline_depth; stage++ ){
- if( !m_pipeline_reg[stage]->empty() )
- active_lanes|=m_pipeline_reg[stage]->get_active_mask();
- }
- return active_lanes.count();
- }
+ virtual unsigned get_active_lanes_in_pipeline();
+
virtual void active_lanes_in_pipeline() = 0;
/*
virtual void issue( register_set& source_reg )
@@ -1113,6 +1104,9 @@ protected:
warp_inst_t **m_pipeline_reg;
register_set *m_result_port;
class shader_core_ctx *m_core;
+
+ unsigned active_insts_in_pipeline;
+
};
class sfu : public pipelined_simd_unit
@@ -1413,10 +1407,8 @@ struct shader_core_config : public core_config
}
max_warps_per_shader = n_thread_per_shader/warp_size;
assert( !(n_thread_per_shader % warp_size) );
- max_sfu_latency = 512;
- max_sp_latency = 32;
-
- max_tensor_core_latency = 64;
+
+ set_pipeline_latency();
m_L1I_config.init(m_L1I_config.m_config_string,FuncCachePreferNone);
m_L1T_config.init(m_L1T_config.m_config_string,FuncCachePreferNone);
@@ -1432,6 +1424,7 @@ struct shader_core_config : public core_config
unsigned sid_to_cluster( unsigned sid ) const { return sid / n_simt_cores_per_cluster; }
unsigned sid_to_cid( unsigned sid ) const { return sid % n_simt_cores_per_cluster; }
unsigned cid_to_sid( unsigned cid, unsigned cluster_id ) const { return cluster_id*n_simt_cores_per_cluster + cid; }
+ void set_pipeline_latency();
// data
char *gpgpu_shader_core_pipeline_opt;
@@ -1506,7 +1499,9 @@ struct shader_core_config : public core_config
bool sub_core_model;
unsigned max_sp_latency;
+ unsigned max_int_latency;
unsigned max_sfu_latency;
+ unsigned max_dp_latency;
unsigned max_tensor_core_latency;
unsigned n_simt_cores_per_cluster;
@@ -1524,6 +1519,7 @@ struct shader_core_config : public core_config
bool gpgpu_concurrent_kernel_sm;
bool adpative_volta_cache_config;
+
};
struct shader_core_stats_pod {
@@ -1734,7 +1730,7 @@ public:
m_cluster_id = cluster_id;
m_memory_config = config;
}
- mem_fetch *alloc( new_addr_type addr, mem_access_type type, unsigned size, bool wr ) const
+ mem_fetch *alloc( new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle ) const
{
mem_access_t access( type, addr, size, wr );
mem_fetch *mf = new mem_fetch( access,
@@ -1743,11 +1739,12 @@ public:
-1,
m_core_id,
m_cluster_id,
- m_memory_config );
+ m_memory_config,
+ cycle);
return mf;
}
- mem_fetch *alloc( const warp_inst_t &inst, const mem_access_t &access ) const
+ mem_fetch *alloc( const warp_inst_t &inst, const mem_access_t &access, unsigned long long cycle ) const
{
warp_inst_t inst_copy = inst;
mem_fetch *mf = new mem_fetch(access,
@@ -1756,7 +1753,8 @@ public:
inst.warp_id(),
m_core_id,
m_cluster_id,
- m_memory_config);
+ m_memory_config,
+ cycle);
return mf;
}
diff --git a/src/gpgpu-sim/shader_trace.h b/src/gpgpu-sim/shader_trace.h
index de3e059..ac4e894 100644
--- a/src/gpgpu-sim/shader_trace.h
+++ b/src/gpgpu-sim/shader_trace.h
@@ -44,7 +44,7 @@
#define SHADER_DPRINTF(x, ...) do {\
if (SHADER_DTRACE(x)) {\
printf( SHADER_PRINT_STR,\
- gpu_sim_cycle + gpu_tot_sim_cycle,\
+ m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle,\
Trace::trace_streams_str[Trace::x],\
get_sid() );\
printf(__VA_ARGS__);\
@@ -56,7 +56,7 @@
#define SCHED_DPRINTF(...) do {\
if (SHADER_DTRACE(WARP_SCHEDULER)) {\
printf( SCHED_PRINT_STR,\
- gpu_sim_cycle + gpu_tot_sim_cycle,\
+ m_shader->get_gpu()->gpu_sim_cycle + m_shader->get_gpu()->gpu_tot_sim_cycle,\
Trace::trace_streams_str[Trace::WARP_SCHEDULER],\
get_sid(),\
m_id );\
diff --git a/src/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc
index 270bace..777f9bb 100644
--- a/src/gpgpusim_entrypoint.cc
+++ b/src/gpgpusim_entrypoint.cc
@@ -222,10 +222,12 @@ gpgpu_sim *gpgpu_ptx_sim_init_perf()
read_parser_environment_variables();
option_parser_t opp = option_parser_create();
- icnt_reg_options(opp);
- g_the_gpu_config.reg_options(opp); // register GPU microrachitecture options
ptx_reg_options(opp);
ptx_opcocde_latency_options(opp);
+
+ icnt_reg_options(opp);
+ g_the_gpu_config.reg_options(opp); // register GPU microrachitecture options
+
option_parser_cmdline(opp, sg_argc, sg_argv); // parse configuration options
fprintf(stdout, "GPGPU-Sim: Configuration options:\n\n");
option_parser_print(opp, stdout);
@@ -273,7 +275,7 @@ void print_simulation_time()
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 (cycle/sec)\n", (unsigned)(gpu_tot_sim_cycle / difference) );
+ printf("gpgpu_simulation_rate = %u (cycle/sec)\n", (unsigned)(g_the_gpu->gpu_tot_sim_cycle / difference) );
fflush(stdout);
}
diff --git a/src/stream_manager.cc b/src/stream_manager.cc
index 6cd62a2..e07f4e4 100644
--- a/src/stream_manager.cc
+++ b/src/stream_manager.cc
@@ -190,7 +190,7 @@ bool stream_operation::do_operation( gpgpu_sim *gpu )
case stream_event: {
printf("event update\n");
time_t wallclock = time((time_t *)NULL);
- m_event->update( gpu_tot_sim_cycle, wallclock );
+ m_event->update( gpu->gpu_tot_sim_cycle, wallclock );
m_stream->record_next_done();
}
break;
diff --git a/src/trace.h b/src/trace.h
index a79b4a0..0b96dcf 100644
--- a/src/trace.h
+++ b/src/trace.h
@@ -31,9 +31,6 @@
#ifndef __TRACE_H__
#define __TRACE_H__
-extern unsigned long long gpu_sim_cycle;
-extern unsigned long long gpu_tot_sim_cycle;
-
namespace Trace {
#define TS_TUP_BEGIN(X) enum X {
@@ -63,17 +60,26 @@ namespace Trace {
#define DPRINTF(x, ...) do {\
if (DTRACE(x)) {\
printf( SIM_PRINT_STR,\
- gpu_sim_cycle + gpu_tot_sim_cycle,\
+ m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle,\
Trace::trace_streams_str[Trace::x] );\
printf(__VA_ARGS__);\
}\
} while (0)
+#define DPRINTFG(x, ...) do {\
+ if (DTRACE(x)) {\
+ printf( SIM_PRINT_STR,\
+ gpu_sim_cycle + gpu_tot_sim_cycle,\
+ Trace::trace_streams_str[Trace::x] );\
+ printf(__VA_ARGS__);\
+ }\
+} while (0)
#else
#define DTRACE(x) (false)
#define DPRINTF(x, ...) do {} while (0)
+#define DPRINTFG(x, ...) do {} while (0)
#endif