summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Aamodt <[email protected]>2010-10-12 00:46:24 -0800
committerTor Aamodt <[email protected]>2010-10-12 00:46:24 -0800
commitb0cf792926caf74b393a14e36de676c7afd68164 (patch)
treeddcdd107959a1cea591a503e1e73080f14fbfb0f
parentb3ce70a797756285ea9b15b3e5cf515d8b6a2b63 (diff)
1. adding simt_core_cluster, which models a TPC or (for fermi) GPC...
this gives us a place to stick caches shared among shader cores but on the shader side of the interconnect... maybe move the clock boundary code here? after integrating booksim 2 code? 2. added a pending write table to ldst_unit rather than scoreboard ... rationale is that ld/st unit needs to process register writes once it is done it can notify scoreboard once. 3. re-enabled shared memory delay (use pipeline within ldst_unit) 4. re-enabling operand collector writeback for all instruction types 5. disable MSHRs in this change list passing CUDA 3.1 regression next? texture cache, then redo mshrs? [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 7845]
-rw-r--r--configs/QuadroFX5800/gpgpusim.config4
-rw-r--r--src/abstract_hardware_model.cc1
-rw-r--r--src/abstract_hardware_model.h31
-rw-r--r--src/cuda-sim/instructions.cc2
-rw-r--r--src/debug.cc2
-rw-r--r--src/gpgpu-sim/gpu-sim.cc279
-rw-r--r--src/gpgpu-sim/gpu-sim.h43
-rw-r--r--src/gpgpu-sim/icnt_wrapper.h6
-rw-r--r--src/gpgpu-sim/l2cache.cc27
-rw-r--r--src/gpgpu-sim/mem_fetch.cc71
-rw-r--r--src/gpgpu-sim/mem_fetch.h89
-rw-r--r--src/gpgpu-sim/scoreboard.cc44
-rw-r--r--src/gpgpu-sim/scoreboard.h13
-rw-r--r--src/gpgpu-sim/shader.cc530
-rw-r--r--src/gpgpu-sim/shader.h164
-rw-r--r--src/gpgpu-sim/stats.h1
-rw-r--r--src/gpgpu-sim/visualizer.cc6
-rw-r--r--src/gpgpusim_entrypoint.cc4
-rw-r--r--src/intersim/interconnect_interface.cpp36
-rw-r--r--src/intersim/interconnect_interface.h2
20 files changed, 800 insertions, 555 deletions
diff --git a/configs/QuadroFX5800/gpgpusim.config b/configs/QuadroFX5800/gpgpusim.config
index e5e29bc..97be091 100644
--- a/configs/QuadroFX5800/gpgpusim.config
+++ b/configs/QuadroFX5800/gpgpusim.config
@@ -4,7 +4,8 @@
-gpgpu_ptx_force_max_capability 11
# high level architecture configuration
--gpgpu_n_shader 30
+-gpgpu_n_clusters 10
+-gpgpu_n_cores_per_cluster 3
-gpgpu_n_mem 8
-gpgpu_clock_domains 325.0:650.0:650.0:800.0
@@ -31,7 +32,6 @@
# interconnection
-network_mode 1
-inter_config_file icnt_config_quadro_islip.txt
--gpu_concentration 3
# dram model config
-gpgpu_dram_scheduler 1
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index 619b9b7..7b67df9 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -3,6 +3,7 @@
#include <algorithm>
unsigned mem_access_t::next_access_uid = 0;
+unsigned warp_inst_t::sm_next_uid = 0;
void move_warp( warp_inst_t *&dst, warp_inst_t *&src )
{
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index 41fe025..b94aa48 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -480,6 +480,13 @@ struct shader_core_config
unsigned null_bank_func(address_type, unsigned) const { return 1; }
unsigned shmem_bank_func(address_type addr, unsigned) const;
unsigned dcache_bank_func(address_type add, unsigned line_size) const;
+
+ unsigned n_simt_cores_per_cluster;
+ unsigned n_simt_clusters;
+ unsigned n_simt_ejection_buffer_size;
+ unsigned ldst_unit_response_queue_size;
+
+ unsigned mem2device(unsigned memid) const { return memid + n_simt_clusters; }
};
typedef unsigned (shader_core_config::*bank_func_t)(address_type add, unsigned line_size) const;
@@ -488,14 +495,22 @@ typedef address_type (*tag_func_t)(address_type add, unsigned line_size);
class warp_inst_t: public inst_t {
public:
// constructors
+ warp_inst_t()
+ {
+ m_uid=0;
+ m_empty=true;
+ m_config=NULL;
+ }
warp_inst_t( const struct shader_core_config *config )
{
+ m_uid=0;
assert(config->warp_size<=MAX_WARP_SIZE);
m_config=config;
m_empty=true;
m_isatomic=false;
m_per_scalar_thread_valid=false;
m_mem_accesses_created=false;
+ m_cache_hit=false;
}
// modifiers
@@ -519,9 +534,11 @@ public:
if( mask & (1<<i) )
warp_active_mask.set(i);
}
+ m_uid = ++sm_next_uid;
m_warp_id = warp_id;
issue_cycle = cycle;
cycles = initiation_interval;
+ m_cache_hit=false;
m_empty=false;
}
void set_addr( unsigned n, new_addr_type addr )
@@ -564,6 +581,14 @@ public:
}
}
}
+ void clear_active( std::vector<unsigned> &inactive )
+ {
+ std::vector<unsigned>::iterator i;
+ for(i=inactive.begin(); i!=inactive.end();i++) {
+ unsigned t=*i;
+ warp_active_mask.reset(t);
+ }
+ }
void set_not_active( unsigned lane_id )
{
warp_active_mask.reset(lane_id);
@@ -618,7 +643,9 @@ public:
void print( FILE *fout ) const;
protected:
+ unsigned m_uid;
bool m_empty;
+ bool m_cache_hit;
unsigned long long issue_cycle;
unsigned cycles; // used for implementing initiation interval delay
bool m_isatomic;
@@ -628,17 +655,17 @@ protected:
struct per_thread_info {
per_thread_info() {
- cache_miss=false;
memreqaddr=0;
}
dram_callback_t callback;
new_addr_type memreqaddr; // effective address
- bool cache_miss;
};
bool m_per_scalar_thread_valid;
std::vector<per_thread_info> m_per_scalar_thread;
bool m_mem_accesses_created;
std::vector<mem_access_t> m_accessq;
+
+ static unsigned sm_next_uid;
};
void move_warp( warp_inst_t *&dst, warp_inst_t *&src );
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc
index e67c779..1ae1919 100644
--- a/src/cuda-sim/instructions.cc
+++ b/src/cuda-sim/instructions.cc
@@ -1082,8 +1082,6 @@ void atom_callback( const inst_t* inst, ptx_thread_info* thread )
// Write operation result into global memory
// (i.e. copy src1_data to dst)
thread->get_global_memory()->write(src1_data.u32,size/8,&op_result.s64,thread,pI);
- gpgpu_sim *gpu = thread->get_gpu();
- gpu->decrement_atomic_count(thread->get_hw_sid(),thread->get_hw_wid());
}
// atom_impl will now result in a callback being called in mem_ctrl_pop (gpu-sim.c)
diff --git a/src/debug.cc b/src/debug.cc
index 236870c..49cae96 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -84,6 +84,7 @@ void gpgpu_sim::gpgpu_debug()
done = false;
}
} else {
+ /*
for( unsigned sid=0; sid < m_n_shader; sid++ ) {
unsigned hw_thread_id = -1;
abort();
@@ -101,6 +102,7 @@ void gpgpu_sim::gpgpu_debug()
printf( "\n" );
}
}
+ */
}
}
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index 9b71aec..4e434c4 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -163,7 +163,6 @@ char * gpgpu_clock_domains;
/* GPU uArch parameters */
unsigned int gpu_n_mem_per_ctrlr;
-int gpu_n_tpc;
char *gpgpu_dwf_hw_opt;
unsigned int more_thread = 1;
@@ -232,11 +231,19 @@ void gpgpu_sim::reg_options(option_parser_t opp)
option_parser_register(opp, "-gpgpu_shader_cta", OPT_UINT32, &m_shader_config->max_cta_per_core,
"Maximum number of concurrent CTAs in shader (default 8)",
"8");
-
- option_parser_register(opp, "-gpgpu_n_shader", OPT_UINT32, &m_n_shader,
- "number of shaders in gpu",
+ option_parser_register(opp, "-gpgpu_n_clusters", OPT_UINT32, &m_shader_config->n_simt_clusters,
+ "number of processing clusters",
+ "10");
+ option_parser_register(opp, "-gpgpu_n_cores_per_cluster", OPT_UINT32, &m_shader_config->n_simt_cores_per_cluster,
+ "number of simd cores per cluster",
+ "3");
+ option_parser_register(opp, "-gpgpu_n_cluster_ejection_buffer_size", OPT_UINT32, &m_shader_config->n_simt_ejection_buffer_size,
+ "number of packets in ejection buffer",
"8");
- option_parser_register(opp, "-gpgpu_n_mem", OPT_UINT32, &m_n_mem,
+ option_parser_register(opp, "-gpgpu_n_ldst_response_buffer_size", OPT_UINT32, &m_shader_config->ldst_unit_response_queue_size,
+ "number of response packets in ld/st unit ejection buffer",
+ "2");
+ option_parser_register(opp, "-gpgpu_n_mem", OPT_UINT32, &m_memory_config->m_n_mem,
"number of memory modules (e.g. memory controllers) in gpu",
"8");
option_parser_register(opp, "-gpgpu_n_mem_per_ctrlr", OPT_UINT32, &gpu_n_mem_per_ctrlr,
@@ -340,9 +347,6 @@ void gpgpu_sim::reg_options(option_parser_t opp)
option_parser_register(opp, "-gpgpu_cflog_interval", OPT_INT32, &gpgpu_cflog_interval,
"Interval between each snapshot in control flow logger",
"0");
- option_parser_register(opp, "-gpu_concentration", OPT_INT32, &gpu_concentration,
- "Number of shader cores per interconnection port (default = 1)",
- "1");
option_parser_register(opp, "-gpgpu_local_mem_map", OPT_BOOL, &m_shader_config->gpgpu_local_mem_map,
"Mapping from local memory space address to simulated GPU physical address space (default = enabled)",
"1");
@@ -396,13 +400,6 @@ void gpgpu_sim::reg_options(option_parser_t opp)
/////////////////////////////////////////////////////////////////////////////
-int mem2device(int memid)
-{
- return memid + gpu_n_tpc;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
void increment_x_then_y_then_z( dim3 &i, const dim3 &bound)
{
i.x++;
@@ -433,18 +430,15 @@ void gpgpu_sim::launch( kernel_info_t &kinfo )
m_running_kernels.push_back(kinfo);
}
-void gpgpu_sim::next_grid( unsigned &grid_num, class function_info *&entry )
+void gpgpu_sim::next_grid()
{
- grid_num = ++m_grid_num;
m_the_kernel = m_running_kernels.front();
m_running_kernels.pop_front();
- entry = m_the_kernel.entry();
}
gpgpu_sim::gpgpu_sim()
{
m_options_set=false;
- m_grid_num=0;
m_shader_config = (shader_core_config*)calloc(1,sizeof(shader_core_config));
m_shader_stats = (shader_core_stats*)calloc(1,sizeof(shader_core_stats));
m_memory_config = (memory_config*)calloc(1,sizeof(memory_config));
@@ -474,7 +468,7 @@ void gpgpu_sim::init_gpu()
assert( !(m_shader_config->n_thread_per_shader % m_shader_config->warp_size) );
m_shader_stats->num_warps_issuable = (int*) calloc(m_shader_config->max_warps_per_shader+1, sizeof(int));
- m_shader_stats->num_warps_issuable_pershader = (int*) calloc(m_n_shader, sizeof(int));
+ m_shader_stats->num_warps_issuable_pershader = (int*) calloc(m_shader_config->n_simt_clusters*m_shader_config->n_simt_cores_per_cluster, sizeof(int));
m_shader_stats->shader_cycle_distro = (unsigned int*) calloc(m_shader_config->warp_size + 3, sizeof(unsigned int));
if(ntok != 2) {
@@ -487,32 +481,27 @@ void gpgpu_sim::init_gpu()
m_shader_config->pdom_sched_type = m_pdom_sched_type;
m_shader_config->gpgpu_n_shmem_bank=16;
- m_sc = (shader_core_ctx**) calloc(m_n_shader, sizeof(shader_core_ctx*));
- for (unsigned i=0;i<m_n_shader;i++) {
- m_sc[i] = (shader_core_ctx*)calloc(sizeof(shader_core_ctx),1);
- m_sc[i] = new (m_sc[i]) shader_core_ctx(this,"sh",i,i/gpu_concentration,m_shader_config,m_shader_stats);
- }
-
- ptx_file_line_stats_create_exposed_latency_tracker(m_n_shader);
+ m_cluster = new simt_core_cluster*[m_shader_config->n_simt_clusters];
+ for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++)
+ m_cluster[i] = new simt_core_cluster(this,i,m_shader_config,m_shader_stats);
- assert(m_n_shader % gpu_concentration == 0);
- gpu_n_tpc = m_n_shader / gpu_concentration;
+ ptx_file_line_stats_create_exposed_latency_tracker(num_shader());
- addrdec_setnchip(m_n_mem);
- m_memory_partition_unit = new memory_partition_unit*[m_n_mem];
- for (unsigned i=0;i<m_n_mem;i++)
+ addrdec_setnchip(m_memory_config->m_n_mem);
+ m_memory_partition_unit = new memory_partition_unit*[m_memory_config->m_n_mem];
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++)
m_memory_partition_unit[i] = new memory_partition_unit(i, m_memory_config);
- m_memory_stats = new memory_stats_t(m_n_mem,m_n_shader,m_shader_config,m_memory_config);
- for (unsigned i=0;i<m_n_mem;i++)
+ m_memory_stats = new memory_stats_t(m_memory_config->m_n_mem,num_shader(),m_shader_config,m_memory_config);
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++)
m_memory_partition_unit[i]->set_stats(m_memory_stats);
- concurrent_row_access = (unsigned int**) calloc(m_n_mem, sizeof(unsigned int*));
- num_activates = (unsigned int**) calloc(m_n_mem, sizeof(unsigned int*));
- row_access = (unsigned int**) calloc(m_n_mem, sizeof(unsigned int*));
- max_conc_access2samerow = (unsigned int**) calloc(m_n_mem, sizeof(unsigned int*));
- max_servicetime2samerow = (unsigned int**) calloc(m_n_mem, sizeof(unsigned int*));
+ concurrent_row_access = (unsigned int**) calloc(m_memory_config->m_n_mem, sizeof(unsigned int*));
+ num_activates = (unsigned int**) calloc(m_memory_config->m_n_mem, sizeof(unsigned int*));
+ row_access = (unsigned int**) calloc(m_memory_config->m_n_mem, sizeof(unsigned int*));
+ max_conc_access2samerow = (unsigned int**) calloc(m_memory_config->m_n_mem, sizeof(unsigned int*));
+ max_servicetime2samerow = (unsigned int**) calloc(m_memory_config->m_n_mem, sizeof(unsigned int*));
- for (unsigned i=0;i<m_n_mem ;i++ ) {
+ for (unsigned i=0;i<m_memory_config->m_n_mem ;i++ ) {
concurrent_row_access[i] = (unsigned int*) calloc(m_memory_config->gpu_mem_n_bk, sizeof(unsigned int));
row_access[i] = (unsigned int*) calloc(m_memory_config->gpu_mem_n_bk, sizeof(unsigned int));
num_activates[i] = (unsigned int*) calloc(m_memory_config->gpu_mem_n_bk, sizeof(unsigned int));
@@ -520,11 +509,9 @@ void gpgpu_sim::init_gpu()
max_servicetime2samerow[i] = (unsigned int*) calloc(m_memory_config->gpu_mem_n_bk, sizeof(unsigned int));
}
- m_memory_stats = new memory_stats_t(m_n_mem,m_n_shader,m_shader_config,m_memory_config);
+ m_memory_stats = new memory_stats_t(m_memory_config->m_n_mem,num_shader(),m_shader_config,m_memory_config);
- m_shader_stats->max_return_queue_length = (unsigned int*) calloc(m_n_shader, sizeof(unsigned int));
-
- icnt_init(gpu_n_tpc, m_n_mem,m_shader_config);
+ icnt_init(m_shader_config->n_simt_clusters, m_memory_config->m_n_mem,m_shader_config);
time_vector_create(NUM_MEM_REQ_STAT,MR_2SH_ICNT_INJECTED);
fprintf(stdout, "GPU performance model initialization complete.\n");
@@ -598,7 +585,6 @@ void gpgpu_sim::reinit_clock_domains(void)
unsigned int gpgpu_sim::run_gpu_sim()
{
// run a CUDA grid on the GPU microarchitecture simulator
- int grid_num = m_grid_num;
kernel_info_t &entry = m_the_kernel;
size_t program_size = get_kernel_code_size(entry.entry());
@@ -617,9 +603,9 @@ unsigned int gpgpu_sim::run_gpu_sim()
m_shader_stats->gpu_completed_thread = 0;
reinit_clock_domains();
- set_param_gpgpu_num_shaders(m_n_shader);
- for (unsigned i=0;i<m_n_shader;i++)
- m_sc[i]->reinit(0,m_shader_config->n_thread_per_shader,true);
+ set_param_gpgpu_num_shaders(num_shader());
+ for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++)
+ m_cluster[i]->reinit();
if (gpu_max_cta_opt != 0) {
g_total_cta_left = gpu_max_cta_opt;
} else {
@@ -640,23 +626,23 @@ unsigned int gpgpu_sim::run_gpu_sim()
}
// initialize the control-flow, memory access, memory latency logger
- create_thread_CFlogger( m_n_shader, m_shader_config->n_thread_per_shader, program_size, 0, gpgpu_cflog_interval );
- shader_CTA_count_create( m_n_shader, gpgpu_cflog_interval);
+ create_thread_CFlogger( num_shader(), m_shader_config->n_thread_per_shader, program_size, 0, gpgpu_cflog_interval );
+ shader_CTA_count_create( num_shader(), gpgpu_cflog_interval);
if (gpgpu_cflog_interval != 0) {
- insn_warp_occ_create( m_n_shader, m_shader_config->warp_size, program_size );
- shader_warp_occ_create( m_n_shader, m_shader_config->warp_size, gpgpu_cflog_interval);
- shader_mem_acc_create( m_n_shader, m_n_mem, 4, gpgpu_cflog_interval);
- shader_mem_lat_create( m_n_shader, gpgpu_cflog_interval);
- shader_cache_access_create( m_n_shader, 3, gpgpu_cflog_interval);
+ insn_warp_occ_create( num_shader(), m_shader_config->warp_size, program_size );
+ shader_warp_occ_create( num_shader(), m_shader_config->warp_size, gpgpu_cflog_interval);
+ shader_mem_acc_create( num_shader(), m_memory_config->m_n_mem, 4, gpgpu_cflog_interval);
+ shader_mem_lat_create( num_shader(), gpgpu_cflog_interval);
+ shader_cache_access_create( num_shader(), 3, gpgpu_cflog_interval);
set_spill_interval (gpgpu_cflog_interval * 40);
}
// calcaulte the max cta count and cta size for local memory address mapping
- m_shader_config->gpu_max_cta_per_shader = m_sc[0]->max_cta(entry.entry());
+ m_shader_config->gpu_max_cta_per_shader = m_cluster[0]->max_cta(entry.entry());
//gpu_max_cta_per_shader is limited by number of CTAs if not enough
- if (m_the_kernel.num_blocks() < m_shader_config->gpu_max_cta_per_shader*m_n_shader) {
- m_shader_config->gpu_max_cta_per_shader = (m_the_kernel.num_blocks() / m_n_shader);
- if (m_the_kernel.num_blocks() % m_n_shader)
+ if (m_the_kernel.num_blocks() < m_shader_config->gpu_max_cta_per_shader*num_shader()) {
+ m_shader_config->gpu_max_cta_per_shader = (m_the_kernel.num_blocks() / num_shader());
+ if (m_the_kernel.num_blocks() % num_shader())
m_shader_config->gpu_max_cta_per_shader++;
}
unsigned int gpu_cta_size = m_the_kernel.threads_per_cta();
@@ -670,10 +656,10 @@ unsigned int gpgpu_sim::run_gpu_sim()
while (not_completed || mem_busy || icnt2mem_busy) {
cycle();
not_completed = 0;
- for (unsigned i=0;i<m_n_shader;i++)
- not_completed += m_sc[i]->get_not_completed();
+ for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++)
+ not_completed += m_cluster[i]->get_not_completed();
mem_busy = 0;
- for (unsigned i=0;i<m_n_mem;i++)
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++)
mem_busy += m_memory_partition_unit[i]->busy();
icnt2mem_busy = icnt_busy();
if (gpu_max_cycle && (gpu_tot_sim_cycle + gpu_sim_cycle) >= gpu_max_cycle)
@@ -683,14 +669,13 @@ unsigned int gpgpu_sim::run_gpu_sim()
if (gpu_deadlock_detect && gpu_deadlock)
break;
}
- m_memory_stats->memlatstat_lat_pw(m_n_shader,m_shader_config->n_thread_per_shader,m_shader_config->warp_size);
+ m_memory_stats->memlatstat_lat_pw(num_shader(),m_shader_config->n_thread_per_shader,m_shader_config->warp_size);
gpu_tot_sim_cycle += gpu_sim_cycle;
gpu_tot_sim_insn += gpu_sim_insn;
gpu_tot_completed_thread += m_shader_stats->gpu_completed_thread;
ptx_file_line_stats_write_file();
- printf("stats for grid: %d\n", grid_num);
gpu_print_stat();
if (g_network_mode) {
interconnect_stats();
@@ -699,10 +684,10 @@ unsigned int gpgpu_sim::run_gpu_sim()
printf("----------------------------END-of-Interconnect-DETAILS-------------------------" );
}
if (m_memory_config->gpgpu_memlatency_stat & GPU_MEMLATSTAT_QUEUELOGS ) {
- for (unsigned i=0;i<m_n_mem;i++)
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++)
m_memory_partition_unit[i]->queue_latency_log_dump(stdout);
if (m_memory_config->gpgpu_cache_dl2_opt) {
- for(unsigned i=0; i<m_n_mem; i++)
+ for(unsigned i=0; i<m_memory_config->m_n_mem; i++)
m_memory_partition_unit[i]->L2c_log(DUMPLOG);
L2c_latency_log_dump();
}
@@ -715,8 +700,8 @@ unsigned int gpgpu_sim::run_gpu_sim()
(unsigned) gpu_sim_insn_last_update, (unsigned) (gpu_tot_sim_cycle-gpu_sim_cycle),
(unsigned) (gpu_sim_cycle - gpu_sim_insn_last_update ));
unsigned num_cores=0;
- for (unsigned i=0;i<m_n_shader;i++) {
- unsigned not_completed = m_sc[i]->get_not_completed();
+ for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) {
+ unsigned not_completed = m_cluster[i]->get_not_completed();
if( not_completed ) {
if ( !num_cores ) {
printf("GPGPU-Sim uArch: DEADLOCK shader cores no longer committing instructions [core(# threads)]:\n" );
@@ -730,7 +715,7 @@ unsigned int gpgpu_sim::run_gpu_sim()
}
}
printf("\n");
- for (unsigned i=0;i<m_n_mem;i++) {
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++) {
bool busy = m_memory_partition_unit[i]->busy();
if( busy )
printf("GPGPU-Sim uArch DEADLOCK: memory partition %u busy\n", i );
@@ -769,12 +754,7 @@ void gpgpu_sim::gpu_print_stat() const
// performance counter that are not local to one shader
shader_print_accstats(stdout);
- m_memory_stats->memlatstat_print(m_n_mem,m_memory_config->gpu_mem_n_bk);
- printf("max return queue length = ");
- for (unsigned i=0;i<m_n_shader;i++) {
- printf("%d ", m_shader_stats->max_return_queue_length[i]);
- }
- printf("\n");
+ m_memory_stats->memlatstat_print(m_memory_config->m_n_mem,m_memory_config->gpu_mem_n_bk);
// merge misses
printf("L1 read misses = %d\n", m_shader_stats->L1_read_miss);
printf("L1 write misses = %d\n", m_shader_stats->L1_write_miss);
@@ -802,9 +782,9 @@ void gpgpu_sim::gpu_print_stat() const
//printf("\n");
if (m_memory_config->gpgpu_cache_dl2_opt) {
- m_memory_stats->L2c_print_stat( m_n_mem );
+ m_memory_stats->L2c_print_stat( m_memory_config->m_n_mem );
}
- for (unsigned i=0;i<m_n_mem;i++)
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++)
m_memory_partition_unit[i]->print(stdout);
/*
unsigned a,m;
@@ -940,94 +920,6 @@ void gpgpu_sim::mem_instruction_stats(warp_inst_t &inst)
}
}
-////////////////////////////////////////////////////////////////////////////////////
-// Wrapper function for shader cores' memory system:
-////////////////////////////////////////////////////////////////////////////////////
-
-// Check the memory system for buffer availability
-unsigned char gpgpu_sim::fq_has_buffer(unsigned long long int addr, int bsize, bool write, int sid )
-{
- //requests should be single always now
- int rsize = bsize;
- //maintain similar functionality with fq_push, if its a read, bsize is the load size, not the request's size
- if (!write) {
- rsize = READ_PACKET_SIZE;
- }
- return check_icnt_has_buffer(addr, rsize, sid);
-}
-
-unsigned char gpgpu_sim::check_icnt_has_buffer(unsigned long long int addr, int bsize, int sid )
-{
- int tpc_id = sid / gpu_concentration;
- return icnt_has_buffer(tpc_id, bsize);
-}
-
-int gpgpu_sim::issue_mf_from_fq(mem_fetch *mf)
-{
- // stats
- if (mf->get_is_write()) m_shader_stats->made_write_mfs++;
- else m_shader_stats->made_read_mfs++;
- switch (mf->get_mem_acc()) {
- case CONST_ACC_R: m_shader_stats->gpgpu_n_mem_const++; break;
- case TEXTURE_ACC_R: m_shader_stats->gpgpu_n_mem_texture++; break;
- case GLOBAL_ACC_R: m_shader_stats->gpgpu_n_mem_read_global++; break;
- case GLOBAL_ACC_W: m_shader_stats->gpgpu_n_mem_write_global++; break;
- case LOCAL_ACC_R: m_shader_stats->gpgpu_n_mem_read_local++; break;
- case LOCAL_ACC_W: m_shader_stats->gpgpu_n_mem_write_local++; break;
- case INST_ACC_R: m_shader_stats->gpgpu_n_mem_read_inst++; break;
- default: assert(0);
- }
-
- unsigned destination = mf->get_tlx_addr().chip;
- unsigned tpc_id = mf->get_tpc();
- mf->set_status(IN_ICNT2MEM,MR_ICNT_PUSHED,gpu_sim_cycle+gpu_tot_sim_cycle);
- if (!mf->get_is_write()) {
- mf->set_type(RD_REQ);
- icnt_push(tpc_id, mem2device(destination), (void*)mf, mf->get_ctrl_size() );
- } else {
- mf->set_type(WT_REQ);
- icnt_push(tpc_id, mem2device(destination), (void*)mf, mf->size());
- gpgpu_n_sent_writes++;
- }
- return 0;
-}
-
-void shader_core_ctx::fill_shd_L1_with_new_line(mem_fetch * mf)
-{
- // When the data arrives, it flags all the appropriate MSHR
- // entries accordingly (by checking the address in each entry )
- if ( mf->isinst() ) {
- m_L1I->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
- m_warp[mf->get_wid()].clear_imiss_pending();
- delete mf->get_mshr();
- delete mf;
- } else {
- m_ldst_unit->fill(mf);
- }
- freed_read_mfs++;
-}
-
-void shader_core_ctx::store_ack( class mem_fetch *mf )
-{
- unsigned warp_id = mf->get_wid();
- m_warp[warp_id].dec_store_req();
-}
-
-void gpgpu_sim::fq_pop(int tpc_id)
-{
- mem_fetch *mf = (mem_fetch*) icnt_pop(tpc_id);
- if (!mf)
- return;
- assert(mf->get_type() == REPLY_DATA);
- mf->set_status(IN_ICNT2SHADER,MR_2SH_FQ_POP,gpu_sim_cycle+gpu_tot_sim_cycle);
- if (mf->get_is_write()) {
- m_sc[mf->get_sid()]->store_ack(mf);
- delete mf;
- } else {
- m_memory_stats->memlatstat_read_done(mf,m_shader_config->max_warps_per_shader);
- m_sc[mf->get_sid()]->fill_shd_L1_with_new_line(mf);
- }
-}
////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1074,7 +966,7 @@ void shader_core_ctx::issue_block2core( kernel_info_t &kernel )
for (unsigned i = start_thread; i<end_thread; i++) {
m_thread[i].m_cta_id = free_cta_hw_id;
unsigned warp_id = i/m_config->warp_size;
- nthreads_in_block += ptx_sim_init_thread(kernel,&m_thread[i].m_functional_model_thread_state,m_sid,i,cta_size-(i-start_thread),m_config->n_thread_per_shader,this,free_cta_hw_id,warp_id,m_gpu);
+ nthreads_in_block += ptx_sim_init_thread(kernel,&m_thread[i].m_functional_model_thread_state,m_sid,i,cta_size-(i-start_thread),m_config->n_thread_per_shader,this,free_cta_hw_id,warp_id,m_cluster->get_gpu());
warps.set( warp_id );
}
assert( nthreads_in_block > 0 && nthreads_in_block <= m_config->n_thread_per_shader); // should be at least one, but less than max
@@ -1230,26 +1122,26 @@ void gpgpu_sim::cycle()
{
int clock_mask = next_clock_domain();
- // shader core loading (pop from ICNT into shader core) follows CORE clock
if (clock_mask & CORE ) {
- for (int i=0;i<gpu_n_tpc;i++)
- fq_pop(i);
+ // shader core loading (pop from ICNT into core) follows CORE clock
+ for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++)
+ m_cluster[i]->icnt_cycle();
}
if (clock_mask & ICNT) {
// pop from memory controller to interconnect
- for (unsigned i=0;i<m_n_mem;i++) {
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++) {
mem_fetch* mf = m_memory_partition_unit[i]->top();
if (mf) {
mf->set_status(IN_ICNT2SHADER,MR_2SH_ICNT_PUSHED,gpu_sim_cycle+gpu_tot_sim_cycle);
unsigned response_size = mf->get_is_write()?mf->get_ctrl_size():mf->size();
- if ( icnt_has_buffer( mem2device(i), response_size ) ) {
+ if ( ::icnt_has_buffer( m_shader_config->mem2device(i), response_size ) ) {
if (!mf->get_is_write())
mf->set_return_timestamp(gpu_sim_cycle+gpu_tot_sim_cycle);
else {
freed_L1write_mfs++;
gpgpu_n_processed_writes++;
}
- icnt_push( mem2device(i), mf->get_tpc(), mf, response_size );
+ ::icnt_push( m_shader_config->mem2device(i), mf->get_tpc(), mf, response_size );
m_memory_partition_unit[i]->pop();
} else {
gpu_stall_icnt2sh++;
@@ -1261,24 +1153,24 @@ void gpgpu_sim::cycle()
}
if (clock_mask & DRAM) {
- for (unsigned i=0;i<m_n_mem;i++)
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++)
m_memory_partition_unit[i]->issueCMD(); // Issue the dram command (scheduler + delay model)
}
// L2 operations follow L2 clock domain
if (clock_mask & L2) {
- for (unsigned i=0;i<m_n_mem;i++)
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++)
m_memory_partition_unit[i]->cache_cycle();
}
if (clock_mask & ICNT) {
- for (unsigned i=0;i<m_n_mem;i++) {
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++) {
if ( m_memory_partition_unit[i]->full() ) {
gpu_stall_dramfull++;
continue;
}
// move memory request from interconnect into memory partition (if memory controller not backed up)
- mem_fetch* mf = (mem_fetch*) icnt_pop( mem2device(i) );
+ mem_fetch* mf = (mem_fetch*) icnt_pop( m_shader_config->mem2device(i) );
m_memory_partition_unit[i]->push( mf, gpu_sim_cycle + gpu_tot_sim_cycle );
}
icnt_transfer();
@@ -1286,9 +1178,9 @@ void gpgpu_sim::cycle()
if (clock_mask & CORE) {
// L1 cache + shader core pipeline stages
- for (unsigned i=0;i<m_n_shader;i++) {
- if (m_sc[i]->get_not_completed() || more_thread) {
- m_sc[i]->cycle();
+ for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) {
+ if (m_cluster[i]->get_not_completed() || more_thread) {
+ m_cluster[i]->core_cycle();
}
}
if( g_single_step && ((gpu_sim_cycle+gpu_tot_sim_cycle) >= g_single_step) ) {
@@ -1298,9 +1190,9 @@ void gpgpu_sim::cycle()
if( g_interactive_debugger_enabled )
gpgpu_debug();
- for (unsigned i=0;i<m_n_shader && more_thread;i++) {
- if ( ( (m_sc[i]->get_n_active_cta()+1) <= m_sc[i]->max_cta(m_the_kernel.entry()) ) && g_total_cta_left ) {
- m_sc[i]->issue_block2core( m_the_kernel );
+ for (unsigned i=0;i<m_shader_config->n_simt_clusters && more_thread;i++) {
+ if ( ( (m_cluster[i]->get_n_active_cta()+1) <= m_cluster[i]->max_cta(m_the_kernel.entry()) ) && g_total_cta_left ) {
+ m_cluster[i]->issue_block2core( m_the_kernel );
if (!g_total_cta_left)
more_thread = 0;
assert( g_total_cta_left > -1 );
@@ -1310,9 +1202,9 @@ void gpgpu_sim::cycle()
// Flush the caches once all of threads are completed.
if (gpgpu_flush_cache) {
int all_threads_complete = 1 ;
- for (unsigned i=0;i<m_n_shader;i++) {
- if (m_sc[i]->get_not_completed() == 0)
- m_sc[i]->cache_flush();
+ for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) {
+ if (m_cluster[i]->get_not_completed() == 0)
+ m_cluster[i]->cache_flush();
else
all_threads_complete = 0 ;
}
@@ -1320,7 +1212,7 @@ void gpgpu_sim::cycle()
printf("Flushed L2 caches...\n");
if (m_memory_config->gpgpu_cache_dl2_opt) {
int dlc = 0;
- for (unsigned i=0;i<m_n_mem;i++) {
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++) {
dlc = m_memory_partition_unit[i]->flushL2();
assert (dlc == 0); // need to model actual writes to DRAM here
printf("Dirty lines flushed from L2 %d is %d\n", i, dlc );
@@ -1345,11 +1237,11 @@ void gpgpu_sim::cycle()
(unsigned)days,(unsigned)hrs,(unsigned)minutes,(unsigned)sec,
ctime(&curr_time));
fflush(stdout);
- m_memory_stats->memlatstat_lat_pw(m_n_shader,m_shader_config->n_thread_per_shader,m_shader_config->warp_size);
+ m_memory_stats->memlatstat_lat_pw(num_shader(),m_shader_config->n_thread_per_shader,m_shader_config->warp_size);
visualizer_printstat();
if (gpgpu_runtime_stat && (gpu_runtime_stat_flag != 0) ) {
if (gpu_runtime_stat_flag & GPU_RSTAT_BW_STAT) {
- for (unsigned i=0;i<m_n_mem;i++)
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++)
m_memory_partition_unit[i]->print_stat(stdout);
printf("maxmrqlatency = %d \n", m_memory_stats->max_mrq_latency);
printf("maxmflatency = %d \n", m_memory_stats->max_mf_latency);
@@ -1371,7 +1263,7 @@ void gpgpu_sim::cycle()
}
if (gpu_runtime_stat_flag & GPU_RSTAT_SCHED ) {
printf("Average Num. Warps Issuable per Shader:\n");
- for (unsigned i=0;i<m_n_shader;i++) {
+ for (unsigned i=0;i<num_shader();i++) {
printf("%2.2f ", (float) m_shader_stats->num_warps_issuable_pershader[i]/ gpu_stat_sample_freq);
m_shader_stats->num_warps_issuable_pershader[i] = 0;
}
@@ -1380,7 +1272,7 @@ void gpgpu_sim::cycle()
}
}
- for (unsigned i=0;i<m_n_mem;i++)
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++)
m_memory_stats->acc_mrq_length[i] += m_memory_partition_unit[i]->dram_que_length();
if (!(gpu_sim_cycle % 20000)) {
// deadlock detection
@@ -1417,17 +1309,17 @@ void gpgpu_sim::dump_pipeline( int mask, int s, int m ) const
printf("Dumping pipeline state...\n");
if(!mask) mask = 0xFFFFFFFF;
- for (unsigned i=0;i<m_n_shader;i++) {
+ for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) {
if(s != -1) {
i = s;
}
- if(mask&1) m_sc[i]->display_pipeline(stdout, 1, mask & 0x2E );
+ if(mask&1) m_cluster[sid_to_cluster(i)]->display_pipeline(i,stdout,1,mask & 0x2E);
if(s != -1) {
break;
}
}
if(mask&0x10000) {
- for (unsigned i=0;i<m_n_mem;i++) {
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++) {
if(m != -1) {
i=m;
}
@@ -1447,3 +1339,4 @@ void memory_partition_unit::visualizer_print( gzFile visualizer_file )
{
m_dram->visualizer_print(visualizer_file);
}
+
diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h
index 5dbdf51..51ebd58 100644
--- a/src/gpgpu-sim/gpu-sim.h
+++ b/src/gpgpu-sim/gpu-sim.h
@@ -113,6 +113,7 @@ struct memory_config {
bool gpgpu_memlatency_stat;
unsigned gpgpu_dram_buswidth;
unsigned gpgpu_dram_burst_length;
+ unsigned m_n_mem;
};
// global config
@@ -140,12 +141,10 @@ public:
void set_prop( struct cudaDeviceProp *prop );
void launch( kernel_info_t &kinfo );
- void next_grid( unsigned &grid_num, class function_info *&entry );
+ void next_grid();
unsigned run_gpu_sim();
- unsigned char fq_has_buffer(unsigned long long int addr, int bsize, bool write, int sid );
- void decrement_atomic_count( unsigned sid, unsigned wid );
void get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc );
const kernel_info_t &the_kernel() const { return m_the_kernel; }
@@ -156,10 +155,9 @@ public:
const struct cudaDeviceProp *get_prop() const;
enum divergence_support_t simd_model() const;
- unsigned num_shader() const { return m_n_shader; }
+ unsigned num_shader() const { return m_shader_config->n_simt_clusters*m_shader_config->n_simt_cores_per_cluster; }
unsigned threads_per_core() const;
void mem_instruction_stats( class warp_inst_t &inst);
- int issue_mf_from_fq(class mem_fetch *mf);
void gpu_print_stat() const;
void dump_pipeline( int mask, int s, int m ) const;
@@ -174,9 +172,7 @@ private:
void reinit_clock_domains(void);
int next_clock_domain(void);
- unsigned char check_icnt_has_buffer(unsigned long long int addr, int bsize, int sid );
void cycle();
- void fq_pop(int tpc_id);
void L2c_options(class OptionParser *opp);
void L2c_print_cache_stat() const;
void L2c_print_debug();
@@ -188,15 +184,28 @@ private:
void print_shader_cycle_distro( FILE *fout ) const;
void gpgpu_debug();
+ unsigned sid_to_cluster( unsigned sid ) const;
- // data
- class shader_core_ctx **m_sc;
+///// data /////
+
+ class simt_core_cluster **m_cluster;
class memory_partition_unit **m_memory_partition_unit;
- unsigned m_grid_num;
kernel_info_t m_the_kernel;
std::list<kernel_info_t> m_running_kernels;
+ // time of next rising edge
+ double core_time;
+ double icnt_time;
+ double dram_time;
+ double l2_time;
+
+ // debug
+ bool gpu_deadlock;
+
+ //// configuration parameters ////
+ bool m_options_set;
+
// clock domains - frequency
double core_freq;
double icnt_freq;
@@ -209,24 +218,12 @@ private:
double dram_period;
double l2_period;
- // time of next rising edge
- double core_time;
- double icnt_time;
- double dram_time;
- double l2_time;
-
- // configuration parameters
- bool m_options_set;
struct cudaDeviceProp *m_cuda_properties;
struct shader_core_config *m_shader_config;
struct memory_config *m_memory_config;
- unsigned int m_n_shader;
- unsigned int m_n_mem;
- int gpu_concentration;
int m_pdom_sched_type;
- // options
bool gpu_deadlock_detect;
int m_ptx_convert_to_ptxplus;
int m_ptx_save_converted_ptxplus;
@@ -239,8 +236,6 @@ private:
unsigned long long gpu_tot_completed_thread;
unsigned long long last_gpu_sim_insn;
- // debug
- bool gpu_deadlock;
public:
unsigned long long gpu_sim_insn;
unsigned long long gpu_tot_sim_insn;
diff --git a/src/gpgpu-sim/icnt_wrapper.h b/src/gpgpu-sim/icnt_wrapper.h
index 26e394b..ff8905d 100644
--- a/src/gpgpu-sim/icnt_wrapper.h
+++ b/src/gpgpu-sim/icnt_wrapper.h
@@ -68,9 +68,9 @@
#define ICNT_WRAPPER_H
// functional interface to the interconnect
-typedef int (*icnt_has_buffer_p)(unsigned int input, unsigned int size);
-typedef void (*icnt_push_p)(unsigned int input, unsigned int output, void* data, unsigned int size);
-typedef void* (*icnt_pop_p)(unsigned int output);
+typedef bool (*icnt_has_buffer_p)(unsigned input, unsigned int size);
+typedef void (*icnt_push_p)(unsigned input, unsigned output, void* data, unsigned int size);
+typedef void* (*icnt_pop_p)(unsigned output);
typedef void (*icnt_transfer_p)( );
typedef unsigned (*icnt_busy_p)( );
typedef void (*icnt_drain_p)( );
diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc
index 411f452..29903ea 100644
--- a/src/gpgpu-sim/l2cache.cc
+++ b/src/gpgpu-sim/l2cache.cc
@@ -525,11 +525,12 @@ bool memory_partition_unit::L2c_write_back( unsigned long long int addr, int bsi
(unsigned)-1/*sid*/,
(unsigned)-1/*tpc*/,
(unsigned)-1/*wid*/,
- NULL,true,
+ (unsigned)-1/*mshr_id*/,
+ NULL/*inst*/,
+ true/*write*/,
partial_write_mask_t(),
L2_WRBK_ACC,
- L2_WTBK_DATA,
- -1/*pc*/);
+ L2_WTBK_DATA );
made_write_mfs++;
L2todram_wbqueue->push(mf,gpu_sim_cycle);
gpgpu_n_sent_writes++;
@@ -635,7 +636,7 @@ void memory_stats_t::print( FILE *fp )
void gpgpu_sim::L2c_print_cache_stat() const
{
unsigned i, j, k;
- for (i=0,j=0,k=0;i<m_n_mem;i++)
+ for (i=0,j=0,k=0;i<m_memory_config->m_n_mem;i++)
m_memory_partition_unit[i]->L2c_print_cache_stat(k,j);
printf("L2 Cache Total Miss Rate = %0.3f\n", (float)j/k);
}
@@ -645,46 +646,46 @@ void gpgpu_sim::L2c_print_debug()
unsigned i;
printf(" ");
- for (i=0;i<m_n_mem;i++)
+ for (i=0;i<m_memory_config->m_n_mem;i++)
printf(" dram[%d]", i);
printf("\n");
printf("cbtoL2 queue length =");
- for (i=0;i<m_n_mem;i++)
+ for (i=0;i<m_memory_config->m_n_mem;i++)
printf("%8d", m_memory_partition_unit[i]->get_cbtoL2queue_length() );
printf("\n");
printf("cbtoL2 write queue length =");
- for (i=0;i<m_n_mem;i++)
+ for (i=0;i<m_memory_config->m_n_mem;i++)
printf("%8d", m_memory_partition_unit[i]->get_cbtoL2writequeue_length());
printf("\n");
printf("L2tocb queue length =");
- for (i=0;i<m_n_mem;i++) {
+ for (i=0;i<m_memory_config->m_n_mem;i++) {
printf("%8d", m_memory_partition_unit[i]->get_L2tocbqueue_length());
}
printf("\n");
printf("dramtoL2 queue length =");
- for (i=0;i<m_n_mem;i++) {
+ for (i=0;i<m_memory_config->m_n_mem;i++) {
printf("%8d", m_memory_partition_unit[i]->get_dramtoL2queue_length());
}
printf("\n");
printf("dramtoL2 write queue length =");
- for (i=0;i<m_n_mem;i++) {
+ for (i=0;i<m_memory_config->m_n_mem;i++) {
printf("%8d", m_memory_partition_unit[i]->get_dramtoL2writequeue_length());
}
printf("\n");
printf("L2todram queue length =");
- for (i=0;i<m_n_mem;i++) {
+ for (i=0;i<m_memory_config->m_n_mem;i++) {
printf("%8d", m_memory_partition_unit[i]->get_L2todramqueue_length());
}
printf("\n");
printf("L2todram writeback queue length =");
- for (i=0;i<m_n_mem;i++) {
+ for (i=0;i<m_memory_config->m_n_mem;i++) {
printf("%8d", m_memory_partition_unit[i]->get_L2todram_wbqueue_length());
}
printf("\n");
@@ -722,7 +723,7 @@ unsigned memory_partition_unit::flushL2()
void gpgpu_sim::L2c_latency_log_dump()
{
- for (unsigned i=0;i<m_n_mem;i++)
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++)
m_memory_partition_unit[i]->L2c_latency_log_dump();
}
diff --git a/src/gpgpu-sim/mem_fetch.cc b/src/gpgpu-sim/mem_fetch.cc
index 1a4af1e..50442c8 100644
--- a/src/gpgpu-sim/mem_fetch.cc
+++ b/src/gpgpu-sim/mem_fetch.cc
@@ -77,70 +77,65 @@ mem_fetch::mem_fetch( new_addr_type addr,
unsigned sid,
unsigned tpc,
unsigned wid,
- class mshr_entry * mshr,
- bool write,
+ unsigned mshr_id,
+ warp_inst_t *inst,
+ bool write,
partial_write_mask_t partial_write_mask,
enum mem_access_type mem_acc,
- enum mf_type type,
- address_type pc )
+ enum mf_type type )
{
- class mem_fetch *mf = this;
- mf->request_uid = sm_next_mf_request_uid++;
+ m_request_uid = sm_next_mf_request_uid++;
- mf->addr = addr;
- mf->nbytes_L1 = data_size;
- mf->ctrl_size = ctrl_size;
- mf->sid = sid;
- mf->wid = wid;
- mf->tpc = tpc;
- mf->mshr = mshr;
- mf->m_write = write;
- addrdec_tlx(addr,&mf->tlx);
- mf->mem_acc = mem_acc;
- mf->type = type;
- mf->pc = pc;
- mf->timestamp = gpu_sim_cycle + gpu_tot_sim_cycle;
- mf->timestamp2 = 0;
+ m_addr = addr;
+ m_data_size = data_size;
+ m_ctrl_size = ctrl_size;
+ m_sid = sid;
+ m_wid = wid;
+ m_tpc = tpc;
+ m_mshr_id = mshr_id;
+ if( inst ) m_inst = *inst;
+ m_write = write;
+ addrdec_tlx(addr,&m_raw_addr);
+ m_mem_acc = mem_acc;
+ m_type = type;
+ m_timestamp = gpu_sim_cycle + gpu_tot_sim_cycle;
+ m_timestamp2 = 0;
+
+ m_status = INITIALIZED;
}
void mem_fetch::print( FILE *fp ) const
{
- fprintf(fp," mf: uid=%6u, addr=0x%08llx, sid=%u, wid=%u, pc=0x%04x, %s, bank=%u, ",
- request_uid, addr, sid, wid, pc, (m_write?"write":"read "), tlx.bk);
- if( mshr ) mshr->print(fp);
+ fprintf(fp," mf: uid=%6u, addr=0x%08llx, sid=%u, wid=%u, mshr_id=%u, %s, bank=%u, ",
+ m_request_uid, m_addr, m_sid, m_wid, m_mshr_id, (m_write?"write":"read "), m_raw_addr.bk);
+ if( !m_inst.empty() ) m_inst.print(fp);
else fprintf(fp,"\n");
}
void mem_fetch::set_status( enum mshr_status status, enum mem_req_stat stat, unsigned long long cycle )
{
- if ( mshr ) {
- mshr->set_status(status);
- time_vector_update(request_uid,stat,cycle,type);
- }
+ m_status = status;
}
bool mem_fetch::isatomic() const
{
- if( !mshr ) return false;
- return mshr->isatomic();
+ if( m_inst.empty() ) return false;
+ return m_inst.isatomic();
}
void mem_fetch::do_atomic()
{
- mshr->do_atomic();
-}
-
-bool mem_fetch::isinst() const
-{
- return (mshr==NULL)?false:mshr->isinst();
+ m_inst.do_atomic();
}
bool mem_fetch::istexture() const
-{
- return (mshr==NULL)?false:mshr->istexture();
+{
+ if( m_inst.empty() ) return false;
+ return m_inst.space.get_type() == tex_space;
}
bool mem_fetch::isconst() const
{
- return (mshr==NULL)?false:mshr->isconst();
+ if( m_inst.empty() ) return false;
+ return m_inst.space.get_type() == const_space;
}
diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h
index 0aab2cb..31a47da 100644
--- a/src/gpgpu-sim/mem_fetch.h
+++ b/src/gpgpu-sim/mem_fetch.h
@@ -103,6 +103,7 @@ enum mshr_status {
IN_L2TOCBQUEUE_HIT,
IN_L2TOCBQUEUE_MISS,
IN_ICNT2SHADER,
+ IN_CLUSTER2SHADER,
FETCHED,
NUM_MSHR_STATUS
};
@@ -138,66 +139,72 @@ public:
unsigned sid,
unsigned tpc,
unsigned wid,
- class mshr_entry * mshr,
- bool write,
+ unsigned mshr_id,
+ warp_inst_t *inst,
+ bool write,
partial_write_mask_t partial_write_mask,
enum mem_access_type mem_acc,
- enum mf_type type,
- address_type pc );
+ enum mf_type type );
void set_status( enum mshr_status status, enum mem_req_stat stat, unsigned long long cycle );
- void set_type( enum mf_type t ) { type=t; }
+ void set_type( enum mf_type t ) { m_type=t; }
void do_atomic();
void print( FILE *fp ) const;
- const addrdec_t &get_tlx_addr() const { return tlx; }
- unsigned get_data_size() const { return nbytes_L1; }
- unsigned get_ctrl_size() const { return ctrl_size; }
- unsigned size() const { return nbytes_L1+ctrl_size; }
- new_addr_type get_addr() const { return addr; }
- class mshr_entry *get_mshr() { return mshr; }
+ const addrdec_t &get_tlx_addr() const { return m_raw_addr; }
+ unsigned get_data_size() const { return m_data_size; }
+ unsigned get_ctrl_size() const { return m_ctrl_size; }
+ unsigned size() const { return m_data_size+m_ctrl_size; }
+ new_addr_type get_addr() const { return m_addr; }
+ unsigned get_mshr() { return m_mshr_id; }
bool get_is_write() const { return m_write; }
- unsigned get_request_uid() const { return request_uid; }
- unsigned get_sid() const { return sid; }
- unsigned get_tpc() const { return tpc; }
- unsigned get_wid() const { return wid; }
- bool isinst() const;
+ unsigned get_request_uid() const { return m_request_uid; }
+ unsigned get_sid() const { return m_sid; }
+ unsigned get_tpc() const { return m_tpc; }
+ unsigned get_wid() const { return m_wid; }
bool istexture() const;
bool isconst() const;
- enum mf_type get_type() const { return type; }
+ enum mf_type get_type() const { return m_type; }
bool isatomic() const;
- void set_return_timestamp( unsigned t ) { timestamp2=t; }
- void set_icnt_receive_time( unsigned t ) { icnt_receive_time=t; }
- unsigned get_timestamp() const { return timestamp; }
- unsigned get_return_timestamp() const { return timestamp2; }
- unsigned get_icnt_receive_time() const { return icnt_receive_time; }
- enum mem_access_type get_mem_acc() const { return mem_acc; }
- address_type get_pc() const { return pc; }
+ void set_return_timestamp( unsigned t ) { m_timestamp2=t; }
+ void set_icnt_receive_time( unsigned t ) { m_icnt_receive_time=t; }
+ unsigned get_timestamp() const { return m_timestamp; }
+ unsigned get_return_timestamp() const { return m_timestamp2; }
+ unsigned get_icnt_receive_time() const { return m_icnt_receive_time; }
+ enum mem_access_type get_mem_acc() const { return m_mem_acc; }
+ address_type get_pc() const { return m_inst.empty()?-1:m_inst.pc; }
+ const warp_inst_t &get_inst() { return m_inst; }
+ enum mshr_status get_status() const { return m_status; }
private:
- // request origination
- unsigned request_uid;
- address_type pc;
- unsigned sid;
- unsigned tpc;
- unsigned wid;
- class mshr_entry* mshr;
+ // request source information
+ unsigned m_request_uid;
+ unsigned m_sid;
+ unsigned m_tpc;
+ unsigned m_wid;
+ unsigned m_mshr_id;
+
+ // where is the request now?
+ enum mshr_status m_status;
// request type, address, size, mask
bool m_write;
- enum mem_access_type mem_acc;
- enum mf_type type;
- new_addr_type addr;
- addrdec_t tlx;
- partial_write_mask_t write_mask;
- unsigned nbytes_L1;
- unsigned ctrl_size;
+ enum mem_access_type m_mem_acc;
+ enum mf_type m_type;
+ new_addr_type m_addr;
+ addrdec_t m_raw_addr;
+ partial_write_mask_t m_write_mask;
+ unsigned m_data_size; // bytes
+ unsigned m_ctrl_size;
// statistics
- unsigned timestamp; // set to gpu_sim_cycle+gpu_tot_sim_cycle at struct creation
- unsigned timestamp2; // set to gpu_sim_cycle+gpu_tot_sim_cycle when pushed onto icnt to shader; only used for reads
- unsigned icnt_receive_time; // set to gpu_sim_cycle + interconnect_latency when fixed icnt latency mode is enabled
+ unsigned m_timestamp; // set to gpu_sim_cycle+gpu_tot_sim_cycle at struct creation
+ unsigned m_timestamp2; // set to gpu_sim_cycle+gpu_tot_sim_cycle when pushed onto icnt to shader; only used for reads
+ unsigned m_icnt_receive_time; // set to gpu_sim_cycle + interconnect_latency when fixed icnt latency mode is enabled
+
+ // requesting instruction
+ warp_inst_t m_inst;
static unsigned sm_next_mf_request_uid;
};
diff --git a/src/gpgpu-sim/scoreboard.cc b/src/gpgpu-sim/scoreboard.cc
index 3484714..f3029f1 100644
--- a/src/gpgpu-sim/scoreboard.cc
+++ b/src/gpgpu-sim/scoreboard.cc
@@ -19,61 +19,47 @@ Scoreboard::Scoreboard( unsigned sid, unsigned n_warps )
}
// Print scoreboard contents
-void Scoreboard::printContents()
+void Scoreboard::printContents() const
{
printf("scoreboard contents (sid=%d): \n", m_sid);
for(unsigned i=0; i<reg_table.size(); i++) {
if(reg_table[i].size() == 0 ) continue;
- printf(" wid = %d: ", i);
- std::set<int>::iterator it;
- for ( it=reg_table[i].begin() ; it != reg_table[i].end(); it++ )
- printf("%d ", *it);
+ printf(" wid = %2d: ", i);
+ std::set<unsigned>::const_iterator it;
+ for( it=reg_table[i].begin() ; it != reg_table[i].end(); it++ )
+ printf("%u ", *it);
printf("\n");
}
}
-
-// Mark register as write-pending
void Scoreboard::reserveRegister(unsigned wid, unsigned regnum)
{
if( !(reg_table[wid].find(regnum) == reg_table[wid].end()) ){
printf("Error: trying to reserve an already reserved register (sid=%d, wid=%d, regnum=%d).", m_sid, wid, regnum);
- assert(reg_table[wid].find(regnum) == reg_table[wid].end());
+ abort();
}
-
reg_table[wid].insert(regnum);
}
-
// Unmark register as write-pending
void Scoreboard::releaseRegister(unsigned wid, unsigned regnum)
{
- if( !(reg_table[wid].find(regnum) != reg_table[wid].end()) ) {
- printf("Error: trying to release an unreserved register (sid=%d, wid=%d, regnum=%d).", m_sid, wid, regnum);
- assert(reg_table[wid].find(regnum) != reg_table[wid].end());
- }
+ if( !(reg_table[wid].find(regnum) != reg_table[wid].end()) )
+ return;
reg_table[wid].erase(regnum);
}
-
-// Reserve registers for an instruction
-void Scoreboard::reserveRegisters(unsigned wid, const class inst_t* inst)
+void Scoreboard::reserveRegisters(const class warp_inst_t* inst)
{
- // Reserve registers
- if(inst->out[0] > 0) reserveRegister(wid, inst->out[0]);
- if(inst->out[1] > 0) reserveRegister(wid, inst->out[1]);
- if(inst->out[2] > 0) reserveRegister(wid, inst->out[2]);
- if(inst->out[3] > 0) reserveRegister(wid, inst->out[3]);
+ for( unsigned r=0; r < 4; r++)
+ if(inst->out[r] > 0) reserveRegister(inst->warp_id(), inst->out[r]);
}
// Release registers for an instruction
void Scoreboard::releaseRegisters(const class warp_inst_t *inst)
{
- unsigned wid = inst->warp_id();
- if(inst->out[0] > 0) releaseRegister(wid, inst->out[0]);
- if(inst->out[1] > 0) releaseRegister(wid, inst->out[1]);
- if(inst->out[2] > 0) releaseRegister(wid, inst->out[2]);
- if(inst->out[3] > 0) releaseRegister(wid, inst->out[3]);
+ for( unsigned r=0; r < 4; r++)
+ if(inst->out[r] > 0) releaseRegister(inst->warp_id(), inst->out[r]);
}
/**
@@ -82,7 +68,7 @@ void Scoreboard::releaseRegisters(const class warp_inst_t *inst)
* @return
* true if WAW or RAW hazard (no WAR since in-order issue)
**/
-bool Scoreboard::checkCollision( unsigned wid, const class inst_t *inst )
+bool Scoreboard::checkCollision( unsigned wid, const class inst_t *inst ) const
{
// Get list of all input and output registers
std::set<int> inst_regs;
@@ -100,7 +86,7 @@ bool Scoreboard::checkCollision( unsigned wid, const class inst_t *inst )
if(inst->ar2 > 0) inst_regs.insert(inst->ar2);
// Check for collision, get the intersection of reserved registers and instruction registers
- std::set<int>::iterator it2;
+ std::set<int>::const_iterator it2;
for ( it2=inst_regs.begin() ; it2 != inst_regs.end(); it2++ )
if(reg_table[wid].find(*it2) != reg_table[wid].end()) {
return true;
diff --git a/src/gpgpu-sim/scoreboard.h b/src/gpgpu-sim/scoreboard.h
index 4e1c154..1b7235d 100644
--- a/src/gpgpu-sim/scoreboard.h
+++ b/src/gpgpu-sim/scoreboard.h
@@ -20,22 +20,21 @@ class Scoreboard {
public:
Scoreboard( unsigned sid, unsigned n_warps );
- void printContents();
-
- void reserveRegisters(unsigned wid, const inst_t *inst);
+ void reserveRegisters(const warp_inst_t *inst);
void releaseRegisters(const warp_inst_t *inst);
+ void releaseRegister(unsigned wid, unsigned regnum);
- bool checkCollision(unsigned wid, const inst_t *inst);
+ bool checkCollision(unsigned wid, const inst_t *inst) const;
bool pendingWrites(unsigned wid) const;
+ void printContents() const;
private:
void reserveRegister(unsigned wid, unsigned regnum);
- void releaseRegister(unsigned wid, unsigned regnum);
unsigned m_sid;
// keeps track of pending writes to registers
- // indexed by warp id
- std::vector< std::set<int> > reg_table;
+ // indexed by warp id, reg_id => pending write count
+ std::vector< std::set<unsigned> > reg_table;
};
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index f298a67..ae62b97 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -79,6 +79,9 @@
#include "mem_fetch.h"
#include "mem_latency_stat.h"
#include "visualizer.h"
+#include "../intersim/statwraper.h"
+#include "../intersim/interconnect_interface.h"
+#include "icnt_wrapper.h"
#include <string.h>
#include <limits.h>
@@ -102,6 +105,7 @@ static const char* MSHR_Status_str[] = {
"IN_L2TOCBQUEUE_HIT",
"IN_L2TOCBQUEUE_MISS",
"IN_ICNT2SHADER",
+ "IN_CLUSTER2SHADER",
"FETCHED",
};
@@ -146,9 +150,7 @@ bool mshr_lookup::can_merge(mshr_entry * mshr)
if (mshr->isatomic())
return false; // can't merge a atomic operation
bool interwarp_mshr_merge = m_shader_config->gpgpu_interwarp_mshr_merge & GLOBAL_MSHR_MERGE;
- if (mshr->isinst())
- interwarp_mshr_merge=true;
- else if (mshr->istexture())
+ if (mshr->istexture())
interwarp_mshr_merge = m_shader_config->gpgpu_interwarp_mshr_merge & TEX_MSHR_MERGE;
else if (mshr->isconst())
interwarp_mshr_merge = m_shader_config->gpgpu_interwarp_mshr_merge & CONST_MSHR_MERGE;
@@ -235,9 +237,15 @@ std::list<mshr_entry*> &mshr_shader_unit::choose_return_queue()
return m_mshr_return_queue;
}
-void mshr_shader_unit::mshr_return_from_mem(mshr_entry *mshr)
+void mshr_shader_unit::mshr_return_from_mem(unsigned mshr_id)
{
- mshr->set_status( FETCHED );
+ if(mshr_id == -1) {
+ return;
+ }
+ mshr_entry *mshr = &m_mshrs[mshr_id];
+ mshr->set_fetched();
+ mem_fetch *mf = mshr->get_mf();
+ if( mf ) mf->set_status( FETCHED, MR_RETURN_Q, gpu_sim_cycle+gpu_tot_sim_cycle );
if ( not mshr->istexture() ) {
//place in return queue
mshr->add_to_queue( m_mshr_return_queue );
@@ -266,9 +274,10 @@ void mshr_shader_unit::print(FILE* fp)
mshr_entry *mshr = *m;
mshr->print(fp);
}
- fprintf(fp,"\nTotal outstanding memory requests = %u\n", num_outstanding );
+ fprintf(fp,"outstanding memory requests = %u\n", num_outstanding );
}
+
std::list<unsigned> shader_core_ctx::get_regs_written( const inst_t &fvt ) const
{
std::list<unsigned> result;
@@ -280,31 +289,22 @@ std::list<unsigned> shader_core_ctx::get_regs_written( const inst_t &fvt ) const
return result;
}
-int log2i(int n) {
- int lg;
- lg = -1;
- while (n) {
- n>>=1;lg++;
- }
- return lg;
-}
-
-shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
- const char *name,
+shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
+ class simt_core_cluster *cluster,
unsigned shader_id,
unsigned tpc_id,
struct shader_core_config *config,
struct shader_core_stats *stats )
: m_barriers( config->max_warps_per_shader, config->max_cta_per_core )
{
- m_gpu = gpu;
+ m_gpu = gpu;
+ m_cluster = cluster;
m_config = config;
m_stats = stats;
unsigned warp_size=config->warp_size;
config->max_sfu_latency = 32;
config->max_sp_latency = 32;
- m_name = name;
m_sid = shader_id;
m_tpc = tpc_id;
@@ -364,7 +364,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
m_dispatch_port[1] = ID_OC_SFU;
m_issue_port[1] = OC_EX_SFU;
- m_ldst_unit = new ldst_unit( m_gpu, this, &m_pipeline_reg[EX_WB], config, m_stats, m_sid, m_tpc );
+ m_ldst_unit = new ldst_unit( m_cluster, this, &m_operand_collector, m_scoreboard, config, m_stats, m_sid, m_tpc );
m_fu[2] = m_ldst_unit;
m_dispatch_port[2] = ID_OC_MEM;
m_issue_port[2] = OC_EX_MEM;
@@ -406,12 +406,6 @@ void shader_core_ctx::init_warps( unsigned cta_id, unsigned start_thread, unsign
}
}
-// initalize the pipeline stage register to nops
-void shader_core_ctx::clear_stage_reg(int stage)
-{
- m_pipeline_reg[stage]->clear();
-}
-
// return the next pc of a thread
address_type shader_core_ctx::next_pc( int tid ) const
{
@@ -501,9 +495,15 @@ void pdom_warp_ctx_t::pdom_update_warp_mask()
assert(scheduled_warp->m_stack_top < m_warp_size * 2);
}
+unsigned gpgpu_sim::sid_to_cluster( unsigned sid ) const
+{
+ return sid / m_shader_config->n_simt_cores_per_cluster;
+}
+
void gpgpu_sim::get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc )
{
- m_sc[sid]->get_pdom_stack_top_info(tid,pc,rpc);
+ unsigned cluster_id = sid_to_cluster(sid);
+ m_cluster[cluster_id]->get_pdom_stack_top_info(sid,tid,pc,rpc);
}
void shader_core_ctx::get_pdom_stack_top_info( unsigned tid, unsigned *pc, unsigned *rpc )
@@ -615,27 +615,23 @@ void shader_core_ctx::fetch()
enum cache_request_status status = m_L1I->access( (unsigned long long)pc, 0, gpu_sim_cycle, &wb );
if( status != HIT ) {
unsigned req_size = READ_PACKET_SIZE;
- if( m_gpu->fq_has_buffer(ppc, req_size, false, m_sid) ) {
+ if( !m_cluster->icnt_injection_buffer_full(ppc, req_size, false) ) {
m_last_warp_fetched=warp_id;
- mshr_entry *mshr = new mshr_entry();
- mshr->init(ppc,false,instruction_space,warp_id);
-
mem_fetch *mf = new mem_fetch(pc,
req_size,
READ_PACKET_SIZE,
m_sid,
m_tpc,
warp_id,
- mshr,
+ (unsigned)-1/*mshr_id*/,
+ NULL/*we don't have an instruction yet*/,
false,
NO_PARTIAL_WRITE,
INST_ACC_R,
- RD_REQ,
- pc);
- mshr->set_mf(mf);
- m_gpu->issue_mf_from_fq(mf);
+ RD_REQ );
+ m_cluster->icnt_inject_request_packet(mf);
- m_warp[warp_id].set_imiss_pending(mshr);
+ m_warp[warp_id].set_imiss_pending();
m_warp[warp_id].set_last_fetch(gpu_sim_cycle);
}
} else {
@@ -658,7 +654,8 @@ void shader_core_ctx::func_exec_inst( warp_inst_t &inst )
if( inst.has_callback(t) )
m_warp[inst.warp_id()].inc_n_atomic();
if (inst.space.is_local() && (inst.is_load() || inst.is_store()))
- inst.set_addr(t, translate_local_memaddr(inst.get_addr(t), tid, m_gpu->num_shader()) );
+ inst.set_addr(t, translate_local_memaddr(inst.get_addr(t), tid,
+ m_config->n_simt_clusters*m_config->n_simt_cores_per_cluster) );
if ( ptx_thread_done(tid) ) {
m_warp[inst.warp_id()].inc_n_completed();
m_warp[inst.warp_id()].ibuffer_flush();
@@ -679,7 +676,7 @@ void shader_core_ctx::issue_warp( warp_inst_t *&pipe_reg, const warp_inst_t *nex
else if( next_inst->op == MEMORY_BARRIER_OP )
set_at_memory_barrier(warp_id);
m_pdom_warp[warp_id]->pdom_update_warp_mask();
- m_scoreboard->reserveRegisters(warp_id, next_inst);
+ m_scoreboard->reserveRegisters(pipe_reg);
m_warp[warp_id].set_next_pc(next_inst->pc + next_inst->isize);
}
@@ -806,7 +803,7 @@ mshr_entry* mshr_shader_unit::add_mshr(mem_access_t &access, warp_inst_t* pinst)
if (mergehit) {
mergehit->merge(mshr);
if (mergehit->fetched())
- mshr_return_from_mem(mshr);
+ mshr_return_from_mem(mshr->get_id());
}
m_mshr_lookup.mshr_fast_lookup_insert(mshr);
}
@@ -1035,7 +1032,7 @@ mem_stage_stall_type ldst_unit::send_mem_request(warp_inst_t &inst, mem_access_t
// It is possible to do this writeback in the same cycle as the access request, this may not be realistic.
if (access.need_wb) {
unsigned req_size = m_config->gpgpu_cache_dl1_linesize + WRITE_PACKET_SIZE;
- if ( !m_gpu->fq_has_buffer(access.wb_addr, req_size, true, m_sid) ) {
+ if ( m_cluster->icnt_injection_buffer_full(access.wb_addr, req_size, true) ) {
m_stats->gpu_stall_sh2icnt++;
return WB_ICNT_RC_FAIL;
}
@@ -1044,31 +1041,40 @@ mem_stage_stall_type ldst_unit::send_mem_request(warp_inst_t &inst, mem_access_t
READ_PACKET_SIZE,
m_sid,
m_tpc,
- -1,
+ -1/*wid*/,
+ -1/*mshr id*/,
NULL,
true,
NO_PARTIAL_WRITE,
inst.space.is_local()?LOCAL_ACC_W:GLOBAL_ACC_W, //space of cache line is same as new request
- WT_REQ,
- -1);
- m_gpu->issue_mf_from_fq(mf);
+ WT_REQ );
+ m_cluster->icnt_inject_request_packet(mf);
+ inst.clear_active(access.warp_indices);
m_stats->L1_writeback++;
access.need_wb = false;
}
bool is_write = inst.is_store();
mem_access_type access_type;
+ bool requires_mshr = false;
switch(inst.space.get_type()) {
case const_space:
- case param_space_kernel: access_type = CONST_ACC_R; break;
- case tex_space: access_type = TEXTURE_ACC_R; break;
- case global_space: access_type = is_write? GLOBAL_ACC_W: GLOBAL_ACC_R; break;
+ case param_space_kernel:
+ access_type = CONST_ACC_R;
+ break;
+ case tex_space:
+ access_type = TEXTURE_ACC_R;
+ break;
+ case global_space:
+ access_type = is_write? GLOBAL_ACC_W: GLOBAL_ACC_R;
+ break;
case local_space:
- case param_space_local: access_type = is_write? LOCAL_ACC_W: LOCAL_ACC_R; break;
+ case param_space_local:
+ access_type = is_write? LOCAL_ACC_W: LOCAL_ACC_R;
+ break;
default: assert(0); break;
}
//reserve mshr
- bool requires_mshr = (!is_write);
if (requires_mshr && !access.reserved_mshr) {
if (not m_mshr_unit->has_mshr(1))
return MSHR_RC_FAIL;
@@ -1087,7 +1093,7 @@ mem_stage_stall_type ldst_unit::send_mem_request(warp_inst_t &inst, mem_access_t
else
request_size += WRITE_PACKET_SIZE + WRITE_MASK_SIZE; //plain write
}
- if ( !m_gpu->fq_has_buffer(access.addr, request_size, is_write, m_sid) ) {
+ if ( m_cluster->icnt_injection_buffer_full(access.addr, request_size, is_write) ) {
// can't allocate icnt
m_stats->gpu_stall_sh2icnt++;
return ICNT_RC_FAIL;
@@ -1105,21 +1111,29 @@ mem_stage_stall_type ldst_unit::send_mem_request(warp_inst_t &inst, mem_access_t
if (write_mask.count() != access.req_size)
m_stats->gpgpu_n_partial_writes++;
}
+ unsigned mshr_id = access.reserved_mshr?access.reserved_mshr->get_id():-1;
+ warp_inst_t inst_copy = inst;
+ inst_copy.set_active(access.warp_indices);
mem_fetch *mf = new mem_fetch(access.addr,
request_size,
is_write?WRITE_PACKET_SIZE:READ_PACKET_SIZE,
m_sid,
m_tpc,
warp_id,
- access.reserved_mshr,
+ mshr_id,
+ &inst_copy,
is_write,
write_mask,
access_type,
- is_write?WT_REQ:RD_REQ,
- inst.pc);
+ is_write?WT_REQ:RD_REQ);
if( access.reserved_mshr )
access.reserved_mshr->set_mf(mf);
- m_gpu->issue_mf_from_fq(mf);
+ m_cluster->icnt_inject_request_packet(mf);
+ if( inst.is_load() ) {
+ for( unsigned r=0; r < 4; r++)
+ if(inst.out[r] > 0)
+ m_pending_writes[inst.warp_id()][inst.out[r]]++;
+ }
}
return NO_RC_FAIL;
}
@@ -1136,6 +1150,7 @@ void shader_core_ctx::writeback()
m_gpu->gpu_sim_insn += pipe_reg->active_count();
pipe_reg->clear();
}
+ m_ldst_unit->writeback();
}
bool ldst_unit::shared_cycle( warp_inst_t &inst, mem_stage_stall_type &rc_fail, mem_stage_access_type &fail_type)
@@ -1176,18 +1191,19 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue( ldst_unit::cache_ch
break;
unsigned current_order = inst.accessq_back().order;
// consume all requests of the same "order" but stop if we hit a structural hazard
- while ((!inst.accessq_empty()) && inst.accessq_back().order == current_order && hazard_cond == NO_RC_FAIL) {
+ while( !inst.accessq_empty() && inst.accessq_back().order == current_order && hazard_cond == NO_RC_FAIL) {
hazard_cond = (this->*cache_check)(inst,inst.accessq_back());
if (hazard_cond != NO_RC_FAIL)
break; // can't complete this request this cycle.
- if (! inst.accessq_back().cache_hit){
+ if ( !inst.accessq_back().cache_hit ){
if (mem_req_count < memory_send_max) {
mem_req_count++;
- hazard_cond = send_mem_request(inst,inst.accessq_back()); // attemp to get mshr, icnt, send;
+ hazard_cond = send_mem_request(inst,inst.accessq_back());
}
else hazard_cond = COAL_STALL; // not really a coal stall, its a too many memory request stall;
- if ( hazard_cond != NO_RC_FAIL) break; //can't complete this request this cycle.
- }
+ if ( hazard_cond != NO_RC_FAIL)
+ break; //can't complete this request this cycle.
+ }
inst.accessq_pop_back();
}
}
@@ -1236,7 +1252,6 @@ bool ldst_unit::texture_cycle( warp_inst_t &inst, mem_stage_stall_type &rc_fail,
return inst.accessq_empty(); //done if empty.
}
-
mem_stage_stall_type ldst_unit::dcache_check(warp_inst_t &inst, mem_access_t& access)
{
// Global memory (data cache) checks the cache for each access at the time it is processed.
@@ -1255,7 +1270,8 @@ mem_stage_stall_type ldst_unit::dcache_check(warp_inst_t &inst, mem_access_t& ac
return WB_CACHE_RSRV_FAIL;
}
access.cache_hit = (status == HIT); //if HIT_W_WT then still send to memory so "MISS"
- if (status == MISS_W_WB) access.need_wb = true;
+ if (status == MISS_W_WB)
+ access.need_wb = true;
if (status == WB_HIT_ON_MISS && inst.is_store())
{
//write has hit a reserved cache line
@@ -1320,15 +1336,14 @@ bool ldst_unit::memory_cycle( warp_inst_t &inst, mem_stage_stall_type &stall_rea
return inst.accessq_empty(); //done if empty.
}
+bool ldst_unit::response_buffer_full() const
+{
+ return m_response_fifo.size() >= m_config->ldst_unit_response_queue_size;
+}
+
void ldst_unit::fill( mem_fetch *mf )
{
- m_mshr_unit->mshr_return_from_mem(mf->get_mshr());
- if (mf->istexture())
- m_L1T->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
- else if (mf->isconst())
- m_L1C->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
- else if (!m_config->gpgpu_no_dl1)
- m_L1D->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
+ m_response_fifo.push_back(mf);
}
void ldst_unit::flush()
@@ -1376,20 +1391,23 @@ void ldst_unit::generate_mem_accesses(warp_inst_t &inst)
case param_space_unclassified: abort(); break;
default: break; // non-memory operations
}
- m_gpu->mem_instruction_stats(inst);
+ m_cluster->mem_instruction_stats(inst);
inst.set_mem_accesses_created();
}
-ldst_unit::ldst_unit( gpgpu_sim *gpu,
+ldst_unit::ldst_unit( simt_core_cluster *cluster,
shader_core_ctx *core,
- warp_inst_t **result_port,
+ opndcoll_rfu_t *operand_collector,
+ Scoreboard *scoreboard,
shader_core_config *config,
shader_core_stats *stats,
unsigned sid,
- unsigned tpc ) : simd_function_unit(result_port,config)
+ unsigned tpc ) : pipelined_simd_unit(NULL,config,6)
{
- m_gpu = gpu;
+ m_cluster = cluster;
m_core = core;
+ m_operand_collector = operand_collector;
+ m_scoreboard = scoreboard;
m_stats = stats;
m_sid = sid;
m_tpc = tpc;
@@ -1407,21 +1425,69 @@ ldst_unit::ldst_unit( gpgpu_sim *gpu,
config->gpgpu_cache_dl1_linesize = m_L1D->get_line_sz();
config->gpgpu_cache_texl1_linesize = m_L1T->get_line_sz();
config->gpgpu_cache_constl1_linesize = m_L1C->get_line_sz();
- m_gpu->ptx_set_tex_cache_linesize(m_L1T->get_line_sz());
+ m_cluster->get_gpu()->ptx_set_tex_cache_linesize(m_L1T->get_line_sz());
m_mshr_unit = new mshr_shader_unit(m_config);
m_mem_rc = NO_RC_FAIL;
}
+void ldst_unit::writeback()
+{
+ mshr_entry *m = m_mshr_unit->return_head();
+ if( m ) m_mshr_unit->pop_return_head();
+
+ if( !m_pipeline_reg[0]->empty() ) {
+ // shared memory has priority
+ if( m_operand_collector->writeback(*m_pipeline_reg[0]) ) {
+ m_scoreboard->releaseRegisters(m_pipeline_reg[0]);
+ m_core->dec_inst_in_pipeline(m_pipeline_reg[0]->warp_id());
+ m_pipeline_reg[0]->clear();
+ }
+ }
+
+ if( !m_response_fifo.empty() ) {
+ mem_fetch *mf = m_response_fifo.front();
+ if( mf->get_is_write() ) {
+ m_core->store_ack(mf);
+ m_response_fifo.pop_front();
+ } else {
+ const warp_inst_t &inst = mf->get_inst();
+ if( m_operand_collector->writeback(inst) ) {
+ m_response_fifo.pop_front();
+ if( mf->isatomic() )
+ m_core->decrement_atomic_count(mf->get_wid(),inst.active_count());
+ for( unsigned r=0; r < 4; r++ ) {
+ if( inst.out[r] > 0 ) {
+ assert( m_pending_writes[inst.warp_id()][inst.out[r]] > 0 );
+ unsigned still_pending = --m_pending_writes[inst.warp_id()][inst.out[r]];
+ if( !still_pending ) {
+ m_pending_writes[inst.warp_id()].erase(inst.out[r]);
+ m_scoreboard->releaseRegister( inst.warp_id(), inst.out[r] );
+ }
+ }
+ }
+ m_mshr_unit->mshr_return_from_mem(mf->get_mshr());
+ if (mf->istexture())
+ m_L1T->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
+ else if (mf->isconst())
+ m_L1C->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
+ else if (!m_config->gpgpu_no_dl1)
+ m_L1D->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
+ delete mf;
+ }
+ }
+ }
+}
+
void ldst_unit::cycle()
{
- mshr_entry *m = m_mshr_unit->return_head();
- if( m ) {
- delete m->get_mf();
- m_mshr_unit->pop_return_head();
- }
+ for( unsigned stage=0; (stage+1)<m_pipeline_depth; stage++ )
+ if( m_pipeline_reg[stage]->empty() && !m_pipeline_reg[stage+1]->empty() )
+ move_warp(m_pipeline_reg[stage], m_pipeline_reg[stage+1]);
+ // process new memory requests
warp_inst_t &pipe_reg = *m_dispatch_reg;
generate_mem_accesses(pipe_reg);
+
enum mem_stage_stall_type rc_fail = NO_RC_FAIL;
mem_stage_access_type type;
bool done = true;
@@ -1436,30 +1502,65 @@ void ldst_unit::cycle()
m_stats->gpu_stall_shd_mem_breakdown[type][rc_fail]++;
return;
}
- if( !(*m_result_port)->empty() )
- return; // writeback stalled
- move_warp(*m_result_port,m_dispatch_reg);
+
+ if( !pipe_reg.empty() ) {
+ unsigned warp_id = pipe_reg.warp_id();
+ if( pipe_reg.is_load() ) {
+ if( pipe_reg.space.get_type() == shared_space ) {
+ if( m_pipeline_reg[5]->empty() ) {
+ // new shared memory request
+ move_warp(m_pipeline_reg[5],m_dispatch_reg);
+ m_dispatch_reg->clear();
+ }
+ } else {
+ if( pipe_reg.active_count() > 0 ) {
+ if( !m_operand_collector->writeback(pipe_reg) )
+ return;
+ }
+
+ bool pending_requests=false;
+ for( unsigned r=0; r<4; r++ ) {
+ unsigned reg_id = pipe_reg.out[r];
+ if( reg_id > 0 ) {
+ if( m_pending_writes[warp_id].find(reg_id) != m_pending_writes[warp_id].end() ) {
+ assert( m_pending_writes[warp_id][reg_id] > 0 );
+ pending_requests=true;
+ break;
+ }
+ }
+ }
+ if( !pending_requests )
+ m_scoreboard->releaseRegisters(m_dispatch_reg);
+ m_core->dec_inst_in_pipeline(warp_id);
+ m_dispatch_reg->clear();
+ }
+ } else {
+ // stores exit pipeline here
+ m_core->dec_inst_in_pipeline(warp_id);
+ m_dispatch_reg->clear();
+ }
+ }
}
void shader_core_ctx::register_cta_thread_exit(int tid )
{
- shader_core_ctx *shader = this;
unsigned padded_cta_size = m_gpu->the_kernel().threads_per_cta();
if (padded_cta_size%m_config->warp_size)
padded_cta_size = ((padded_cta_size/m_config->warp_size)+1)*(m_config->warp_size);
int cta_num = tid/padded_cta_size;
- assert( shader->m_cta_status[cta_num] > 0 );
- shader->m_cta_status[cta_num]--;
- if (!shader->m_cta_status[cta_num]) {
- shader->m_n_active_cta--;
- shader->deallocate_barrier(cta_num);
- shader_CTA_count_unlog(shader->m_sid, 1);
- printf("GPGPU-Sim uArch: Shader %d finished CTA #%d (%lld,%lld)\n", shader->m_sid, cta_num, gpu_sim_cycle, gpu_tot_sim_cycle );
+ assert( m_cta_status[cta_num] > 0 );
+ m_cta_status[cta_num]--;
+ if (!m_cta_status[cta_num]) {
+ m_n_active_cta--;
+ deallocate_barrier(cta_num);
+ shader_CTA_count_unlog(m_sid, 1);
+ printf("GPGPU-Sim uArch: Shader %d finished CTA #%d (%lld,%lld)\n", m_sid, cta_num, gpu_sim_cycle, gpu_tot_sim_cycle );
}
}
void gpgpu_sim::shader_print_runtime_stat( FILE *fout )
{
+ /*
fprintf(fout, "SHD_INSN: ");
for (unsigned i=0;i<m_n_shader;i++)
fprintf(fout, "%u ",m_sc[i]->get_num_sim_insn());
@@ -1477,11 +1578,13 @@ void gpgpu_sim::shader_print_runtime_stat( FILE *fout )
for (unsigned i=0; i<m_shader_config->n_thread_per_shader; i++)
fprintf(fout, "%d ", m_sc[0]->get_thread_n_insn(i) );
fprintf(fout, "\n");
+ */
}
void gpgpu_sim::shader_print_l1_miss_stat( FILE *fout )
{
+ /*
fprintf(fout, "THD_INSN_AC: ");
for (unsigned i=0; i<m_shader_config->n_thread_per_shader; i++)
fprintf(fout, "%d ", m_sc[0]->get_thread_n_insn_ac(i));
@@ -1530,6 +1633,7 @@ void gpgpu_sim::shader_print_l1_miss_stat( FILE *fout )
}
}
fprintf(fout, "\n");
+ */
}
void warp_inst_t::print( FILE *fout ) const
@@ -1598,6 +1702,20 @@ void ldst_unit::print(FILE *fout) const
fprintf(fout,"\n");
}
m_mshr_unit->print(fout);
+ fprintf(fout,"Pending register writes:\n");
+ std::map<unsigned/*warp_id*/, std::map<unsigned/*regnum*/,unsigned/*count*/> >::const_iterator w;
+ for( w=m_pending_writes.begin(); w!=m_pending_writes.end(); w++ ) {
+ unsigned warp_id = w->first;
+ const std::map<unsigned/*regnum*/,unsigned/*count*/> &warp_info = w->second;
+ if( warp_info.empty() )
+ continue;
+ fprintf(fout," w%2u : ", warp_id );
+ std::map<unsigned/*regnum*/,unsigned/*count*/>::const_iterator r;
+ for( r=warp_info.begin(); r!=warp_info.end(); ++r ) {
+ fprintf(fout," %u(%u)", r->first, r->second );
+ }
+ fprintf(fout,"\n");
+ }
}
void shader_core_ctx::display_pipeline(FILE *fout, int print_mem, int mask )
@@ -1696,7 +1814,7 @@ unsigned int shader_core_ctx::max_cta( class function_info *kernel )
}
if (result < 1) {
- printf ("Error: max_cta_per_shader(\"%s\") returning %d. Kernel requires more resources than shader has?\n", m_name, result);
+ printf ("Error: max_cta_per_shader(\"sid=%u\") returning %d. Kernel requires more resources than shader has?\n", m_sid, result);
abort();
}
return result;
@@ -1966,10 +2084,40 @@ void shader_core_ctx::deallocate_barrier( unsigned cta_id )
m_barriers.deallocate_barrier(cta_id);
}
-void shader_core_ctx::decrement_atomic_count( unsigned wid )
+void shader_core_ctx::decrement_atomic_count( unsigned wid, unsigned n )
+{
+ assert( m_warp[wid].get_n_atomic() >= n );
+ m_warp[wid].dec_n_atomic(n);
+}
+
+
+bool shader_core_ctx::fetch_unit_response_buffer_full() const
+{
+ return false;
+}
+
+void shader_core_ctx::accept_fetch_response( mem_fetch *mf )
{
- assert( m_warp[wid].get_n_atomic() > 0 );
- m_warp[wid].dec_n_atomic();
+ m_L1I->shd_cache_fill(mf->get_addr(),gpu_sim_cycle+gpu_tot_sim_cycle);
+ m_warp[mf->get_wid()].clear_imiss_pending();
+ delete mf;
+}
+
+bool shader_core_ctx::ldst_unit_response_buffer_full()
+{
+ return m_ldst_unit->response_buffer_full();
+}
+
+void shader_core_ctx::accept_ldst_unit_response(mem_fetch * mf)
+{
+ m_ldst_unit->fill(mf);
+ //freed_read_mfs++;
+}
+
+void shader_core_ctx::store_ack( class mem_fetch *mf )
+{
+ unsigned warp_id = mf->get_wid();
+ m_warp[warp_id].dec_store_req();
}
bool shd_warp_t::done()
@@ -2077,7 +2225,6 @@ void mshr_entry::init( new_addr_type address, bool wr, memory_space_t space, uns
{
static unsigned next_request_uid = 1;
m_request_uid = next_request_uid++;
- m_status = INITIALIZED;
m_addr = address;
m_mf = NULL;
m_merged_on_other_reqest = false;
@@ -2087,23 +2234,11 @@ void mshr_entry::init( new_addr_type address, bool wr, memory_space_t space, uns
m_islocal = space.is_local();
m_isconst = space.is_const();
m_istexture = space==tex_space;
+ m_isatomic = false;
m_insts.clear();
m_warp_id = warp_id;
}
-void mshr_entry::set_status( enum mshr_status status )
-{
- mshr_entry * req = this;
- while (req) {
- req->m_status = status;
- req = req->m_merged_requests;
- }
-#if DEBUGL1MISS
-#define CACHE_TAG_OF_64(x) ((x) & (~((unsigned long long int)64 - 1)))
- printf("cycle %d Addr %x %d \n",gpu_sim_cycle,CACHE_TAG_OF_64(m_addr),status);
-#endif
-}
-
void mshr_entry::print(FILE *fp) const
{
fprintf(fp, "MSHR(%u): w%2u req uid=%5u, %s (0x%llx) merged:%d status:%s ",
@@ -2113,7 +2248,7 @@ void mshr_entry::print(FILE *fp) const
(m_iswrite)? "store" : "load ",
m_addr,
(m_merged_requests != NULL || m_merged_on_other_reqest),
- MSHR_Status_str[m_status]);
+ m_mf?MSHR_Status_str[ m_mf->get_status() ]:"???");
if ( m_mf )
ptx_print_insn( m_mf->get_pc(), fp );
fprintf(fp,"\n");
@@ -2165,22 +2300,20 @@ int register_bank(int regnum, int wid, unsigned num_banks, unsigned bank_warp_sh
return bank % num_banks;
}
-bool opndcoll_rfu_t::writeback( const warp_inst_t &warp )
+bool opndcoll_rfu_t::writeback( const warp_inst_t &inst )
{
- assert( !warp.empty() );
- std::list<unsigned> regs = m_shader->get_regs_written(warp);
+ assert( !inst.empty() );
+ std::list<unsigned> regs = m_shader->get_regs_written(inst);
std::list<unsigned>::iterator r;
- unsigned last_reg = -1;
unsigned n=0;
for( r=regs.begin(); r!=regs.end();r++,n++ ) {
unsigned reg = *r;
- unsigned bank = register_bank(reg,warp.warp_id(),m_num_banks,m_bank_warp_shift);
+ unsigned bank = register_bank(reg,inst.warp_id(),m_num_banks,m_bank_warp_shift);
if( m_arbiter.bank_idle(bank) ) {
- m_arbiter.allocate_bank_for_write(bank,op_t(&warp,reg,m_num_banks,m_bank_warp_shift));
+ m_arbiter.allocate_bank_for_write(bank,op_t(&inst,reg,m_num_banks,m_bank_warp_shift));
} else {
return false;
}
- last_reg=reg;
}
return true;
}
@@ -2237,13 +2370,6 @@ void opndcoll_rfu_t::allocate_reads()
}
}
-
-void gpgpu_sim::decrement_atomic_count( unsigned sid, unsigned wid )
-{
- m_sc[sid]->decrement_atomic_count(wid);
-}
-
-
bool opndcoll_rfu_t::collector_unit_t::ready() const
{
return (!m_free) && m_not_ready.none() && (*m_port)->empty();
@@ -2320,3 +2446,159 @@ class ptx_thread_info *shader_core_ctx::get_thread_state( unsigned hw_thread_id
assert( hw_thread_id < m_config->n_thread_per_shader );
return m_thread[ hw_thread_id ].m_functional_model_thread_state;
}
+
+simt_core_cluster::simt_core_cluster( class gpgpu_sim *gpu,
+ unsigned cluster_id,
+ struct shader_core_config *config,
+ struct shader_core_stats *stats )
+{
+ m_cta_issue_next_core=0;
+ m_cluster_id=cluster_id;
+ m_gpu = gpu;
+ m_config = config;
+ m_stats = stats;
+ m_core = new shader_core_ctx*[ config->n_simt_cores_per_cluster ];
+ for( unsigned i=0; i < config->n_simt_cores_per_cluster; i++ )
+ m_core[i] = new shader_core_ctx(gpu,this,cid_to_sid(i),m_cluster_id,config,stats);
+}
+
+void simt_core_cluster::core_cycle()
+{
+ for( unsigned i=0; i < m_config->n_simt_cores_per_cluster; i++ )
+ m_core[i]->cycle();
+}
+
+void simt_core_cluster::reinit()
+{
+ for( unsigned i=0; i < m_config->n_simt_cores_per_cluster; i++ )
+ m_core[i]->reinit(0,m_config->n_thread_per_shader,true);
+}
+
+unsigned simt_core_cluster::max_cta( class function_info *kernel )
+{
+ return m_config->n_simt_cores_per_cluster * m_core[0]->max_cta(kernel);
+}
+
+int simt_core_cluster::get_not_completed() const
+{
+ unsigned not_completed=0;
+ for( unsigned i=0; i < m_config->n_simt_cores_per_cluster; i++ )
+ not_completed += m_core[i]->get_not_completed();
+ return not_completed;
+}
+
+unsigned simt_core_cluster::get_n_active_cta() const
+{
+ unsigned n=0;
+ for( unsigned i=0; i < m_config->n_simt_cores_per_cluster; i++ )
+ n += m_core[i]->get_n_active_cta();
+ return n;
+}
+
+void simt_core_cluster::issue_block2core( class kernel_info_t &kernel )
+{
+ for( unsigned i=0; i < m_config->n_simt_cores_per_cluster; i++ ) {
+ unsigned core = (i+m_cta_issue_next_core)%m_config->n_simt_cores_per_cluster;
+ if( m_core[core]->get_n_active_cta() < m_core[core]->max_cta(kernel.entry()) ) {
+ m_core[core]->issue_block2core(kernel);
+ break;
+ }
+ }
+}
+
+void simt_core_cluster::cache_flush()
+{
+ for( unsigned i=0; i < m_config->n_simt_cores_per_cluster; i++ )
+ m_core[i]->cache_flush();
+}
+
+bool simt_core_cluster::icnt_injection_buffer_full(new_addr_type addr, int bsize, bool write )
+{
+ //requests should be single always now
+ int rsize = bsize;
+ //maintain similar functionality with fq_push, if its a read, bsize is the load size, not the request's size
+ if (!write)
+ rsize = READ_PACKET_SIZE;
+ return ! ::icnt_has_buffer(m_cluster_id, rsize);
+}
+
+void simt_core_cluster::icnt_inject_request_packet(class mem_fetch *mf)
+{
+ // stats
+ if (mf->get_is_write()) m_stats->made_write_mfs++;
+ else m_stats->made_read_mfs++;
+ switch (mf->get_mem_acc()) {
+ case CONST_ACC_R: m_stats->gpgpu_n_mem_const++; break;
+ case TEXTURE_ACC_R: m_stats->gpgpu_n_mem_texture++; break;
+ case GLOBAL_ACC_R: m_stats->gpgpu_n_mem_read_global++; break;
+ case GLOBAL_ACC_W: m_stats->gpgpu_n_mem_write_global++; break;
+ case LOCAL_ACC_R: m_stats->gpgpu_n_mem_read_local++; break;
+ case LOCAL_ACC_W: m_stats->gpgpu_n_mem_write_local++; break;
+ case INST_ACC_R: m_stats->gpgpu_n_mem_read_inst++; break;
+ default: assert(0);
+ }
+
+ unsigned destination = mf->get_tlx_addr().chip;
+ mf->set_status(IN_ICNT2MEM,MR_ICNT_PUSHED,gpu_sim_cycle+gpu_tot_sim_cycle);
+ if (!mf->get_is_write()) {
+ mf->set_type(RD_REQ);
+ ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void*)mf, mf->get_ctrl_size() );
+ } else {
+ mf->set_type(WT_REQ);
+ ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void*)mf, mf->size());
+ //gpgpu_n_sent_writes++;
+ }
+}
+
+void simt_core_cluster::icnt_eject_response_packet(class mem_fetch * mf)
+{
+ assert( mf->get_tpc() == m_cluster_id );
+ m_response_fifo.push_back(mf);
+}
+
+void simt_core_cluster::icnt_cycle()
+{
+ if( !m_response_fifo.empty() ) {
+ mem_fetch *mf = m_response_fifo.front();
+ unsigned cid = sid_to_cid(mf->get_sid());
+ if( mf->get_mem_acc() == INST_ACC_R ) {
+ // instruction fetch response
+ if( !m_core[cid]->fetch_unit_response_buffer_full() ) {
+ m_response_fifo.pop_front();
+ m_core[cid]->accept_fetch_response(mf);
+ }
+ } else {
+ // data response
+ if( !m_core[cid]->ldst_unit_response_buffer_full() ) {
+ m_response_fifo.pop_front();
+ m_core[cid]->accept_ldst_unit_response(mf);
+ }
+ }
+ }
+ if( m_response_fifo.size() < m_config->n_simt_ejection_buffer_size ) {
+ mem_fetch *mf = (mem_fetch*) ::icnt_pop(m_cluster_id);
+ if (!mf)
+ return;
+ assert(mf->get_tpc() == m_cluster_id);
+ assert(mf->get_type() == REPLY_DATA);
+ mf->set_status(IN_CLUSTER2SHADER,MR_2SH_FQ_POP,gpu_sim_cycle+gpu_tot_sim_cycle);
+ //m_memory_stats->memlatstat_read_done(mf,m_shader_config->max_warps_per_shader);
+ m_response_fifo.push_back(mf);
+ }
+}
+
+void simt_core_cluster::mem_instruction_stats(class warp_inst_t &inst)
+{
+ m_gpu->mem_instruction_stats(inst);
+}
+
+void simt_core_cluster::get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc )
+{
+ unsigned cid = sid_to_cid(sid);
+ m_core[cid]->get_pdom_stack_top_info(tid,pc,rpc);
+}
+
+void simt_core_cluster::display_pipeline( unsigned sid, FILE *fout, int print_mem, int mask )
+{
+ m_core[sid_to_cid(sid)]->display_pipeline(fout,print_mem,mask);
+}
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index d6ef552..b516495 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -171,7 +171,7 @@ public:
unsigned get_n_atomic() const { return m_n_atomic; }
void inc_n_atomic() { m_n_atomic++; }
- void dec_n_atomic() { m_n_atomic--; }
+ void dec_n_atomic(unsigned n) { m_n_atomic-=n; }
void set_membar() { m_membar=true; }
void clear_membar() { m_membar=false; }
@@ -209,16 +209,11 @@ public:
m_ibuffer[m_next].m_inst = NULL;
m_ibuffer[m_next].m_valid = false;
}
- void ibuffer_step()
- {
- m_next = (m_next+1)%IBUFFER_SIZE;
- }
- bool imiss_pending() const { return m_imiss_pending!=NULL; }
- void set_imiss_pending( class mshr_entry *mshr )
- {
- m_imiss_pending=mshr;
- }
- void clear_imiss_pending() { m_imiss_pending=NULL; }
+ void ibuffer_step() { m_next = (m_next+1)%IBUFFER_SIZE; }
+
+ bool imiss_pending() const { return m_imiss_pending; }
+ void set_imiss_pending() { m_imiss_pending=true; }
+ void clear_imiss_pending() { m_imiss_pending=false; }
bool stores_done() const { return m_stores_outstanding == 0; }
void inc_store_req() { m_stores_outstanding++; }
@@ -229,13 +224,13 @@ public:
}
bool inst_in_pipeline() const { return m_inst_in_pipeline > 0; }
-
void inc_inst_in_pipeline() { m_inst_in_pipeline++; }
void dec_inst_in_pipeline()
{
assert( m_inst_in_pipeline > 0 );
m_inst_in_pipeline--;
}
+
unsigned get_cta_id() const { return m_cta_id; }
private:
@@ -248,7 +243,7 @@ private:
address_type m_next_pc;
unsigned n_completed; // number of threads in warp completed
- class mshr_entry *m_imiss_pending;
+ bool m_imiss_pending;
struct ibuffer_entry {
ibuffer_entry() { m_valid = false; m_inst = NULL; }
@@ -308,34 +303,40 @@ class mshr_entry {
public:
mshr_entry()
{
- m_status = INVALID;
m_merged_requests=NULL;
m_mf=NULL;
m_id=0;
+ m_status = INITIALIZED;
+ m_isatomic=false;
}
void set_id( unsigned n ) { m_id = n; }
+ unsigned get_id() const { return m_id; }
void init( new_addr_type address, bool wr, memory_space_t space, unsigned warp_id );
void clear() { m_insts.clear(); }
void set_mf( class mem_fetch *mf ) { m_mf=mf; }
class mem_fetch *get_mf() { return m_mf; }
- void add_inst( warp_inst_t inst ) { m_insts.push_back(inst); }
- void set_status( enum mshr_status status );
+ void add_inst( warp_inst_t inst )
+ {
+ m_insts.push_back(inst);
+ m_isatomic = inst.isatomic();
+ }
void merge( mshr_entry *mshr )
{
//merge this request;
m_merged_requests = mshr;
mshr->m_merged_on_other_reqest = true;
}
- void do_atomic()
+ void set_fetched()
{
- for( std::vector<warp_inst_t>::iterator e=m_insts.begin(); e != m_insts.end(); ++e ) {
- warp_inst_t &inst = *e;
- inst.do_atomic();
+ mshr_entry *mshr = this;
+ while( mshr ) {
+ mshr->m_status=FETCHED;
+ mshr->m_mf=NULL;
+ mshr=mshr->m_merged_requests;
}
}
mshr_entry *get_last_merged()
{
- assert(m_status!=INVALID);
mshr_entry *mshr_hit = this;
while (mshr_hit->m_merged_requests)
mshr_hit = mshr_hit->m_merged_requests;
@@ -357,7 +358,7 @@ public:
unsigned get_warp_id() const { return m_warp_id; }
bool ismerged() const { return m_merged_on_other_reqest; }
- bool fetched() const { return m_status == FETCHED;};
+ bool fetched() const { return m_status==FETCHED;}
bool iswrite() const { return m_iswrite; }
bool isinst() const { return m_isinst; }
bool istexture() const { return m_istexture; }
@@ -367,17 +368,10 @@ public:
unsigned num_inst() const { return m_insts.size(); }
inst_t &get_inst(unsigned n)
{
- assert(m_status!=INVALID&&m_insts.size()>0);
+ assert(n<m_insts.size());
return m_insts[n];
}
- bool isatomic() const
- {
- assert(m_status!=INVALID);
- if( isinst() )
- return false;
- assert(m_insts.size()>0);
- return m_insts[0].isatomic();
- }
+ bool isatomic() const { return m_isatomic; }
new_addr_type get_addr() const { return m_addr; }
void print(FILE *fp) const;
@@ -390,13 +384,14 @@ private:
bool m_iswrite;
bool m_merged_on_other_reqest; //true if waiting for another mshr - this mshr doesn't send a memory request
struct mshr_entry *m_merged_requests; //mshrs waiting on this mshr
- enum mshr_status m_status;
class mem_fetch *m_mf; // link to corresponding memory fetch structure
+ enum mshr_status m_status;
bool m_isinst; //if it's a request from the instruction cache
bool m_istexture; //if it's a request from the texture cache
bool m_isconst; //if it's a request from the constant cache
bool m_islocal; //if it's a request to the local memory of a thread
bool m_wt_no_w2cache; //in write_through, sometimes need to prevent writing back returning data into cache, because its been written in the meantime.
+ bool m_isatomic;
};
const unsigned WARP_PER_CTA_MAX = 32;
@@ -822,7 +817,7 @@ public:
void pop_return_head();
mshr_entry* add_mshr(mem_access_t &access, warp_inst_t* inst);
- void mshr_return_from_mem(mshr_entry *mshr);
+ void mshr_return_from_mem(unsigned mshr_id);
unsigned get_max_mshr_used() const {return m_max_mshr_used;}
void print(FILE* fp);
@@ -872,9 +867,8 @@ struct ifetch_buffer_t {
class simd_function_unit {
public:
- simd_function_unit( warp_inst_t **result_port, const shader_core_config *config )
+ simd_function_unit( const shader_core_config *config )
{
- m_result_port = result_port;
m_config=config;
m_dispatch_reg = new warp_inst_t(config);
}
@@ -895,14 +889,13 @@ public:
protected:
std::string m_name;
const shader_core_config *m_config;
- warp_inst_t **m_result_port;
warp_inst_t *m_dispatch_reg;
};
-class alu : public simd_function_unit {
+class pipelined_simd_unit : public simd_function_unit {
public:
- alu( warp_inst_t **result_port, const shader_core_config *config, unsigned max_latency )
- : simd_function_unit(result_port,config)
+ pipelined_simd_unit( warp_inst_t **result_port, const shader_core_config *config, unsigned max_latency )
+ : simd_function_unit(config)
{
m_result_port = result_port;
m_pipeline_depth = max_latency;
@@ -946,16 +939,17 @@ public:
}
}
}
-private:
+protected:
unsigned m_pipeline_depth;
warp_inst_t **m_pipeline_reg;
+ warp_inst_t **m_result_port;
};
-class sfu : public alu
+class sfu : public pipelined_simd_unit
{
public:
sfu( warp_inst_t **result_port, const shader_core_config *config )
- : alu(result_port,config,config->max_sfu_latency) { m_name = "SFU"; }
+ : pipelined_simd_unit(result_port,config,config->max_sfu_latency) { m_name = "SFU"; }
virtual bool can_issue( const warp_inst_t &inst ) const
{
switch(inst.op) {
@@ -963,15 +957,15 @@ public:
case ALU_SFU_OP: break;
default: return false;
}
- return alu::can_issue(inst);
+ return pipelined_simd_unit::can_issue(inst);
}
};
-class sp_unit : public alu
+class sp_unit : public pipelined_simd_unit
{
public:
sp_unit( warp_inst_t **result_port, const shader_core_config *config )
- : alu(result_port,config,config->max_sp_latency) { m_name = "SP "; }
+ : pipelined_simd_unit(result_port,config,config->max_sp_latency) { m_name = "SP "; }
virtual bool can_issue( const warp_inst_t &inst ) const
{
switch(inst.op) {
@@ -981,15 +975,18 @@ public:
case MEMORY_BARRIER_OP: return false;
default: break;
}
- return alu::can_issue(inst);
+ return pipelined_simd_unit::can_issue(inst);
}
};
-class ldst_unit : public simd_function_unit {
+class simt_core_cluster;
+
+class ldst_unit: public pipelined_simd_unit {
public:
- ldst_unit( gpgpu_sim *gpu,
+ ldst_unit( simt_core_cluster *gpu,
shader_core_ctx *core,
- warp_inst_t **result_port,
+ opndcoll_rfu_t *operand_collector,
+ Scoreboard *scoreboard,
shader_core_config *config,
shader_core_stats *stats,
unsigned sid, unsigned tpc );
@@ -998,6 +995,7 @@ public:
virtual void cycle();
void fill( mem_fetch *mf );
void flush();
+ void writeback();
// accessors
virtual bool can_issue( const warp_inst_t &inst ) const
@@ -1011,6 +1009,7 @@ public:
return simd_function_unit::can_issue(inst);
}
virtual bool stallable() const { return true; }
+ bool response_buffer_full() const;
void print(FILE *fout) const;
private:
@@ -1035,8 +1034,8 @@ private:
warp_inst_t &inst );
mem_stage_stall_type send_mem_request(warp_inst_t &inst, mem_access_t &access);
- gpgpu_sim *m_gpu;
- shader_core_ctx *m_core;
+ class simt_core_cluster *m_cluster;
+ class shader_core_ctx *m_core;
unsigned m_sid;
unsigned m_tpc;
@@ -1044,6 +1043,10 @@ private:
cache_t *m_L1T; // texture cache
cache_t *m_L1C; // constant cache
mshr_shader_unit *m_mshr_unit;
+ std::map<unsigned/*warp_id*/, std::map<unsigned/*regnum*/,unsigned/*count*/> > m_pending_writes;
+ std::list<mem_fetch*> m_response_fifo;
+ opndcoll_rfu_t *m_operand_collector;
+ Scoreboard *m_scoreboard;
enum mem_stage_stall_type m_mem_rc;
@@ -1065,7 +1068,7 @@ class shader_core_ctx : public core_t
{
public:
shader_core_ctx( class gpgpu_sim *gpu,
- const char *name,
+ class simt_core_cluster *cluster,
unsigned shader_id,
unsigned tpc_id,
struct shader_core_config *config,
@@ -1085,7 +1088,7 @@ public:
bool warp_waiting_at_mem_barrier( unsigned warp_id );
void allocate_barrier( unsigned cta_id, warp_set_t warps );
void deallocate_barrier( unsigned cta_id );
- void decrement_atomic_count( unsigned wid );
+ void decrement_atomic_count( unsigned wid, unsigned n );
void cycle();
@@ -1097,10 +1100,12 @@ public:
void display_pdom_state(FILE *fout, int mask );
void display_pipeline( FILE *fout, int print_mem, int mask3bit );
void register_cta_thread_exit(int cta_num );
- void fill_shd_L1_with_new_line( class mem_fetch * mf );
+ bool fetch_unit_response_buffer_full() const;
+ void accept_fetch_response( mem_fetch *mf );
+ bool ldst_unit_response_buffer_full();
+ void accept_ldst_unit_response( class mem_fetch * mf );
void store_ack( class mem_fetch *mf );
void dump_istream_state( FILE *fout );
- unsigned first_valid_thread( unsigned stage );
class ptx_thread_info* get_functional_thread( unsigned tid ) { return m_thread[tid].m_functional_model_thread_state; }
std::list<unsigned> get_regs_written( const inst_t &fvt ) const;
const shader_core_config *get_config() const { return m_config; }
@@ -1114,11 +1119,10 @@ public:
unsigned get_thread_n_l1_access_ac( unsigned tid ) const { return m_thread[tid].n_l1_access_ac; }
unsigned get_n_active_cta() const { return m_n_active_cta; }
void inc_store_req( unsigned warp_id) { m_warp[warp_id].inc_store_req(); }
+ void dec_inst_in_pipeline( unsigned warp_id ) { m_warp[warp_id].dec_inst_in_pipeline(); }
private:
- void clear_stage_reg(int stage);
-
address_type next_pc( int tid ) const;
void fetch();
@@ -1132,15 +1136,13 @@ private:
void writeback();
- void call_thread_done(inst_t &done_inst );
-
void print_stage(unsigned int stage, FILE *fout) const;
// general information
unsigned m_sid; // shader id
unsigned m_tpc; // texture processor cluster id (aka, node id when using interconnect concentration)
- const char *m_name;
const shader_core_config *m_config;
+ class simt_core_cluster *m_cluster;
class gpgpu_sim *m_gpu;
// statistics
@@ -1180,4 +1182,46 @@ private:
std::bitset<MAX_ALU_LATENCY> m_result_bus;
};
+class simt_core_cluster {
+public:
+ simt_core_cluster( class gpgpu_sim *gpu,
+ unsigned cluster_id,
+ struct shader_core_config *config,
+ struct shader_core_stats *stats );
+
+ void core_cycle();
+ void icnt_cycle();
+
+ void reinit();
+ unsigned max_cta( class function_info *kernel );
+ int get_not_completed() const;
+ unsigned get_n_active_cta() const;
+ void issue_block2core( class kernel_info_t &kernel );
+ void cache_flush();
+
+ bool icnt_injection_buffer_full(new_addr_type addr, int bsize, bool write );
+ void icnt_inject_request_packet(class mem_fetch *mf);
+ bool icnt_ejection_buffer_full() const { return m_response_fifo.size() >= m_config->n_simt_ejection_buffer_size; }
+ void icnt_eject_response_packet(class mem_fetch * mf);
+ void mem_instruction_stats(class warp_inst_t &inst);
+ void get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc );
+
+ gpgpu_sim *get_gpu() { return m_gpu; }
+
+ void display_pipeline( unsigned sid, FILE *fout, int print_mem, int mask );
+
+private:
+ unsigned sid_to_cid( unsigned sid ) { return sid % m_config->n_simt_cores_per_cluster; }
+ unsigned cid_to_sid( unsigned cid ) { return m_cluster_id*m_config->n_simt_cores_per_cluster + cid; }
+
+ unsigned m_cluster_id;
+ gpgpu_sim *m_gpu;
+ const shader_core_config *m_config;
+ shader_core_stats *m_stats;
+ shader_core_ctx **m_core;
+
+ unsigned m_cta_issue_next_core;
+ std::list<mem_fetch*> m_response_fifo;
+};
+
#endif /* SHADER_H */
diff --git a/src/gpgpu-sim/stats.h b/src/gpgpu-sim/stats.h
index 2c494eb..20acfa1 100644
--- a/src/gpgpu-sim/stats.h
+++ b/src/gpgpu-sim/stats.h
@@ -120,7 +120,6 @@ struct shader_core_stats
unsigned int gpu_stall_by_MSHRwb;
unsigned int gpu_stall_shd_mem;
unsigned int gpu_stall_sh2icnt;
- unsigned int *max_return_queue_length;
//memory access classification
int gpgpu_n_mem_read_local;
diff --git a/src/gpgpu-sim/visualizer.cc b/src/gpgpu-sim/visualizer.cc
index 4474dcd..15dc157 100644
--- a/src/gpgpu-sim/visualizer.cc
+++ b/src/gpgpu-sim/visualizer.cc
@@ -126,6 +126,7 @@ void gpgpu_sim::visualizer_printstat()
gzsetparams(visualizer_file, g_visualizer_zlevel, Z_DEFAULT_STRATEGY);
visualizer_first_printstat = false;
+ /*
// instruction count per shader core
gzprintf(visualizer_file, "shaderinsncount: ");
for (unsigned i=0;i<m_n_shader;i++)
@@ -137,6 +138,7 @@ void gpgpu_sim::visualizer_printstat()
for (unsigned i=0;i<m_n_shader;i++)
gzprintf(visualizer_file, "%u ", m_sc[i]->get_n_diverge());
gzprintf(visualizer_file, "\n");
+ */
cflog_visualizer_gzprint(visualizer_file);
shader_CTA_count_visualizer_gzprint(visualizer_file);
@@ -172,7 +174,7 @@ void gpgpu_sim::visualizer_printstat()
m_sc[i]->new_cache_window();
*/
- for (unsigned i=0;i<m_n_mem;i++)
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++)
m_memory_partition_unit[i]->visualizer_print(visualizer_file);
// overall cache miss rates
@@ -208,7 +210,7 @@ void gpgpu_sim::visualizer_printstat()
time_vector_print_interval2gzfile(visualizer_file);
gzprintf(visualizer_file, "WarpDivergenceBreakdown:");
unsigned int total=0;
- unsigned int cf = (m_shader_config->gpgpu_warpdistro_shader==-1)?m_n_shader:1;
+ unsigned int cf = (m_shader_config->gpgpu_warpdistro_shader==-1)?num_shader():1;
gzprintf(visualizer_file, " %d", (m_shader_stats->shader_cycle_distro[0] - last_shader_cycle_distro[0]) / cf );
gzprintf(visualizer_file, " %d", (m_shader_stats->shader_cycle_distro[2] - last_shader_cycle_distro[2]) / cf );
for (unsigned i=0; i<m_shader_config->warp_size+3; i++) {
diff --git a/src/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc
index 6f13cd2..f6dea90 100644
--- a/src/gpgpusim_entrypoint.cc
+++ b/src/gpgpusim_entrypoint.cc
@@ -95,9 +95,7 @@ void *gpgpu_sim_thread(void*)
{
do {
sem_wait(&g_sim_signal_start);
- unsigned grid;
- class function_info *entry;
- g_the_gpu.next_grid(grid,entry);
+ g_the_gpu.next_grid();
g_the_gpu.run_gpu_sim();
print_simulation_time();
sem_post(&g_sim_signal_finish);
diff --git a/src/intersim/interconnect_interface.cpp b/src/intersim/interconnect_interface.cpp
index 0ed7150..5d3d55c 100644
--- a/src/intersim/interconnect_interface.cpp
+++ b/src/intersim/interconnect_interface.cpp
@@ -67,6 +67,18 @@ public:
}
return data;
}
+ void * top_packet(){
+ assert (packet_n);
+ void * data = NULL;
+ void * temp_d = buf.front();
+ while (data==NULL) {
+ if (tail_flag.front()) {
+ data = buf.front();
+ }
+ assert(temp_d == buf.front()); //all flits must belong to the same packet
+ }
+ return data;
+ }
void push_flit_data(void* data,bool is_tail) {
buf.push(data);
tail_flag.push(is_tail);
@@ -130,17 +142,19 @@ void map_gen(int dim,int memcount, int memnodes[])
assert(k==dim*dim);
}
-void display_map(int dim,int count){
+void display_map(int dim,int count)
+{
+ printf("GPGPU-Sim uArch: ");
int i=0;
for (i=0;i<count;i++) {
- printf("%d ",node_map[i]);
- if (i%dim ==0) {
- printf("\n");
- }
+ printf("%3d ",node_map[i]);
+ if (i%dim ==0)
+ printf("\nGPGPU-Sim uArch: ");
}
}
-void create_node_map(int n_shader, int n_mem, int size, int use_map) {
+void create_node_map(int n_shader, int n_mem, int size, int use_map)
+{
node_map = (int*)malloc((size)*sizeof(int));
if (use_map) {
switch (size) {
@@ -216,7 +230,7 @@ void create_node_map(int n_shader, int n_mem, int size, int use_map) {
}
}
}
- printf("nodemap\n");
+ printf("GPGPU-Sim uArch: interconnect nodemap\n");
display_map((int) sqrt(size),size);
}
@@ -287,18 +301,18 @@ void icnt_init_grid (){
}
}
-int interconnect_has_buffer(unsigned int input_node, unsigned int tot_req_size)
+bool interconnect_has_buffer(unsigned int input_node, unsigned int tot_req_size)
{
unsigned int input = node_map[input_node];
- int has_buffer;
+ bool has_buffer = false;
unsigned int n_flits = tot_req_size / _flit_size + ((tot_req_size % _flit_size)? 1:0);
if (!(fixed_lat_icnt || perfect_icnt)) {
has_buffer = (traffic[0]->_partial_packets[input][0].size() + n_flits) <= input_buffer_capacity;
if ((net_c>1) && is_mem(input))
has_buffer = (traffic[1]->_partial_packets[input][0].size() + n_flits) <= input_buffer_capacity;
} else {
- has_buffer = 1;
+ has_buffer = true;
}
return has_buffer;
}
@@ -554,6 +568,7 @@ void time_vector_update(unsigned int uid, int slot , long int cycle, int type);
void time_vector_update_icnt_injected(void* data, int input)
{
+ /*
mem_fetch* mf = (mem_fetch*) data;
if( mf->get_mshr() && !mf->get_mshr()->isinst() ) {
unsigned uid=mf->get_request_uid();
@@ -565,4 +580,5 @@ void time_vector_update_icnt_injected(void* data, int input)
time_vector_update( uid, MR_ICNT_INJECTED, cycle,req_type );
}
}
+ */
}
diff --git a/src/intersim/interconnect_interface.h b/src/intersim/interconnect_interface.h
index 3e3826d..9003fc6 100644
--- a/src/intersim/interconnect_interface.h
+++ b/src/intersim/interconnect_interface.h
@@ -13,7 +13,7 @@ struct glue_buf {
};
//node side functions
-int interconnect_has_buffer(unsigned int input, unsigned int size);
+bool interconnect_has_buffer(unsigned int input, unsigned int size);
void interconnect_push ( unsigned int input, unsigned int output,
void* data, unsigned int size);
void* interconnect_pop(unsigned int output);