summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/gpu-sim.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim/gpu-sim.cc')
-rw-r--r--src/gpgpu-sim/gpu-sim.cc125
1 files changed, 106 insertions, 19 deletions
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index 63ba759..a8be4d2 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -150,6 +150,8 @@ void power_config::reg_options(class OptionParser * opp)
void memory_config::reg_options(class OptionParser * opp)
{
+ option_parser_register(opp, "-perf_sim_memcpy", OPT_BOOL, &m_perf_sim_memcpy,
+ "Fill the L2 cache on memcpy", "1");
option_parser_register(opp, "-gpgpu_dram_scheduler", OPT_INT32, &scheduler_type,
"0 = fifo, 1 = FR-FCFS (defaul)", "1");
option_parser_register(opp, "-gpgpu_dram_partition_queues", OPT_CSTR, &gpgpu_L2_queue_config,
@@ -202,7 +204,27 @@ void memory_config::reg_options(class OptionParser * opp)
option_parser_register(opp, "-dram_latency", OPT_UINT32, &dram_latency,
"DRAM latency (default 30)",
"30");
-
+ option_parser_register(opp, "-dual_bus_interface", OPT_UINT32, &dual_bus_interface,
+ "dual_bus_interface (default = 0) ",
+ "0");
+ option_parser_register(opp, "-dram_bnk_indexing_policy", OPT_UINT32, &dram_bnk_indexing_policy,
+ "dram_bnk_indexing_policy (0 = normal indexing, 1 = Xoring with the higher bits) (Default = 0)",
+ "0");
+ option_parser_register(opp, "-dram_bnkgrp_indexing_policy", OPT_UINT32, &dram_bnkgrp_indexing_policy,
+ "dram_bnkgrp_indexing_policy (0 = take higher bits, 1 = take lower bits) (Default = 0)",
+ "0");
+ option_parser_register(opp, "-Seperate_Write_Queue_Enable", OPT_BOOL, &seperate_write_queue_enabled,
+ "Seperate_Write_Queue_Enable",
+ "0");
+ option_parser_register(opp, "-Write_Queue_Size", OPT_CSTR, &write_queue_size_opt,
+ "Write_Queue_Size",
+ "32:28:16");
+ option_parser_register(opp, "-Elimnate_rw_turnaround", OPT_BOOL, &elimnate_rw_turnaround,
+ "elimnate_rw_turnaround i.e set tWTR and tRTW = 0",
+ "0");
+ option_parser_register(opp, "-icnt_flit_size", OPT_UINT32, &icnt_flit_size,
+ "icnt_flit_size",
+ "32");
m_address_mapping.addrdec_setoption(opp);
}
@@ -229,6 +251,12 @@ void shader_core_config::reg_options(class OptionParser * opp)
"per-shader L1 data cache config "
" {<nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>,<mshr>:<N>:<merge>,<mq> | none}",
"none" );
+ option_parser_register(opp, "-l1_latency", OPT_UINT32, &m_L1D_config.l1_latency,
+ "L1 Hit Latency",
+ "0");
+ option_parser_register(opp, "-smem_latency", OPT_UINT32, &smem_latency,
+ "smem Latency",
+ "3");
option_parser_register(opp, "-gpgpu_cache:dl1PrefL1", OPT_CSTR, &m_L1D_config.m_config_stringPrefL1,
"per-shader L1 data cache config "
" {<nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>,<mshr>:<N>:<merge>,<mq> | none}",
@@ -256,6 +284,9 @@ void shader_core_config::reg_options(class OptionParser * opp)
option_parser_register(opp, "-gpgpu_shader_registers", OPT_UINT32, &gpgpu_shader_registers,
"Number of registers per shader core. Limits number of concurrent CTAs. (default 8192)",
"8192");
+ option_parser_register(opp, "-gpgpu_ignore_resources_limitation", OPT_BOOL, &gpgpu_ignore_resources_limitation,
+ "gpgpu_ignore_resources_limitation (default 0)",
+ "0");
option_parser_register(opp, "-gpgpu_shader_cta", OPT_UINT32, &max_cta_per_core,
"Maximum number of concurrent CTAs in shader (default 8)",
"8");
@@ -277,6 +308,9 @@ void shader_core_config::reg_options(class OptionParser * opp)
option_parser_register(opp, "-gpgpu_shmem_size", OPT_UINT32, &gpgpu_shmem_size,
"Size of shared memory per shader core (default 16kB)",
"16384");
+ option_parser_register(opp, "-adpative_volta_cache_config", OPT_BOOL, &adpative_volta_cache_config,
+ "adpative_volta_cache_config",
+ "0");
option_parser_register(opp, "-gpgpu_shmem_size", OPT_UINT32, &gpgpu_shmem_sizeDefault,
"Size of shared memory per shader core (default 16kB)",
"16384");
@@ -295,6 +329,9 @@ void shader_core_config::reg_options(class OptionParser * opp)
option_parser_register(opp, "-gpgpu_shmem_warp_parts", OPT_INT32, &mem_warp_parts,
"Number of portions a warp is divided into for shared memory bank conflict check ",
"2");
+ option_parser_register(opp, "-gpgpu_shmem_warp_parts", OPT_INT32, &mem_warp_parts,
+ "Number of portions a warp is divided into for shared memory bank conflict check ",
+ "2");
option_parser_register(opp, "-gpgpu_warpdistro_shader", OPT_INT32, &gpgpu_warpdistro_shader,
"Specify which shader core to collect the warp size distribution from",
"-1");
@@ -303,7 +340,7 @@ void shader_core_config::reg_options(class OptionParser * opp)
"0");
option_parser_register(opp, "-gpgpu_local_mem_map", OPT_BOOL, &gpgpu_local_mem_map,
"Mapping from local memory space address to simulated GPU physical address space (default = enabled)",
- "1");
+ "1");
option_parser_register(opp, "-gpgpu_num_reg_banks", OPT_INT32, &gpgpu_num_reg_banks,
"Number of register banks (default = 8)",
"8");
@@ -313,6 +350,9 @@ void shader_core_config::reg_options(class OptionParser * opp)
option_parser_register(opp, "-gpgpu_operand_collector_num_units_sp", OPT_INT32, &gpgpu_operand_collector_num_units_sp,
"number of collector units (default = 4)",
"4");
+ option_parser_register(opp, "-gpgpu_operand_collector_num_units_dp", OPT_INT32, &gpgpu_operand_collector_num_units_dp,
+ "number of collector units (default = 0)",
+ "0");
option_parser_register(opp, "-gpgpu_operand_collector_num_units_sfu", OPT_INT32, &gpgpu_operand_collector_num_units_sfu,
"number of collector units (default = 4)",
"4");
@@ -328,6 +368,9 @@ void shader_core_config::reg_options(class OptionParser * opp)
option_parser_register(opp, "-gpgpu_operand_collector_num_in_ports_sp", OPT_INT32, &gpgpu_operand_collector_num_in_ports_sp,
"number of collector unit in ports (default = 1)",
"1");
+ option_parser_register(opp, "-gpgpu_operand_collector_num_in_ports_dp", OPT_INT32, &gpgpu_operand_collector_num_in_ports_dp,
+ "number of collector unit in ports (default = 0)",
+ "0");
option_parser_register(opp, "-gpgpu_operand_collector_num_in_ports_sfu", OPT_INT32, &gpgpu_operand_collector_num_in_ports_sfu,
"number of collector unit in ports (default = 1)",
"1");
@@ -343,6 +386,9 @@ void shader_core_config::reg_options(class OptionParser * opp)
option_parser_register(opp, "-gpgpu_operand_collector_num_out_ports_sp", OPT_INT32, &gpgpu_operand_collector_num_out_ports_sp,
"number of collector unit in ports (default = 1)",
"1");
+ option_parser_register(opp, "-gpgpu_operand_collector_num_out_ports_dp", OPT_INT32, &gpgpu_operand_collector_num_out_ports_dp,
+ "number of collector unit in ports (default = 0)",
+ "0");
option_parser_register(opp, "-gpgpu_operand_collector_num_out_ports_sfu", OPT_INT32, &gpgpu_operand_collector_num_out_ports_sfu,
"number of collector unit in ports (default = 1)",
"1");
@@ -356,27 +402,33 @@ void shader_core_config::reg_options(class OptionParser * opp)
"number of collector unit in ports (default = 0)",
"0");
option_parser_register(opp, "-gpgpu_coalesce_arch", OPT_INT32, &gpgpu_coalesce_arch,
- "Coalescing arch (default = 13, anything else is off for now)",
+ "Coalescing arch (GT200 = 13, Fermi = 20)",
"13");
option_parser_register(opp, "-gpgpu_num_sched_per_core", OPT_INT32, &gpgpu_num_sched_per_core,
"Number of warp schedulers per core",
"1");
option_parser_register(opp, "-gpgpu_max_insn_issue_per_warp", OPT_INT32, &gpgpu_max_insn_issue_per_warp,
- "Max number of instructions that can be issued per warp in one cycle by scheduler",
- "2");
+ "Max number of instructions that can be issued per warp in one cycle by scheduler (either 1 or 2)",
+ "2");
+ option_parser_register(opp, "-gpgpu_dual_issue_diff_exec_units", OPT_BOOL, &gpgpu_dual_issue_diff_exec_units,
+ "should dual issue use two different execution unit resources (Default = 1)",
+ "1");
option_parser_register(opp, "-gpgpu_simt_core_sim_order", OPT_INT32, &simt_core_sim_order,
"Select the simulation order of cores in a cluster (0=Fix, 1=Round-Robin)",
"1");
option_parser_register(opp, "-gpgpu_pipeline_widths", OPT_CSTR, &pipeline_widths_string,
"Pipeline widths "
- "ID_OC_SP,ID_OC_SFU,ID_OC_TENSOR_CORE,ID_OC_MEM,OC_EX_SP,OC_EX_SFU,OC_EX_TENSOR_CORE,OC_EX_MEM,EX_WB",
- "1,1,1,1,1,1,1,1,1,1" );
+ "ID_OC_SP,ID_OC_DP,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_SFU,OC_EX_MEM,EX_WB,ID_OC_TENSOR_CORE,OC_EX_TENSOR_CORE",
+ "1,1,1,1,1,1,1,1,1,1,1" );
option_parser_register(opp, "-gpgpu_tensor_core_avail", OPT_INT32, &gpgpu_tensor_core_avail,
"Tensor Core Available (default=0)",
"0");
option_parser_register(opp, "-gpgpu_num_sp_units", OPT_INT32, &gpgpu_num_sp_units,
"Number of SP units (default=1)",
"1");
+ option_parser_register(opp, "-gpgpu_num_dp_units", OPT_INT32, &gpgpu_num_dp_units,
+ "Number of DP units (default=0)",
+ "0");
option_parser_register(opp, "-gpgpu_num_sfu_units", OPT_INT32, &gpgpu_num_sfu_units,
"Number of SF units (default=1)",
"1");
@@ -425,7 +477,6 @@ void gpgpu_sim_config::reg_options(option_parser_t opp)
option_parser_register(opp, "-gpgpu_flush_l2_cache", OPT_BOOL, &gpgpu_flush_l2_cache,
"Flush L2 cache at the end of each kernel call",
"0");
-
option_parser_register(opp, "-gpgpu_deadlock_detect", OPT_BOOL, &gpu_deadlock_detect,
"Stop the simulation at deadlock (1=on (default), 0=off)",
"1");
@@ -669,7 +720,7 @@ gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config )
m_running_kernels.resize( config.max_concurrent_kernel, NULL );
m_last_issued_kernel = 0;
- m_last_cluster_issue = 0;
+ m_last_cluster_issue = m_shader_config->n_simt_clusters-1; // this causes first launch to use simt cluster 0
*average_pipeline_duty_cycle=0;
*active_sms=0;
@@ -813,6 +864,7 @@ void gpgpu_sim::update_stats() {
partiton_replys_in_parallel_total += partiton_replys_in_parallel;
partiton_reqs_in_parallel_util_total += partiton_reqs_in_parallel_util;
gpu_tot_sim_cycle_parition_util += gpu_sim_cycle_parition_util ;
+ gpu_tot_occupancy += gpu_occupancy;
gpu_sim_cycle = 0;
partiton_reqs_in_parallel = 0;
@@ -821,6 +873,7 @@ void gpgpu_sim::update_stats() {
gpu_sim_cycle_parition_util = 0;
gpu_sim_insn = 0;
m_total_cta_launched = 0;
+ gpu_occupancy = occupancy_stats();
}
void gpgpu_sim::print_stats()
@@ -994,6 +1047,9 @@ void gpgpu_sim::gpu_print_stat()
printf("gpu_tot_sim_insn = %lld\n", gpu_tot_sim_insn+gpu_sim_insn);
printf("gpu_tot_ipc = %12.4f\n", (float)(gpu_tot_sim_insn+gpu_sim_insn) / (gpu_tot_sim_cycle+gpu_sim_cycle));
printf("gpu_tot_issued_cta = %lld\n", gpu_tot_issued_cta + m_total_cta_launched);
+ printf("gpu_occupancy = %.4f\% \n", gpu_occupancy.get_occ_fraction() * 100);
+ printf("gpu_tot_occupancy = %.4f\% \n", (gpu_occupancy + gpu_tot_occupancy).get_occ_fraction() * 100);
+
extern unsigned long long g_max_total_param_size;
fprintf(statfout, "max_total_param_size = %llu\n", g_max_total_param_size);
@@ -1032,6 +1088,8 @@ void gpgpu_sim::gpu_print_stat()
}
printf("\nTotal_core_cache_stats:\n");
core_cache_stats.print_stats(stdout, "Total_core_cache_stats_breakdown");
+ printf("\nTotal_core_cache_fail_stats:\n");
+ core_cache_stats.print_fail_stats(stdout, "Total_core_cache_fail_stats_breakdown");
shader_print_scheduler_stat( stdout, false );
m_shader_stats->print(stdout);
@@ -1076,6 +1134,8 @@ void gpgpu_sim::gpu_print_stat()
printf("L2_total_cache_reservation_fails = %u\n", total_l2_css.res_fails);
printf("L2_total_cache_breakdown:\n");
l2_stats.print_stats(stdout, "L2_cache_stats_breakdown");
+ printf("L2_total_cache_reservation_fail_breakdown:\n");
+ l2_stats.print_fail_stats(stdout, "L2_cache_stats_fail_breakdown");
total_l2_css.print_port_stats(stdout, "L2_cache");
}
}
@@ -1429,7 +1489,7 @@ void gpgpu_sim::cycle()
if (mf) {
unsigned response_size = mf->get_is_write()?mf->get_ctrl_size():mf->size();
if ( ::icnt_has_buffer( m_shader_config->mem2device(i), response_size ) ) {
- if (!mf->get_is_write())
+ //if (!mf->get_is_write())
mf->set_return_timestamp(gpu_sim_cycle+gpu_tot_sim_cycle);
mf->set_status(IN_ICNT_TO_SHADER,gpu_sim_cycle+gpu_tot_sim_cycle);
::icnt_push( m_shader_config->mem2device(i), mf->get_tpc(), mf, response_size );
@@ -1462,12 +1522,14 @@ void gpgpu_sim::cycle()
for (unsigned i=0;i<m_memory_config->m_n_mem_sub_partition;i++) {
//move memory request from interconnect into memory partition (if not backed up)
//Note:This needs to be called in DRAM clock domain if there is no L2 cache in the system
- if ( m_memory_sub_partition[i]->full() ) {
+ //In the worst case, we may need to push SECTOR_CHUNCK_SIZE requests, so ensure you have enough buffer for them
+ if ( m_memory_sub_partition[i]->full(SECTOR_CHUNCK_SIZE) ) {
gpu_stall_dramfull++;
} else {
mem_fetch* mf = (mem_fetch*) icnt_pop( m_shader_config->mem2device(i) );
m_memory_sub_partition[i]->push( mf, gpu_sim_cycle + gpu_tot_sim_cycle );
- partiton_reqs_in_parallel_per_cycle++;
+ if(mf)
+ partiton_reqs_in_parallel_per_cycle++;
}
m_memory_sub_partition[i]->cache_cycle(gpu_sim_cycle+gpu_tot_sim_cycle);
m_memory_sub_partition[i]->accumulate_L2cache_stats(m_power_stats->pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX]);
@@ -1494,6 +1556,8 @@ void gpgpu_sim::cycle()
// Update core icnt/cache stats for GPUWattch
m_cluster[i]->get_icnt_stats(m_power_stats->pwr_mem_stat->n_simt_to_mem[CURRENT_STAT_IDX][i], m_power_stats->pwr_mem_stat->n_mem_to_simt[CURRENT_STAT_IDX][i]);
m_cluster[i]->get_cache_stats(m_power_stats->pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX]);
+ m_cluster[i]->get_current_occupancy(gpu_occupancy.aggregate_warp_slot_filled, gpu_occupancy.aggregate_theoretical_warp_slots);
+
}
float temp=0;
for (unsigned i=0;i<m_shader_config->num_shader();i++){
@@ -1521,12 +1585,12 @@ void gpgpu_sim::cycle()
issue_block2core();
- // Depending on configuration, flush the caches once all of threads are completed.
+ // Depending on configuration, invalidate the caches once all of threads are completed.
int all_threads_complete = 1;
if (m_config.gpgpu_flush_l1_cache) {
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();
+ m_cluster[i]->cache_invalidate();
else
all_threads_complete = 0 ;
}
@@ -1548,7 +1612,7 @@ void gpgpu_sim::cycle()
int dlc = 0;
for (unsigned i=0;i<m_memory_config->m_n_mem;i++) {
dlc = m_memory_sub_partition[i]->flushL2();
- assert (dlc == 0); // need to model actual writes to DRAM here
+ assert (dlc == 0); // TODO: need to model actual writes to DRAM here
printf("Dirty lines flushed from L2 %d is %d\n", i, dlc );
}
}
@@ -1560,15 +1624,20 @@ void gpgpu_sim::cycle()
time_t curr_time;
time(&curr_time);
unsigned long long elapsed_time = MAX(curr_time - g_simulation_starttime, 1);
- if ( (elapsed_time - last_liveness_message_time) >= m_config.liveness_message_freq ) {
+ if ( (elapsed_time - last_liveness_message_time) >= m_config.liveness_message_freq && DTRACE(LIVENESS) ) {
days = elapsed_time/(3600*24);
hrs = elapsed_time/3600 - 24*days;
minutes = elapsed_time/60 - 60*(hrs + 24*days);
sec = elapsed_time - 60*(minutes + 60*(hrs + 24*days));
-
- DPRINTF(LIVENESS, "GPGPU-Sim uArch: cycles simulated: %lld inst.: %lld (ipc=%4.1f) sim_rate=%u (inst/sec) elapsed = %u:%u:%02u:%02u / %s",
- gpu_tot_sim_cycle + gpu_sim_cycle, gpu_tot_sim_insn + gpu_sim_insn,
+
+ unsigned long long active = 0, total = 0;
+ for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) {
+ m_cluster[i]->get_current_occupancy(active, total);
+ }
+ DPRINTF(LIVENESS, "uArch: inst.: %lld (ipc=%4.1f, occ=%0.4f\% [%llu / %llu]) sim_rate=%u (inst/sec) elapsed = %u:%u:%02u:%02u / %s",
+ gpu_tot_sim_insn + gpu_sim_insn,
(double)gpu_sim_insn/(double)gpu_sim_cycle,
+ float(active)/float(total) * 100, active, total,
(unsigned)((gpu_tot_sim_insn+gpu_sim_insn) / elapsed_time),
(unsigned)days,(unsigned)hrs,(unsigned)minutes,(unsigned)sec,
ctime(&curr_time));
@@ -1620,6 +1689,24 @@ void shader_core_ctx::dump_warp_state( FILE *fout ) const
m_warp[w].print(fout);
}
+
+void gpgpu_sim::perf_memcpy_to_gpu( size_t dst_start_addr, size_t count )
+{
+ if (m_memory_config->m_perf_sim_memcpy) {
+ assert (dst_start_addr % 32 == 0);
+
+ for ( unsigned counter = 0; counter < count; counter += 32 ) {
+ const unsigned wr_addr = dst_start_addr + counter;
+ addrdec_t raw_addr;
+ mem_access_sector_mask_t mask;
+ mask.set(wr_addr % 128 / 32);
+ m_memory_config->m_address_mapping.addrdec_tlx( wr_addr, &raw_addr );
+ const unsigned partition_id = raw_addr.sub_partition / m_memory_config->m_n_sub_partition_per_memory_channel;
+ m_memory_partition_unit[ partition_id ]->handle_memcpy_to_gpu( wr_addr, raw_addr.sub_partition, mask );
+ }
+ }
+}
+
void gpgpu_sim::dump_pipeline( int mask, int s, int m ) const
{
/*