diff options
| -rw-r--r-- | CHANGES | 2 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 4 | ||||
| -rw-r--r-- | src/gpgpu-sim/power_interface.cc | 4 | ||||
| -rw-r--r-- | src/gpgpu-sim/power_interface.h | 4 | ||||
| -rw-r--r-- | src/gpuwattch/XML_Parse.h | 3 | ||||
| -rw-r--r-- | src/gpuwattch/gpgpu_sim_wrapper.cc | 311 | ||||
| -rw-r--r-- | src/gpuwattch/gpgpu_sim_wrapper.h | 55 |
7 files changed, 183 insertions, 200 deletions
@@ -1,7 +1,7 @@ LOG: Version 3.2.1+edits (development branch) versus 3.2.1 - Replaced legacy L2 cache access statistics with more meaningful breakdown. -- Added NVIDIA Quadro FX5600 GPGPU-Sim and Quadro configuration files. +- Added NVIDIA Quadro FX5600 GPGPU-Sim and GPUWattch configuration files. - Bug Fixes: - Fixed the flit count sent to GPUWattch for atomic operations. - Fix for Bug 51 - Updated the function declaration of diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index a8ebe5d..c38b133 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -889,8 +889,8 @@ void gpgpu_sim::gpu_print_stat() m_shader_stats->print(stdout); #ifdef GPGPUSIM_POWER_MODEL if(m_config.g_power_simulation_enabled){ - m_gpgpusim_wrapper->print_power_kernel_stats(gpu_sim_cycle, gpu_tot_sim_cycle, gpu_tot_sim_insn + gpu_sim_insn, kernel_info_str ); - mcpat_reset_perf_count(m_gpgpusim_wrapper, true); + m_gpgpusim_wrapper->print_power_kernel_stats(gpu_sim_cycle, gpu_tot_sim_cycle, gpu_tot_sim_insn + gpu_sim_insn, kernel_info_str, true ); + mcpat_reset_perf_count(m_gpgpusim_wrapper); } #endif diff --git a/src/gpgpu-sim/power_interface.cc b/src/gpgpu-sim/power_interface.cc index 7d87222..3861b6a 100644 --- a/src/gpgpu-sim/power_interface.cc +++ b/src/gpgpu-sim/power_interface.cc @@ -120,6 +120,6 @@ void mcpat_cycle(const gpgpu_sim_config &config, const struct shader_core_config //wrapper->close_files(); } -void mcpat_reset_perf_count(class gpgpu_sim_wrapper *wrapper, bool do_print){ - wrapper->reset_counters(do_print); +void mcpat_reset_perf_count(class gpgpu_sim_wrapper *wrapper){ + wrapper->reset_counters(); } diff --git a/src/gpgpu-sim/power_interface.h b/src/gpgpu-sim/power_interface.h index 3d04b7e..afac22b 100644 --- a/src/gpgpu-sim/power_interface.h +++ b/src/gpgpu-sim/power_interface.h @@ -37,7 +37,7 @@ void init_mcpat(const gpgpu_sim_config &config, class gpgpu_sim_wrapper *wrapper, unsigned stat_sample_freq, unsigned tot_inst, unsigned inst); void mcpat_cycle(const gpgpu_sim_config &config, const struct shader_core_config *shdr_config, class gpgpu_sim_wrapper *wrapper, class power_stat_t *power_stats, -unsigned stat_sample_freq, unsigned tot_cycle, unsigned cycle, unsigned tot_inst, unsigned inst); -void mcpat_reset_perf_count(class gpgpu_sim_wrapper *wrapper, bool do_print); + unsigned stat_sample_freq, unsigned tot_cycle, unsigned cycle, unsigned tot_inst, unsigned inst); +void mcpat_reset_perf_count(class gpgpu_sim_wrapper *wrapper); #endif /* POWER_INTERFACE_H_ */ diff --git a/src/gpuwattch/XML_Parse.h b/src/gpuwattch/XML_Parse.h index 698445e..d35ba26 100644 --- a/src/gpuwattch/XML_Parse.h +++ b/src/gpuwattch/XML_Parse.h @@ -96,7 +96,8 @@ enum perf_count_t { NOC_A,
PIPE_A,
IDLE_CORE_N,
- CONST_DYNAMICN
+ CONST_DYNAMICN,
+ NUM_PERFORMANCE_COUNTERS
};
typedef struct{
diff --git a/src/gpuwattch/gpgpu_sim_wrapper.cc b/src/gpuwattch/gpgpu_sim_wrapper.cc index 6a67b67..13c5b3e 100644 --- a/src/gpuwattch/gpgpu_sim_wrapper.cc +++ b/src/gpuwattch/gpgpu_sim_wrapper.cc @@ -29,9 +29,6 @@ #include <sys/stat.h> #define SP_BASE_POWER 0 #define SFU_BASE_POWER 0 -#define NUM_COMPONENTS_MODELLED 18 -#define NUM_PERFORMANCE_COUNTERS 30 - static const char * pwr_cmp_label[] = {"IBP,", "ICP,", "DCP,", "TCP,", "CCP,", "SHRDP,", "RFP,", "SPP,", @@ -56,34 +53,34 @@ enum pwr_cmp_t { DRAMP, PIPEP, IDLE_COREP, - CONST_DYNAMICP + CONST_DYNAMICP, + NUM_COMPONENTS_MODELLED }; gpgpu_sim_wrapper::gpgpu_sim_wrapper( bool power_simulation_enabled, char* xmlfile) { - count=0; - gcount=0; + kernel_sample_count=0; + total_sample_count=0; - gpu_avg_power=0; - gpu_tot_avg_power=0; - gpu_max_power=0; - gpu_tot_max_power=0; - gpu_min_power=0; - gpu_tot_min_power=0; + kernel_tot_power=0; num_pwr_cmps=NUM_COMPONENTS_MODELLED; - num_per_counts=NUM_PERFORMANCE_COUNTERS; - pavg=0; - perf_count=(double *)calloc(num_per_counts,sizeof(double)); - initpower_coeff=(double *)calloc(num_per_counts,sizeof(double)); - effpower_coeff=(double *)calloc(num_per_counts,sizeof(double)); - perf_count_avg=(double *)calloc(num_per_counts,sizeof(double)); - perf_count_min=(double *)calloc(num_per_counts,sizeof(double)); - perf_count_max=(double *)calloc(num_per_counts,sizeof(double)); - pwr_cmp=(double *)calloc(num_pwr_cmps,sizeof(double)); - pwr_cmp_avg=(double *)calloc(num_pwr_cmps,sizeof(double)); - pwr_cmp_min=(double *)calloc(num_pwr_cmps,sizeof(double)); - pwr_cmp_max=(double *)calloc(num_pwr_cmps,sizeof(double)); + num_perf_counters=NUM_PERFORMANCE_COUNTERS; + + // Initialize per-component counter/power vectors + avg_max_min_counters<double> init; + kernel_cmp_pwr.resize(NUM_COMPONENTS_MODELLED, init); + kernel_cmp_perf_counters.resize(NUM_PERFORMANCE_COUNTERS, init); + + kernel_power = init; // Per-kernel powers + gpu_tot_power = init; // Global powers + + sample_cmp_pwr.resize(NUM_COMPONENTS_MODELLED, 0); + + sample_perf_counters.resize(NUM_PERFORMANCE_COUNTERS, 0); + initpower_coeff.resize(NUM_PERFORMANCE_COUNTERS, 0); + effpower_coeff.resize(NUM_PERFORMANCE_COUNTERS, 0); + const_dynamic_power=0; proc_power=0; @@ -131,13 +128,7 @@ void gpgpu_sim_wrapper::init_mcpat(char* xmlfile, char* powerfilename, char* pow double steady_min_period, int zlevel, double init_val,int stat_sample_freq ){ // Write File Headers for (-metrics trace, -power trace) - count=0; - gpu_avg_power=0; - gpu_max_power=0; - - pavg=0; - gpu_min_power=0; - + reset_counters(); static bool mcpat_init=true; // initialize file name if it is not set @@ -190,7 +181,7 @@ void gpgpu_sim_wrapper::init_mcpat(char* xmlfile, char* powerfilename, char* pow gzprintf(power_trace_file,"\n"); gzsetparams(metric_trace_file, g_power_trace_zlevel, Z_DEFAULT_STRATEGY); - for(unsigned i=0; i<num_per_counts; i++){ + for(unsigned i=0; i<num_perf_counters; i++){ gzprintf(metric_trace_file,perf_count_label[i]); } gzprintf(metric_trace_file,"\n"); @@ -206,7 +197,7 @@ void gpgpu_sim_wrapper::init_mcpat(char* xmlfile, char* powerfilename, char* pow } gzsetparams(steady_state_tacking_file,g_power_trace_zlevel, Z_DEFAULT_STRATEGY); gzprintf(steady_state_tacking_file,"start,end,power,IPC,"); - for(unsigned i=0; i<num_per_counts; i++){ + for(unsigned i=0; i<num_perf_counters; i++){ gzprintf(steady_state_tacking_file,perf_count_label[i]); } gzprintf(steady_state_tacking_file,"\n"); @@ -225,43 +216,22 @@ void gpgpu_sim_wrapper::init_mcpat(char* xmlfile, char* powerfilename, char* pow } -void gpgpu_sim_wrapper::reset_counters(bool do_print){ - if(do_print) - print_trace_files(); +void gpgpu_sim_wrapper::reset_counters(){ - for(unsigned i=0; i<num_per_counts; ++i){ - perf_count[i] = 0; - } - for(unsigned i=0; i<num_pwr_cmps; ++i){ - pwr_cmp_avg[i]= 0; + avg_max_min_counters<double> init; + for(unsigned i=0; i<num_perf_counters; ++i){ + sample_perf_counters[i] = 0; + kernel_cmp_perf_counters[i] = init; } - for(unsigned i=0; i<num_pwr_cmps; ++i){ - pwr_cmp_max[i]= 0; - } - - for(unsigned i=0; i<num_pwr_cmps; ++i){ - pwr_cmp_min[i]= 0; - } - - for(unsigned i=0; i<num_per_counts; ++i){ - perf_count_avg[i]= 0; - } - - for(unsigned i=0; i<num_per_counts; ++i){ - perf_count_min[i]= 0; - } - - for(unsigned i=0; i<num_per_counts; ++i){ - perf_count_max[i]= 0; + sample_cmp_pwr[i] = 0; + kernel_cmp_pwr[i] = init; } // Reset per-kernel counters - count = 0; - gpu_avg_power = 0; - gpu_max_power = 0; - gpu_min_power = 0; - + kernel_sample_count = 0; + kernel_tot_power = 0; + kernel_power = init; return; } @@ -277,8 +247,8 @@ void gpgpu_sim_wrapper::set_inst_power(bool clk_gated_lanes, double tot_cycles, p->sys.core[0].load_instructions = load_inst; p->sys.core[0].store_instructions = store_inst; p->sys.core[0].committed_instructions = committed_inst; - perf_count[FP_INT]=int_inst+fp_inst; - perf_count[TOT_INST]=tot_inst; + sample_perf_counters[FP_INT]=int_inst+fp_inst; + sample_perf_counters[TOT_INST]=tot_inst; } void gpgpu_sim_wrapper::set_regfile_power(double reads, double writes,double ops) @@ -286,9 +256,9 @@ void gpgpu_sim_wrapper::set_regfile_power(double reads, double writes,double ops p->sys.core[0].int_regfile_reads = reads * p->sys.scaling_coefficients[REG_RD]; p->sys.core[0].int_regfile_writes = writes * p->sys.scaling_coefficients[REG_WR]; p->sys.core[0].non_rf_operands = ops *p->sys.scaling_coefficients[NON_REG_OPs]; - perf_count[REG_RD]=reads; - perf_count[REG_WR]=writes; - perf_count[NON_REG_OPs]=ops; + sample_perf_counters[REG_RD]=reads; + sample_perf_counters[REG_WR]=writes; + sample_perf_counters[NON_REG_OPs]=ops; @@ -298,8 +268,8 @@ void gpgpu_sim_wrapper::set_icache_power(double hits, double misses) { p->sys.core[0].icache.read_accesses = hits * p->sys.scaling_coefficients[IC_H]+misses * p->sys.scaling_coefficients[IC_M]; p->sys.core[0].icache.read_misses = misses * p->sys.scaling_coefficients[IC_M]; - perf_count[IC_H]=hits; - perf_count[IC_M]=misses; + sample_perf_counters[IC_H]=hits; + sample_perf_counters[IC_M]=misses; } @@ -308,8 +278,8 @@ void gpgpu_sim_wrapper::set_ccache_power(double hits, double misses) { p->sys.core[0].ccache.read_accesses = hits * p->sys.scaling_coefficients[CC_H]+misses * p->sys.scaling_coefficients[CC_M]; p->sys.core[0].ccache.read_misses = misses * p->sys.scaling_coefficients[CC_M]; - perf_count[CC_H]=hits; - perf_count[CC_M]=misses; + sample_perf_counters[CC_H]=hits; + sample_perf_counters[CC_M]=misses; // TODO: coalescing logic is counted as part of the caches power (this is not valid for no-caches architectures) } @@ -318,15 +288,15 @@ void gpgpu_sim_wrapper::set_tcache_power(double hits, double misses) { p->sys.core[0].tcache.read_accesses = hits * p->sys.scaling_coefficients[TC_H]+misses * p->sys.scaling_coefficients[TC_M]; p->sys.core[0].tcache.read_misses = misses* p->sys.scaling_coefficients[TC_M]; - perf_count[TC_H]=hits; - perf_count[TC_M]=misses; + sample_perf_counters[TC_H]=hits; + sample_perf_counters[TC_M]=misses; // TODO: coalescing logic is counted as part of the caches power (this is not valid for no-caches architectures) } void gpgpu_sim_wrapper::set_shrd_mem_power(double accesses) { p->sys.core[0].sharedmemory.read_accesses = accesses * p->sys.scaling_coefficients[SHRD_ACC]; - perf_count[SHRD_ACC]=accesses; + sample_perf_counters[SHRD_ACC]=accesses; } @@ -337,10 +307,10 @@ void gpgpu_sim_wrapper::set_l1cache_power(double read_hits, double read_misses, p->sys.core[0].dcache.read_misses = read_misses * p->sys.scaling_coefficients[DC_RM]; p->sys.core[0].dcache.write_accesses = write_hits * p->sys.scaling_coefficients[DC_WH]+write_misses * p->sys.scaling_coefficients[DC_WM]; p->sys.core[0].dcache.write_misses = write_misses * p->sys.scaling_coefficients[DC_WM]; - perf_count[DC_RH]=read_hits; - perf_count[DC_RM]=read_misses; - perf_count[DC_WH]=write_hits; - perf_count[DC_WM]=write_misses; + sample_perf_counters[DC_RH]=read_hits; + sample_perf_counters[DC_RM]=read_misses; + sample_perf_counters[DC_WH]=write_hits; + sample_perf_counters[DC_WM]=write_misses; // TODO: coalescing logic is counted as part of the caches power (this is not valid for no-caches architectures) @@ -356,22 +326,22 @@ void gpgpu_sim_wrapper::set_l2cache_power(double read_hits, double read_misses, p->sys.l2.read_misses = read_misses * p->sys.scaling_coefficients[L2_RM]; p->sys.l2.write_hits =write_hits * p->sys.scaling_coefficients[L2_WH]; p->sys.l2.write_misses = write_misses * p->sys.scaling_coefficients[L2_WM]; - perf_count[L2_RH]=read_hits; - perf_count[L2_RM]=read_misses; - perf_count[L2_WH]=write_hits; - perf_count[L2_WM]=write_misses; + sample_perf_counters[L2_RH]=read_hits; + sample_perf_counters[L2_RM]=read_misses; + sample_perf_counters[L2_WH]=write_hits; + sample_perf_counters[L2_WM]=write_misses; } void gpgpu_sim_wrapper::set_idle_core_power(double num_idle_core) { p->sys.num_idle_cores = num_idle_core; - perf_count[IDLE_CORE_N]=num_idle_core; + sample_perf_counters[IDLE_CORE_N]=num_idle_core; } void gpgpu_sim_wrapper::set_duty_cycle_power(double duty_cycle) { p->sys.core[0].pipeline_duty_cycle = duty_cycle * p->sys.scaling_coefficients[PIPE_A]; - perf_count[PIPE_A]=duty_cycle; + sample_perf_counters[PIPE_A]=duty_cycle; } @@ -381,9 +351,9 @@ void gpgpu_sim_wrapper::set_mem_ctrl_power(double reads, double writes, double d p->sys.mc.memory_reads = reads *p->sys.scaling_coefficients[MEM_RD]; p->sys.mc.memory_writes = writes*p->sys.scaling_coefficients[MEM_WR]; p->sys.mc.dram_pre = dram_precharge*p->sys.scaling_coefficients[MEM_PRE]; - perf_count[MEM_RD]=reads; - perf_count[MEM_WR]=writes; - perf_count[MEM_PRE]=dram_precharge; + sample_perf_counters[MEM_RD]=reads; + sample_perf_counters[MEM_WR]=writes; + sample_perf_counters[MEM_PRE]=dram_precharge; } @@ -395,9 +365,9 @@ void gpgpu_sim_wrapper::set_exec_unit_power(double fpu_accesses, double ialu_acc //Sfu accesses p->sys.core[0].mul_accesses = sfu_accesses*p->sys.scaling_coefficients[SFU_ACC]; - perf_count[SP_ACC]=ialu_accesses; - perf_count[SFU_ACC]=sfu_accesses; - perf_count[FPU_ACC]=fpu_accesses; + sample_perf_counters[SP_ACC]=ialu_accesses; + sample_perf_counters[SFU_ACC]=sfu_accesses; + sample_perf_counters[FPU_ACC]=fpu_accesses; } @@ -411,54 +381,56 @@ void gpgpu_sim_wrapper::set_active_lanes_power(double sp_avg_active_lane, double void gpgpu_sim_wrapper::set_NoC_power(double noc_tot_reads, double noc_tot_writes ) { p->sys.NoC[0].total_accesses = noc_tot_reads * p->sys.scaling_coefficients[NOC_A] + noc_tot_writes * p->sys.scaling_coefficients[NOC_A]; - perf_count[NOC_A]=noc_tot_reads+noc_tot_writes; + sample_perf_counters[NOC_A]=noc_tot_reads+noc_tot_writes; } void gpgpu_sim_wrapper::power_metrics_calculations() { - gcount++; - count++; + total_sample_count++; + kernel_sample_count++; - double total_power = proc->rt_power.readOp.dynamic + pwr_cmp[CONST_DYNAMICP]; + // Current sample power + double sample_power = proc->rt_power.readOp.dynamic + sample_cmp_pwr[CONST_DYNAMICP]; // Average power // Previous + new + constant dynamic power (e.g., dynamic clocking power) - gpu_avg_power += total_power; + kernel_tot_power += sample_power; + kernel_power.avg = kernel_tot_power / kernel_sample_count; for(unsigned ind=0; ind<num_pwr_cmps; ++ind){ - pwr_cmp_avg[ind] += (double)pwr_cmp[ind]; + kernel_cmp_pwr[ind].avg += (double)sample_cmp_pwr[ind]; } - for(unsigned ind=0; ind<num_per_counts; ++ind){ - perf_count_avg[ind] += (double)perf_count[ind]; + for(unsigned ind=0; ind<num_perf_counters; ++ind){ + kernel_cmp_perf_counters[ind].avg += (double)sample_perf_counters[ind]; } // Max Power - if(total_power > gpu_max_power){ - gpu_max_power = total_power; + if(sample_power > kernel_power.max){ + kernel_power.max = sample_power; for(unsigned ind=0; ind<num_pwr_cmps; ++ind){ - pwr_cmp_max[ind] = (double)pwr_cmp[ind]; + kernel_cmp_pwr[ind].max = (double)sample_cmp_pwr[ind]; } - for(unsigned ind=0; ind<num_per_counts; ++ind){ - perf_count_max[ind] = perf_count[ind]; + for(unsigned ind=0; ind<num_perf_counters; ++ind){ + kernel_cmp_perf_counters[ind].max = sample_perf_counters[ind]; } } // Min Power - if(total_power < gpu_min_power ||(gpu_min_power==0) ){ - gpu_min_power = total_power; + if(sample_power < kernel_power.min ||(kernel_power.min==0) ){ + kernel_power.min = sample_power; for(unsigned ind=0; ind<num_pwr_cmps; ++ind){ - pwr_cmp_min[ind] = (double)pwr_cmp[ind]; + kernel_cmp_pwr[ind].min = (double)sample_cmp_pwr[ind]; } - for(unsigned ind=0; ind<num_per_counts; ++ind){ - perf_count_min[ind] = perf_count[ind]; + for(unsigned ind=0; ind<num_perf_counters; ++ind){ + kernel_cmp_perf_counters[ind].min = sample_perf_counters[ind]; } } - gpu_tot_avg_power = (gpu_tot_avg_power + total_power); - gpu_tot_max_power = (total_power > gpu_tot_max_power) ? total_power : gpu_tot_max_power; - gpu_tot_min_power = ((total_power < gpu_tot_min_power) || (gpu_tot_min_power == 0)) ? total_power : gpu_tot_min_power; + gpu_tot_power.avg = (gpu_tot_power.avg + sample_power); + gpu_tot_power.max = (sample_power > gpu_tot_power.max) ? sample_power : gpu_tot_power.max; + gpu_tot_power.min = ((sample_power < gpu_tot_power.min) || (gpu_tot_power.min == 0)) ? sample_power : gpu_tot_power.min; } @@ -467,14 +439,14 @@ void gpgpu_sim_wrapper::print_trace_files() { open_files(); - for(unsigned i=0; i<num_per_counts; ++i){ - gzprintf(metric_trace_file,"%f,",perf_count[i]); + for(unsigned i=0; i<num_perf_counters; ++i){ + gzprintf(metric_trace_file,"%f,",sample_perf_counters[i]); } gzprintf(metric_trace_file,"\n"); gzprintf(power_trace_file,"%f,",proc_power); for(unsigned i=0; i<num_pwr_cmps; ++i){ - gzprintf(power_trace_file,"%f,",pwr_cmp[i]); + gzprintf(power_trace_file,"%f,",sample_cmp_pwr[i]); } gzprintf(power_trace_file,"\n"); @@ -560,7 +532,7 @@ void gpgpu_sim_wrapper::update_coefficients() const_dynamic_power=proc->get_const_dynamic_power()/(proc->cores[0]->executionTime); - for(unsigned i=0; i<num_per_counts; i++){ + for(unsigned i=0; i<num_perf_counters; i++){ initpower_coeff[i]/=(proc->cores[0]->executionTime); effpower_coeff[i]/=(proc->cores[0]->executionTime); } @@ -573,60 +545,60 @@ void gpgpu_sim_wrapper::update_components_power() proc_power=proc->rt_power.readOp.dynamic; - pwr_cmp[IBP]=(proc->cores[0]->ifu->IB->rt_power.readOp.dynamic + sample_cmp_pwr[IBP]=(proc->cores[0]->ifu->IB->rt_power.readOp.dynamic +proc->cores[0]->ifu->IB->rt_power.writeOp.dynamic +proc->cores[0]->ifu->ID_misc->rt_power.readOp.dynamic +proc->cores[0]->ifu->ID_operand->rt_power.readOp.dynamic +proc->cores[0]->ifu->ID_inst->rt_power.readOp.dynamic)/(proc->cores[0]->executionTime); - pwr_cmp[ICP]=proc->cores[0]->ifu->icache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[ICP]=proc->cores[0]->ifu->icache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - pwr_cmp[DCP]=proc->cores[0]->lsu->dcache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[DCP]=proc->cores[0]->lsu->dcache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - pwr_cmp[TCP]=proc->cores[0]->lsu->tcache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[TCP]=proc->cores[0]->lsu->tcache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - pwr_cmp[CCP]=proc->cores[0]->lsu->ccache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[CCP]=proc->cores[0]->lsu->ccache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - pwr_cmp[SHRDP]=proc->cores[0]->lsu->sharedmemory.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[SHRDP]=proc->cores[0]->lsu->sharedmemory.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - pwr_cmp[RFP]=(proc->cores[0]->exu->rfu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)) + sample_cmp_pwr[RFP]=(proc->cores[0]->exu->rfu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)) *(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); - pwr_cmp[SPP]=(proc->cores[0]->exu->exeu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)) + sample_cmp_pwr[SPP]=(proc->cores[0]->exu->exeu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)) *(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); - pwr_cmp[SFUP]=(proc->cores[0]->exu->mul->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)); + sample_cmp_pwr[SFUP]=(proc->cores[0]->exu->mul->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)); - pwr_cmp[FPUP]=(proc->cores[0]->exu->fp_u->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)); + sample_cmp_pwr[FPUP]=(proc->cores[0]->exu->fp_u->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)); - pwr_cmp[SCHEDP]=proc->cores[0]->exu->scheu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[SCHEDP]=proc->cores[0]->exu->scheu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - pwr_cmp[L2CP]=(proc->XML->sys.number_of_L2s>0)? proc->l2array[0]->rt_power.readOp.dynamic/(proc->cores[0]->executionTime):0; + sample_cmp_pwr[L2CP]=(proc->XML->sys.number_of_L2s>0)? proc->l2array[0]->rt_power.readOp.dynamic/(proc->cores[0]->executionTime):0; - pwr_cmp[MCP]=(proc->mc->rt_power.readOp.dynamic-proc->mc->dram->rt_power.readOp.dynamic)/(proc->cores[0]->executionTime); + sample_cmp_pwr[MCP]=(proc->mc->rt_power.readOp.dynamic-proc->mc->dram->rt_power.readOp.dynamic)/(proc->cores[0]->executionTime); - pwr_cmp[NOCP]=proc->nocs[0]->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[NOCP]=proc->nocs[0]->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - pwr_cmp[DRAMP]=proc->mc->dram->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[DRAMP]=proc->mc->dram->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - pwr_cmp[PIPEP]=proc->cores[0]->Pipeline_energy/(proc->cores[0]->executionTime); + sample_cmp_pwr[PIPEP]=proc->cores[0]->Pipeline_energy/(proc->cores[0]->executionTime); - pwr_cmp[IDLE_COREP]=proc->cores[0]->IdleCoreEnergy/(proc->cores[0]->executionTime); + sample_cmp_pwr[IDLE_COREP]=proc->cores[0]->IdleCoreEnergy/(proc->cores[0]->executionTime); // This constant dynamic power (e.g., clock power) part is estimated via regression model. - pwr_cmp[CONST_DYNAMICP]=0; + sample_cmp_pwr[CONST_DYNAMICP]=0; double cnst_dyn = proc->get_const_dynamic_power()/(proc->cores[0]->executionTime); // If the regression scaling term is greater than the recorded constant dynamic power // then use the difference (other portion already added to dynamic power). Else, // all the constant dynamic power is accounted for, add nothing. if(p->sys.scaling_coefficients[CONST_DYNAMICN] > cnst_dyn) - pwr_cmp[CONST_DYNAMICP] = (p->sys.scaling_coefficients[CONST_DYNAMICN]-cnst_dyn); + sample_cmp_pwr[CONST_DYNAMICP] = (p->sys.scaling_coefficients[CONST_DYNAMICN]-cnst_dyn); - proc_power+=pwr_cmp[CONST_DYNAMICP]; + proc_power+=sample_cmp_pwr[CONST_DYNAMICP]; double sum_pwr_cmp=0; for(unsigned i=0; i<num_pwr_cmps; i++){ - sum_pwr_cmp+=pwr_cmp[i]; + sum_pwr_cmp+=sample_cmp_pwr[i]; } bool check=false; check=sanity_check(sum_pwr_cmp,proc_power); @@ -638,45 +610,52 @@ void gpgpu_sim_wrapper::compute() { proc->compute(); } -void gpgpu_sim_wrapper::print_power_kernel_stats(double gpu_sim_cycle, double gpu_tot_sim_cycle, double init_value, const std::string & kernel_info_string) +void gpgpu_sim_wrapper::print_power_kernel_stats(double gpu_sim_cycle, double gpu_tot_sim_cycle, double init_value, const std::string & kernel_info_string, bool print_trace) { detect_print_steady_state(1,init_value); if(g_power_simulation_enabled){ + powerfile<<kernel_info_string<<std::endl; + + sanity_check((kernel_power.avg*kernel_sample_count), kernel_tot_power); powerfile<<"Kernel Average Power Data:"<<std::endl; - powerfile<<"gpu_avg_power = "<< gpu_avg_power/ count<<std::endl; + powerfile<<"kernel_avg_power = " << kernel_power.avg << std::endl; for(unsigned i=0; i<num_pwr_cmps; ++i){ - powerfile<<"gpu_avg_"<<pwr_cmp_label[i]<<" = "<<pwr_cmp_avg[i]/count<<std::endl; + powerfile<<"gpu_avg_"<<pwr_cmp_label[i]<<" = "<<kernel_cmp_pwr[i].avg/kernel_sample_count<<std::endl; } - for(unsigned i=0; i<num_per_counts; ++i){ - powerfile<<"gpu_avg_"<<perf_count_label[i]<<" = "<<perf_count_avg[i]/count<<std::endl; + for(unsigned i=0; i<num_perf_counters; ++i){ + powerfile<<"gpu_avg_"<<perf_count_label[i]<<" = "<<kernel_cmp_perf_counters[i].avg/kernel_sample_count<<std::endl; } powerfile<<std::endl<<"Kernel Maximum Power Data:"<<std::endl; - powerfile<<"gpu_max_power = "<< gpu_max_power<<std::endl; + powerfile<<"kernel_max_power = "<< kernel_power.max<<std::endl; for(unsigned i=0; i<num_pwr_cmps; ++i){ - powerfile<<"gpu_max_"<<pwr_cmp_label[i]<<" = "<<pwr_cmp_max[i]<<std::endl; + powerfile<<"gpu_max_"<<pwr_cmp_label[i]<<" = "<<kernel_cmp_pwr[i].max<<std::endl; } - for(unsigned i=0; i<num_per_counts; ++i){ - powerfile<<"gpu_max_"<<perf_count_label[i]<<" = "<<perf_count_max[i]<<std::endl; + for(unsigned i=0; i<num_perf_counters; ++i){ + powerfile<<"gpu_max_"<<perf_count_label[i]<<" = "<<kernel_cmp_perf_counters[i].max<<std::endl; } powerfile<<std::endl<<"Kernel Minimum Power Data:"<<std::endl; - powerfile<<"gpu_min_power = "<< gpu_min_power<<std::endl; + powerfile<<"kernel_min_power = "<< kernel_power.min<<std::endl; for(unsigned i=0; i<num_pwr_cmps; ++i){ - powerfile<<"gpu_min_"<<pwr_cmp_label[i]<<" = "<<pwr_cmp_min[i]<<std::endl; + powerfile<<"gpu_min_"<<pwr_cmp_label[i]<<" = "<<kernel_cmp_pwr[i].min<<std::endl; } - for(unsigned i=0; i<num_per_counts; ++i){ - powerfile<<"gpu_min_"<<perf_count_label[i]<<" = "<<perf_count_min[i]<<std::endl; + for(unsigned i=0; i<num_perf_counters; ++i){ + powerfile<<"gpu_min_"<<perf_count_label[i]<<" = "<<kernel_cmp_perf_counters[i].min<<std::endl; } powerfile<<std::endl<<"Accumulative Power Statistics Over Previous Kernels:"<<std::endl; - powerfile<<"gpu_tot_avg_power = "<< gpu_tot_avg_power/gcount<<std::endl; - powerfile<<"gpu_tot_max_power = "<<gpu_tot_max_power<<std::endl; - powerfile<<"gpu_tot_min_power = "<<gpu_tot_min_power<<std::endl; + powerfile<<"gpu_tot_avg_power = "<< gpu_tot_power.avg/total_sample_count<<std::endl; + powerfile<<"gpu_tot_max_power = "<<gpu_tot_power.max<<std::endl; + powerfile<<"gpu_tot_min_power = "<<gpu_tot_power.min<<std::endl; powerfile<<std::endl<<std::endl; powerfile.flush(); + + if(print_trace){ + print_trace_files(); + } } } @@ -692,8 +671,8 @@ void gpgpu_sim_wrapper::print_steady_state(int position, double init_val){ if((samples.size() > gpu_steady_min_period)){ // If steady state occurred for some time, print to file has_written_avg=true; - gzprintf(steady_state_tacking_file,"%u,%d,%f,%f,",sample_start,gcount,temp_avg,temp_ipc); - for(unsigned i=0; i<num_per_counts; ++i){ + gzprintf(steady_state_tacking_file,"%u,%d,%f,%f,",sample_start,total_sample_count,temp_avg,temp_ipc); + for(unsigned i=0; i<num_perf_counters; ++i){ gzprintf(steady_state_tacking_file,"%f,", samples_counter.at(i)/((double)samples.size())); } gzprintf(steady_state_tacking_file,"\n"); @@ -704,7 +683,7 @@ void gpgpu_sim_wrapper::print_steady_state(int position, double init_val){ sample_start = 0; sample_val = 0; - init_inst_val=init_val;//gpu_tot_sim_insn+gpu_sim_insn; + init_inst_val=init_val; samples.clear(); samples_counter.clear(); pwr_counter.clear(); @@ -719,22 +698,22 @@ void gpgpu_sim_wrapper::detect_print_steady_state(int position, double init_val) if(position==0){ if(samples.size() == 0){ // First sample - sample_start = gcount; + sample_start = total_sample_count; sample_val = proc->rt_power.readOp.dynamic; - init_inst_val=init_val;//gpu_tot_sim_insn+gpu_sim_insn; + init_inst_val=init_val; samples.push_back(proc->rt_power.readOp.dynamic); assert(samples_counter.size() == 0); assert(pwr_counter.size() == 0); - for(unsigned i=0; i<(num_per_counts); ++i){ - samples_counter.push_back(perf_count[i]); + for(unsigned i=0; i<(num_perf_counters); ++i){ + samples_counter.push_back(sample_perf_counters[i]); } for(unsigned i=0; i<(num_pwr_cmps); ++i){ - pwr_counter.push_back(pwr_cmp[i]); + pwr_counter.push_back(sample_cmp_pwr[i]); } assert(pwr_counter.size() == (double)num_pwr_cmps); - assert(samples_counter.size() == (double)num_per_counts); + assert(samples_counter.size() == (double)num_perf_counters); }else{ // Get current average double temp_avg = sample_val / (double)samples.size() ; @@ -743,12 +722,12 @@ void gpgpu_sim_wrapper::detect_print_steady_state(int position, double init_val) if( abs(proc->rt_power.readOp.dynamic-temp_avg) < gpu_steady_power_deviation){ // Value is within threshold sample_val += proc->rt_power.readOp.dynamic; samples.push_back(proc->rt_power.readOp.dynamic); - for(unsigned i=0; i<(num_per_counts); ++i){ - samples_counter.at(i) += perf_count[i]; + for(unsigned i=0; i<(num_perf_counters); ++i){ + samples_counter.at(i) += sample_perf_counters[i]; } for(unsigned i=0; i<(num_pwr_cmps); ++i){ - pwr_counter.at(i) += pwr_cmp[i]; + pwr_counter.at(i) += sample_cmp_pwr[i]; } }else{ // Value exceeds threshold, not considered steady state diff --git a/src/gpuwattch/gpgpu_sim_wrapper.h b/src/gpuwattch/gpgpu_sim_wrapper.h index f7f5066..9d06092 100644 --- a/src/gpuwattch/gpgpu_sim_wrapper.h +++ b/src/gpuwattch/gpgpu_sim_wrapper.h @@ -41,8 +41,14 @@ using namespace std; +template <typename T> +struct avg_max_min_counters{ + T avg; + T max; + T min; - + avg_max_min_counters(){avg=0; max=0; min=0;} +}; class gpgpu_sim_wrapper { public: @@ -61,8 +67,8 @@ public: void print_trace_files(); void update_components_power(); void update_coefficients(); - void reset_counters(bool do_print); - void print_power_kernel_stats(double gpu_sim_cycle, double gpu_tot_sim_cycle, double init_value, const std::string & kernel_info_string); + void reset_counters(); + void print_power_kernel_stats(double gpu_sim_cycle, double gpu_tot_sim_cycle, double init_value, const std::string & kernel_info_string, bool print_trace); void power_metrics_calculations(); void set_inst_power(bool clk_gated_lanes, double tot_cycles, double busy_cycles, double tot_inst, double int_inst, double fp_inst, double load_inst, double store_inst, double committed_inst); void set_regfile_power(double reads, double writes, double ops); @@ -88,37 +94,34 @@ private: ParseXML * p; // power parameters double const_dynamic_power; - double * pwr_cmp; double proc_power; - double * pwr_cmp_avg; - double * pwr_cmp_max; - double * pwr_cmp_min; - double * perf_count_avg; - double * perf_count_min; - double * perf_count_max; - double pavg; - int count; - unsigned num_per_counts; - unsigned num_pwr_cmps; - int gcount; - double gpu_avg_power; - double gpu_max_power; - double gpu_min_power; - double gpu_tot_avg_power; - double gpu_tot_min_power; - double gpu_tot_max_power; + + unsigned num_perf_counters; // # of performance counters + unsigned num_pwr_cmps; // # of components modelled + int kernel_sample_count; // # of samples per kernel + int total_sample_count; // # of samples per benchmark + + std::vector< avg_max_min_counters<double> > kernel_cmp_pwr; // Per-kernel component power avg/max/min values + std::vector< avg_max_min_counters<double> > kernel_cmp_perf_counters; // Per-kernel component avg/max/min performance counters + + double kernel_tot_power; // Total per-kernel power + avg_max_min_counters<double> kernel_power; // Per-kernel power avg/max/min values + avg_max_min_counters<double> gpu_tot_power; // Global GPU power avg/max/min values (across kernels) + bool has_written_avg; - double * perf_count; - double * initpower_coeff; - double * effpower_coeff; + std::vector<double> sample_cmp_pwr; // Current sample component powers + std::vector<double> sample_perf_counters; // Current sample component perf. counts + std::vector<double> initpower_coeff; + std::vector<double> effpower_coeff; + // For calculating steady-state average unsigned sample_start; double sample_val; double init_inst_val; std::vector<double> samples; - std::vector< double > samples_counter; - std::vector< double > pwr_counter; + std::vector<double> samples_counter; + std::vector<double> pwr_counter; char *xml_filename; char *g_power_filename; |
