summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim
diff options
context:
space:
mode:
authorTayler Hetherington <[email protected]>2012-11-30 21:29:42 -0800
committerAndrew Boktor <[email protected]>2014-08-14 13:49:22 -0700
commit36ce0f2243fd0723a746b3c2f5f0651577312400 (patch)
treee79475e75f800ad34b4851ea710c4ee409f5bd72 /src/gpgpu-sim
parent08ec3343d0bca75e63e130266f75f8242f22050b (diff)
Merging Power model into Fermi
//depot/gpgpu_sim_research/fermi_power/distribution/... to //depot/gpgpu_sim_research/fermi/distribution/... [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 14723]
Diffstat (limited to 'src/gpgpu-sim')
-rw-r--r--src/gpgpu-sim/Makefile20
-rw-r--r--src/gpgpu-sim/dram.cc32
-rw-r--r--src/gpgpu-sim/dram.h11
-rw-r--r--src/gpgpu-sim/dram_sched.cc11
-rw-r--r--src/gpgpu-sim/gpu-cache.cc29
-rw-r--r--src/gpgpu-sim/gpu-cache.h49
-rw-r--r--src/gpgpu-sim/gpu-sim.cc183
-rw-r--r--src/gpgpu-sim/gpu-sim.h123
-rw-r--r--src/gpgpu-sim/icnt_wrapper.cc2
-rw-r--r--src/gpgpu-sim/icnt_wrapper.h3
-rw-r--r--src/gpgpu-sim/l2cache.cc96
-rw-r--r--src/gpgpu-sim/l2cache.h21
-rw-r--r--src/gpgpu-sim/mem_fetch.cc15
-rw-r--r--src/gpgpu-sim/mem_fetch.h6
-rw-r--r--src/gpgpu-sim/mem_fetch_status.tup2
-rw-r--r--src/gpgpu-sim/mem_latency_stat.cc8
-rw-r--r--src/gpgpu-sim/mem_latency_stat.h9
-rw-r--r--src/gpgpu-sim/power_interface.cc125
-rw-r--r--src/gpgpu-sim/power_interface.h43
-rw-r--r--src/gpgpu-sim/power_stat.cc335
-rw-r--r--src/gpgpu-sim/power_stat.h613
-rw-r--r--src/gpgpu-sim/shader.cc452
-rw-r--r--src/gpgpu-sim/shader.h308
-rw-r--r--src/gpgpu-sim/stats.h7
-rw-r--r--src/gpgpu-sim/visualizer.cc5
25 files changed, 2416 insertions, 92 deletions
diff --git a/src/gpgpu-sim/Makefile b/src/gpgpu-sim/Makefile
index fdb4503..04659aa 100644
--- a/src/gpgpu-sim/Makefile
+++ b/src/gpgpu-sim/Makefile
@@ -52,6 +52,11 @@ else
CXXFLAGS +=
endif
+POWER_FLAGS=
+ifneq ($(GPGPUSIM_POWER_MODEL),)
+ POWER_FLAGS = -I$(GPGPUSIM_POWER_MODEL) -DGPGPUSIM_POWER_MODEL
+endif
+
OPTFLAGS += -g3 -fPIC
CPP = g++ $(SNOW)
@@ -60,7 +65,16 @@ OEXT = o
OUTPUT_DIR=../../$(SIM_OBJ_FILES_DIR)/gpgpu-sim
SRCS = $(shell ls *.cc)
-OBJS = $(SRCS:%.cc=$(OUTPUT_DIR)/%.$(OEXT))
+
+EXCLUDES =
+
+ifeq ($(GPGPUSIM_POWER_MODEL), )
+EXCLUDES += power_interface.cc
+endif
+
+CSRCS = $(filter-out $(EXCLUDES), $(SRCS))
+
+OBJS = $(CSRCS:%.cc=$(OUTPUT_DIR)/%.$(OEXT))
libgpu_uarch_sim.a:$(OBJS)
ar rcs $(OUTPUT_DIR)/libgpu_uarch_sim.a $(OBJS)
@@ -69,13 +83,13 @@ Makefile.makedepend: depend
depend:
touch Makefile.makedepend
- makedepend -fMakefile.makedepend -p$(OUTPUT_DIR)/ $(SRCS) 2> /dev/null
+ makedepend -fMakefile.makedepend -p$(OUTPUT_DIR)/ $(CSRCS) 2> /dev/null
$(OUTPUT_DIR)/l2cache.$(OEXT): l2cache.cc
$(CPP) $(OPTFLAGS) $(CXXFLAGS_L2CACHE) -o $*.$(OEXT) -c l2cache.cc
$(OUTPUT_DIR)/%.$(OEXT): %.cc
- $(CPP) $(OPTFLAGS) $(CXXFLAGS) -o $(OUTPUT_DIR)/$*.$(OEXT) -c $*.cc
+ $(CPP) $(OPTFLAGS) $(CXXFLAGS) $(POWER_FLAGS) -o $(OUTPUT_DIR)/$*.$(OEXT) -c $*.cc
clean:
rm -f *.o core *~ *.a
diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc
index a173a52..3594198 100644
--- a/src/gpgpu-sim/dram.cc
+++ b/src/gpgpu-sim/dram.cc
@@ -419,6 +419,17 @@ void dram_t::cycle()
#endif
}
+void dram_t::get_access_stats(unsigned &total_access, unsigned &total_reads, unsigned &total_writes,unsigned &total_l2_read_access,unsigned &total_l2_read_miss,unsigned &total_l2_write_access,unsigned &total_l2_write_miss ){
+ total_access += m_stats->total_n_access;
+ total_reads += m_stats->total_n_reads;
+ total_writes += m_stats->total_n_writes;
+ total_l2_read_access += m_stats->L2_read_access;
+ total_l2_read_miss += m_stats->L2_read_miss;
+ total_l2_write_access += m_stats->L2_write_access;
+ total_l2_write_miss += m_stats->L2_write_miss;
+
+}
+
//if mrq is being serviced by dram, gets popped after CL latency fulfilled
class mem_fetch* dram_t::pop()
{
@@ -525,3 +536,24 @@ void dram_t::visualizer_print( gzFile visualizer_file )
m_stats->mem_access_type_stats[TEXTURE_ACC_R][id][j]);
}
}
+
+
+void dram_t::set_dram_power_stats( unsigned &cmd,
+ unsigned &activity,
+ unsigned &nop,
+ unsigned &act,
+ unsigned &pre,
+ unsigned &rd,
+ unsigned &wr,
+ unsigned &req) const{
+
+ // Point power performance counters to low-level DRAM counters
+ cmd = n_cmd;
+ activity = n_activity;
+ nop = n_nop;
+ act = n_act;
+ pre = n_pre;
+ rd = n_rd;
+ wr = n_wr;
+ req = n_req;
+}
diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h
index ad773b3..0e82763 100644
--- a/src/gpgpu-sim/dram.h
+++ b/src/gpgpu-sim/dram.h
@@ -103,6 +103,7 @@ public:
bool returnq_full() const;
unsigned int queue_limit() const;
void visualizer_print( gzFile visualizer_file );
+ void get_access_stats(unsigned &total_access, unsigned &total_reads, unsigned &total_writes,unsigned &total_l2_read_hit,unsigned &total_l2_read_miss,unsigned &total_l2_write_hit,unsigned &total_l2_write_miss );
class mem_fetch* pop();
void push( class mem_fetch *data );
@@ -112,6 +113,16 @@ public:
class memory_partition_unit *m_memory_partition_unit;
unsigned int id;
+ // Power Model
+ void set_dram_power_stats( unsigned &cmd,
+ unsigned &activity,
+ unsigned &nop,
+ unsigned &act,
+ unsigned &pre,
+ unsigned &rd,
+ unsigned &wr,
+ unsigned &req) const;
+
private:
void scheduler_fifo();
void scheduler_frfcfs();
diff --git a/src/gpgpu-sim/dram_sched.cc b/src/gpgpu-sim/dram_sched.cc
index e556edc..e30bd24 100644
--- a/src/gpgpu-sim/dram_sched.cc
+++ b/src/gpgpu-sim/dram_sched.cc
@@ -133,6 +133,17 @@ void dram_t::scheduler_frfcfs()
frfcfs_scheduler *sched = m_frfcfs_scheduler;
while ( !mrqq->empty() && (!m_config->gpgpu_dram_sched_queue_size || sched->num_pending() < m_config->gpgpu_dram_sched_queue_size)) {
dram_req_t *req = mrqq->pop();
+
+ // Power stats
+ //if(req->data->get_type() != READ_REPLY && req->data->get_type() != WRITE_ACK)
+ m_stats->total_n_access++;
+
+ if(req->data->get_type() == WRITE_REQUEST){
+ m_stats->total_n_writes++;
+ }else if(req->data->get_type() == READ_REQUEST){
+ m_stats->total_n_reads++;
+ }
+
req->data->set_status(IN_PARTITION_MC_INPUT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
sched->add_req(req);
}
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc
index fc2d032..3f44eea 100644
--- a/src/gpgpu-sim/gpu-cache.cc
+++ b/src/gpgpu-sim/gpu-cache.cc
@@ -201,6 +201,13 @@ void tag_array::print( FILE *stream, unsigned &total_access, unsigned &total_mis
total_access+=m_access;
}
+void tag_array::get_stats(unsigned &total_access, unsigned &total_misses) const{
+ // Get the access and miss counts from the tag array
+ total_misses = m_miss;
+ total_access = m_access;
+}
+
+
bool was_write_sent( const std::list<cache_event> &events )
{
for( std::list<cache_event>::const_iterator e=events.begin(); e!=events.end(); e++ ) {
@@ -293,6 +300,7 @@ void baseline_cache::cycle(){
if ( !m_memport->full(mf->get_data_size(),mf->get_is_write()) ) {
m_miss_queue.pop_front();
m_memport->push(mf);
+ n_simt_to_mem+=mf->get_num_flits(true); // Interconnect power stats
}
}
}
@@ -393,6 +401,7 @@ cache_request_status data_cache::wr_hit_wb(new_addr_type addr, unsigned cache_in
cache_block_t &block = m_tag_array.get_block(cache_index);
block.m_status = MODIFIED;
+ m_write_access++;
return HIT;
}
@@ -409,6 +418,7 @@ cache_request_status data_cache::wr_hit_wt(new_addr_type addr, unsigned cache_in
// generate a write-through
send_write_request(mf, WRITE_REQUEST_SENT, time, events);
+ m_write_access++;
return HIT;
}
@@ -423,6 +433,8 @@ cache_request_status data_cache::wr_hit_we(new_addr_type addr, unsigned cache_in
// Invalidate block
block.m_status = INVALID;
+
+ m_write_access++;
return HIT;
}
@@ -481,8 +493,11 @@ enum cache_request_status data_cache::wr_miss_wa(new_addr_type addr, unsigned ca
m_miss_queue.push_back(wb);
wb->set_status(m_miss_queue_status,time);
}
- if( do_miss )
+ if( do_miss ){
+ m_write_access++;
+ m_write_miss++;
return MISS;
+ }
return RESERVATION_FAIL;
}
@@ -494,6 +509,9 @@ enum cache_request_status data_cache::wr_miss_no_wa(new_addr_type addr, unsigned
// on miss, generate write through (no write buffering -- too many threads for that)
send_write_request(mf, WRITE_REQUEST_SENT, time, events);
+
+ m_write_access++;
+ m_write_miss++;
return MISS;
}
@@ -508,6 +526,8 @@ enum cache_request_status data_cache::rd_hit_base(new_addr_type addr, unsigned c
cache_block_t &block = m_tag_array.get_block(cache_index);
block.m_status = MODIFIED; // mark line as dirty
}
+
+ m_read_access++;
return HIT;
}
@@ -528,8 +548,11 @@ enum cache_request_status data_cache::rd_miss_base(new_addr_type addr, unsigned
mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr, L1_WRBK_ACC,m_config.get_line_sz(),true);
send_write_request(wb, WRITE_BACK_REQUEST_SENT, time, events);
}
- if( do_miss )
+ if( do_miss ){
+ m_read_access++;
+ m_read_miss++;
return MISS;
+ }
return RESERVATION_FAIL;
}
@@ -565,7 +588,6 @@ enum cache_request_status l1_cache::access( new_addr_type addr, mem_fetch *mf, u
unsigned cache_index = (unsigned)-1;
enum cache_request_status status = m_tag_array.probe(block_addr,cache_index);
-
// Each function pointer ( m_[rd/wr]_[hit/miss] ) is set in the data_cache constructor to reflect the corresponding cache configuration options.
// Function pointers were used to avoid many long conditional branches resulting from many cache configuration options.
if(wr){ // Write
@@ -652,6 +674,7 @@ void tex_cache::cycle(){
if ( !m_memport->full(mf->get_ctrl_size(),false) ) {
m_request_fifo.pop();
m_memport->push(mf);
+ n_simt_to_mem+=mf->get_num_flits(true); // Interconnect power stats
}
}
// read ready lines from cache
diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h
index 4516e34..783280c 100644
--- a/src/gpgpu-sim/gpu-cache.h
+++ b/src/gpgpu-sim/gpu-cache.h
@@ -255,14 +255,15 @@ private:
friend class l2_cache;
};
+
class tag_array {
public:
- tag_array( const cache_config &config, int core_id, int type_id );
+ tag_array( const cache_config &config, int core_id, int type_id );
~tag_array();
enum cache_request_status probe( new_addr_type addr, unsigned &idx ) const;
enum cache_request_status access( new_addr_type addr, unsigned time, unsigned &idx );
- enum cache_request_status access( new_addr_type addr, unsigned time, unsigned &idx, bool &wb, cache_block_t &evicted );
+ enum cache_request_status access( new_addr_type addr, unsigned time, unsigned &idx, bool &wb, cache_block_t &evicted );
void fill( new_addr_type addr, unsigned time );
void fill( unsigned idx, unsigned time );
@@ -270,11 +271,12 @@ public:
unsigned size() const { return m_config.get_num_lines();}
cache_block_t &get_block(unsigned idx) { return m_lines[idx];}
- void flush(); // flash invalidate all entries
+ void flush(); // flash invalidate all entries
void new_window();
void print( FILE *stream, unsigned &total_access, unsigned &total_misses ) const;
float windowed_miss_rate( ) const;
+ void get_stats(unsigned &total_access, unsigned &total_misses) const;
protected:
@@ -289,12 +291,13 @@ protected:
// performance counters for calculating the amount of misses within a time window
unsigned m_prev_snapshot_access;
unsigned m_prev_snapshot_miss;
- unsigned m_prev_snapshot_pending_hit;
+ unsigned m_prev_snapshot_pending_hit;
int m_core_id; // which shader core is using this
int m_type_id; // what kind of cache is this (normal, texture, constant)
};
+
class mshr_table {
public:
mshr_table( unsigned num_entries, unsigned max_merged )
@@ -366,6 +369,10 @@ public:
assert(config.m_mshr_type == ASSOC);
m_memport=memport;
m_miss_queue_status = status;
+ m_read_access=0;
+ m_write_access=0;
+ m_read_miss=0;
+ m_write_miss=0;
}
virtual enum cache_request_status access( new_addr_type addr, mem_fetch *mf, unsigned time, std::list<cache_event> &events ) = 0;
@@ -384,6 +391,21 @@ public:
void print(FILE *fp, unsigned &accesses, unsigned &misses) const;
void display_state( FILE *fp ) const;
+ virtual void get_data_stats(unsigned &read_access, unsigned &read_misses,unsigned &write_access, unsigned &write_misses) const {
+ read_access = m_read_access;
+ write_access = m_write_access;
+ read_misses = m_read_miss;
+ write_misses = m_write_miss;
+ }
+
+ void get_stats(unsigned &accesses, unsigned &misses) const {
+ m_tag_array.get_stats(accesses, misses);
+ }
+
+ void set_icnt_power_stats(unsigned &simt_to_mem) const{
+ simt_to_mem = n_simt_to_mem;
+ }
+
protected:
std::string m_name;
const cache_config &m_config;
@@ -422,6 +444,14 @@ public:
/// Read miss handler. Check MSHR hit or MSHR available
void send_read_request(new_addr_type addr, new_addr_type block_addr, unsigned cache_index, mem_fetch *mf,
unsigned time, bool &do_miss, bool &wb, cache_block_t &evicted, std::list<cache_event> &events, bool read_only, bool wa);
+
+ // Power stats
+ unsigned m_read_access;
+ unsigned m_write_access;
+ unsigned m_read_miss;
+ unsigned m_write_miss;
+
+ unsigned n_simt_to_mem; // Interconnect power stats
};
/// Read only cache
@@ -574,6 +604,14 @@ public:
mem_fetch *next_access(){return m_result_fifo.pop();}
void display_state( FILE *fp ) const;
+ void get_stats(unsigned &accesses, unsigned &misses) const{
+ m_tags.get_stats(accesses, misses);
+ }
+
+ void set_icnt_power_stats(unsigned &simt_to_mem) const{
+ simt_to_mem = n_simt_to_mem;
+ }
+
private:
std::string m_name;
const cache_config &m_config;
@@ -700,6 +738,9 @@ public:
typedef std::map<mem_fetch*,extra_mf_fields> extra_mf_fields_lookup;
extra_mf_fields_lookup m_extra_mf_fields;
+
+ // Interconnect power stats
+ unsigned n_simt_to_mem;
};
#endif
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index 6aeaa63..fd87299 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -26,6 +26,7 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
#include "gpu-sim.h"
#include <stdio.h>
@@ -33,7 +34,7 @@
#include <math.h>
#include "zlib.h"
-#include "../option_parser.h"
+
#include "shader.h"
#include "dram.h"
#include "mem_fetch.h"
@@ -56,21 +57,27 @@
#include "../debug.h"
#include "../gpgpusim_entrypoint.h"
#include "../cuda-sim/cuda-sim.h"
-
#include "mem_latency_stat.h"
+#include "power_stat.h"
#include "visualizer.h"
#include "stats.h"
+#ifdef GPGPUSIM_POWER_MODEL
+#include "power_interface.h"
+#endif
+
#include <stdio.h>
#include <string.h>
#define MAX(a,b) (((a)>(b))?(a):(b))
+
bool g_interactive_debugger_enabled=false;
unsigned long long gpu_sim_cycle = 0;
unsigned long long gpu_tot_sim_cycle = 0;
+
// performance counter for stalls due to congestion.
unsigned int gpu_stall_dramfull = 0;
unsigned int gpu_stall_icnt2sh = 0;
@@ -84,8 +91,47 @@ unsigned int gpu_stall_icnt2sh = 0;
#define MEM_LATENCY_STAT_IMPL
+
+
+
+
#include "mem_latency_stat.h"
+void power_config::reg_options(class OptionParser * opp)
+{
+
+
+ option_parser_register(opp, "-mcpat_xml_file", OPT_CSTR,
+ &g_power_config_name,"McPAT XML file",
+ "mcpat.xml");
+
+ option_parser_register(opp, "-power_simulation_enabled", OPT_BOOL,
+ &g_power_simulation_enabled, "Turn on power simulator (1=On, 0=Off)",
+ "1");
+
+ option_parser_register(opp, "-power_per_cycle_dump", OPT_BOOL,
+ &g_power_per_cycle_dump, "Dump detailed power output each cycle",
+ "0");
+
+ // Output Data Formats
+ option_parser_register(opp, "-power_trace_enabled", OPT_BOOL,
+ &g_power_trace_enabled, "produce a file for the power trace (1=On, 0=Off)",
+ "0");
+
+ option_parser_register(opp, "-power_trace_zlevel", OPT_INT32,
+ &g_power_trace_zlevel, "Compression level of the power trace output log (0=no comp, 9=highest)",
+ "6");
+
+ option_parser_register(opp, "-steady_power_levels_enabled", OPT_BOOL,
+ &g_steady_power_levels_enabled, "produce a file for the steady power levels (1=On, 0=Off)",
+ "0");
+
+ option_parser_register(opp, "-steady_state_definition", OPT_CSTR,
+ &gpu_steady_state_definition, "allowed deviation:number of samples",
+ "8:4");
+
+}
+
void memory_config::reg_options(class OptionParser * opp)
{
option_parser_register(opp, "-gpgpu_dram_scheduler", OPT_INT32, &scheduler_type,
@@ -164,6 +210,15 @@ void shader_core_config::reg_options(class OptionParser * opp)
option_parser_register(opp, "-gpgpu_perfect_mem", OPT_BOOL, &gpgpu_perfect_mem,
"enable perfect memory mode (no cache miss)",
"0");
+ option_parser_register(opp, "-n_regfile_gating_group", OPT_UINT32, &n_regfile_gating_group,
+ "group of lanes that should be read/written together)",
+ "4");
+ option_parser_register(opp, "-gpgpu_clock_gated_reg_file", OPT_BOOL, &gpgpu_clock_gated_reg_file,
+ "enable clock gated reg file for power calculations",
+ "0");
+ option_parser_register(opp, "-gpgpu_clock_gated_lanes", OPT_BOOL, &gpgpu_clock_gated_lanes,
+ "enable clock gated lanes for power calculations",
+ "0");
option_parser_register(opp, "-gpgpu_shader_registers", OPT_UINT32, &gpgpu_shader_registers,
"Number of registers per shader core. Limits number of concurrent CTAs. (default 8192)",
"8192");
@@ -277,7 +332,7 @@ void gpgpu_sim_config::reg_options(option_parser_t opp)
gpgpu_functional_sim_config::reg_options(opp);
m_shader_config.reg_options(opp);
m_memory_config.reg_options(opp);
-
+ power_config::reg_options(opp);
option_parser_register(opp, "-gpgpu_max_cycle", OPT_INT32, &gpu_max_cycle_opt,
"terminates gpu simulation early (0 = no limit)",
"0");
@@ -290,9 +345,13 @@ void gpgpu_sim_config::reg_options(option_parser_t opp)
option_parser_register(opp, "-gpgpu_runtime_stat", OPT_CSTR, &gpgpu_runtime_stat,
"display runtime statistics such as dram utilization {<freq>:<flag>}",
"10000:0");
- option_parser_register(opp, "-gpgpu_flush_cache", OPT_BOOL, &gpgpu_flush_cache,
- "Flush cache at the end of each kernel call",
+ option_parser_register(opp, "-gpgpu_flush_l1_cache", OPT_BOOL, &gpgpu_flush_l1_cache,
+ "Flush L1 cache at the end of each kernel call",
"0");
+ 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");
@@ -427,14 +486,22 @@ gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config )
set_ptx_warp_size(m_shader_config);
ptx_file_line_stats_create_exposed_latency_tracker(m_config.num_shader());
+#ifdef GPGPUSIM_POWER_MODEL
+ m_gpgpusim_wrapper = new gpgpu_sim_wrapper();
+#endif
+
m_shader_stats = new shader_core_stats(m_shader_config);
m_memory_stats = new memory_stats_t(m_config.num_shader(),m_shader_config,m_memory_config);
+ average_pipeline_duty_cycle = (float *)malloc(sizeof(float));
+ active_sms=(float *)malloc(sizeof(float));
+ m_power_stats = new power_stat_t(m_shader_config,average_pipeline_duty_cycle,active_sms,m_shader_stats,m_memory_config,m_memory_stats);
gpu_sim_insn = 0;
gpu_tot_sim_insn = 0;
gpu_tot_issued_cta = 0;
gpu_deadlock = false;
+
m_cluster = new simt_core_cluster*[m_shader_config->n_simt_clusters];
for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++)
m_cluster[i] = new simt_core_cluster(this,i,m_shader_config,m_memory_config,m_shader_stats,m_memory_stats);
@@ -451,6 +518,8 @@ 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;
+ *average_pipeline_duty_cycle=0;
+ *active_sms=0;
}
int gpgpu_sim::shared_mem_size() const
@@ -564,6 +633,13 @@ void gpgpu_sim::init()
if (g_network_mode)
icnt_init_grid();
+
+ // McPAT initialization function. Called on first launch of GPU
+#ifdef GPGPUSIM_POWER_MODEL
+ if(m_config.g_power_simulation_enabled){
+ init_mcpat(m_config, m_gpgpusim_wrapper, m_config.gpu_stat_sample_freq, gpu_tot_sim_insn, gpu_sim_insn);
+ }
+#endif
}
void gpgpu_sim::update_stats() {
@@ -626,7 +702,7 @@ void gpgpu_sim::deadlock_check()
}
}
-void gpgpu_sim::gpu_print_stat() const
+void gpgpu_sim::gpu_print_stat()
{
printf("gpu_sim_cycle = %lld\n", gpu_sim_cycle);
printf("gpu_sim_insn = %lld\n", gpu_sim_insn);
@@ -636,6 +712,8 @@ void gpgpu_sim::gpu_print_stat() const
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);
+
+
// performance counter for stalls due to congestion.
printf("gpu_stall_dramfull = %d\n", gpu_stall_dramfull);
printf("gpu_stall_icnt2sh = %d\n", gpu_stall_icnt2sh );
@@ -648,6 +726,9 @@ void gpgpu_sim::gpu_print_stat() const
shader_print_l1_miss_stat( stdout );
m_shader_stats->print(stdout);
+#ifdef GPGPUSIM_POWER_MODEL
+ m_gpgpusim_wrapper->print_power_kernel_stats(gpu_sim_cycle,gpu_tot_sim_cycle,gpu_tot_sim_insn + gpu_sim_insn );
+#endif
// performance counter that are not local to one shader
m_memory_stats->memlatstat_print(m_memory_config->m_n_mem,m_memory_config->nbk);
@@ -664,8 +745,34 @@ void gpgpu_sim::gpu_print_stat() const
StatDisp( g_inst_classification_stat[g_ptx_kernel_count]);
StatDisp( g_inst_op_classification_stat[g_ptx_kernel_count]);
}
+
+#ifdef GPGPUSIM_POWER_MODEL
+ m_gpgpusim_wrapper->detect_print_steady_state(1,gpu_tot_sim_insn+gpu_sim_insn);
+#endif
+
+
+ // Interconnect power stat print
+ unsigned total_mem_to_simt=0;
+ unsigned total_simt_to_mem=0;
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++){
+ unsigned temp=0;
+ m_memory_partition_unit[i]->set_icnt_power_stats(temp);
+ total_mem_to_simt += temp;
+ }
+ for(unsigned i=0; i<m_config.num_shader(); i++){
+ unsigned temp=0;
+ m_cluster[i]->set_icnt_stats(temp);
+ total_simt_to_mem += temp;
+ }
+ printf("\nicnt_total_pkts_mem_to_simt=%u\n", total_mem_to_simt);
+ printf("icnt_total_pkts_simt_to_mem=%u\n\n", total_simt_to_mem);
+
time_vector_print();
fflush(stdout);
+
+
+
+
}
@@ -855,8 +962,13 @@ void gpgpu_sim::cycle()
}
if (clock_mask & DRAM) {
- for (unsigned i=0;i<m_memory_config->m_n_mem;i++)
- m_memory_partition_unit[i]->dram_cycle(); // Issue the dram command (scheduler + delay model)
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++){
+ m_memory_partition_unit[i]->dram_cycle(); // Issue the dram command (scheduler + delay model)
+ // Update performance counters for DRAM
+ m_memory_partition_unit[i]->set_dram_power_stats(m_power_stats->pwr_mem_stat->n_cmd[0][i], m_power_stats->pwr_mem_stat->n_activity[0][i],
+ m_power_stats->pwr_mem_stat->n_nop[0][i], m_power_stats->pwr_mem_stat->n_act[0][i], m_power_stats->pwr_mem_stat->n_pre[0][i],
+ m_power_stats->pwr_mem_stat->n_rd[0][i], m_power_stats->pwr_mem_stat->n_wr[0][i], m_power_stats->pwr_mem_stat->n_req[0][i]);
+ }
}
// L2 operations follow L2 clock domain
@@ -871,7 +983,11 @@ void gpgpu_sim::cycle()
m_memory_partition_unit[i]->push( mf, gpu_sim_cycle + gpu_tot_sim_cycle );
}
m_memory_partition_unit[i]->cache_cycle(gpu_sim_cycle+gpu_tot_sim_cycle);
- }
+ m_memory_partition_unit[i]->set_L2cache_power_stats(m_power_stats->pwr_mem_stat->n_l2_read_access[0][i], m_power_stats->pwr_mem_stat->n_l2_read_miss[0][i],
+ m_power_stats->pwr_mem_stat->n_l2_write_access[0][i], m_power_stats->pwr_mem_stat->n_l2_write_miss[0][i]);
+
+ m_memory_partition_unit[i]->set_icnt_power_stats(m_power_stats->pwr_mem_stat->n_mem_to_simt[0][i]);
+ }
}
if (clock_mask & ICNT) {
@@ -883,26 +999,58 @@ void gpgpu_sim::cycle()
for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) {
if (m_cluster[i]->get_not_completed() || get_more_cta_left() ) {
m_cluster[i]->core_cycle();
+ *active_sms+=m_cluster[i]->get_n_active_sms();
+
+ // Interconnect power stats: SIMT->MEM
+ m_cluster[i]->set_icnt_stats(m_power_stats->pwr_mem_stat->n_simt_to_mem[0][i]);
}
}
+ float temp=0;
+ for (unsigned i=0;i<m_shader_config->num_shader();i++){
+ temp+=m_shader_stats->m_pipeline_duty_cycle[i];
+ }
+ temp=temp/m_shader_config->num_shader();
+ *average_pipeline_duty_cycle=((*average_pipeline_duty_cycle)+temp);
+ //cout<<"Average pipeline duty cycle: "<<*average_pipeline_duty_cycle<<endl;
+
+
if( g_single_step && ((gpu_sim_cycle+gpu_tot_sim_cycle) >= g_single_step) ) {
asm("int $03");
}
gpu_sim_cycle++;
if( g_interactive_debugger_enabled )
gpgpu_debug();
-
+
+ // McPAT main cycle (interface with McPAT)
+#ifdef GPGPUSIM_POWER_MODEL
+ if(m_config.g_power_simulation_enabled){
+ mcpat_cycle(m_config, getShaderCoreConfig(), m_gpgpusim_wrapper, m_power_stats, m_config.gpu_stat_sample_freq, gpu_tot_sim_cycle, gpu_sim_cycle, gpu_tot_sim_insn, gpu_sim_insn);
+ }
+#endif
+
issue_block2core();
- // Flush the caches once all of threads are completed.
- if (m_config.gpgpu_flush_cache) {
- int all_threads_complete = 1 ;
+ // Depending on configuration, flush 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();
- else
- all_threads_complete = 0 ;
+ if (m_cluster[i]->get_not_completed() == 0)
+ m_cluster[i]->cache_flush();
+ else
+ all_threads_complete = 0 ;
}
+ }
+
+ if(m_config.gpgpu_flush_l2_cache){
+ 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){
+ all_threads_complete = 0 ;
+ break;
+ }
+ }
+ }
+
if (all_threads_complete && !m_memory_config->m_L2_config.disabled() ) {
printf("Flushed L2 caches...\n");
if (m_memory_config->m_L2_config.get_num_lines()) {
@@ -961,6 +1109,7 @@ void gpgpu_sim::cycle()
}
}
+
void shader_core_ctx::dump_warp_state( FILE *fout ) const
{
fprintf(fout, "\n");
diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h
index d5b810f..7866688 100644
--- a/src/gpgpu-sim/gpu-sim.h
+++ b/src/gpgpu-sim/gpu-sim.h
@@ -32,10 +32,14 @@
#include "../abstract_hardware_model.h"
#include "addrdec.h"
#include "shader.h"
+#include <iostream>
+#include <fstream>
#include <list>
#include <stdio.h>
+
+
// constants for statistics printouts
#define GPU_RSTAT_SHD_INFO 0x1
#define GPU_RSTAT_BW_STAT 0x2
@@ -58,11 +62,90 @@
#define SAMPLELOG 222
#define DUMPLOG 333
+
+
+
+
enum dram_ctrl_t {
DRAM_FIFO=0,
DRAM_FRFCFS=1
};
+
+struct power_config {
+ power_config()
+ {
+ m_valid = true;
+ }
+ void init()
+ {
+
+ if (!g_power_simulation_enabled)
+ return;
+
+ // initialize file name if it is not set
+ time_t curr_time;
+ time(&curr_time);
+ char *date = ctime(&curr_time);
+ char *s = date;
+ while (*s) {
+ if (*s == ' ' || *s == '\t' || *s == ':') *s = '-';
+ if (*s == '\n' || *s == '\r' ) *s = 0;
+ s++;
+ }
+ char buf1[1024];
+ snprintf(buf1,1024,"gpgpusim_power_report__%s.log",date);
+ g_power_filename = strdup(buf1);
+ char buf2[1024];
+ snprintf(buf2,1024,"gpgpusim_power_trace_report__%s.log.gz",date);
+ g_power_trace_filename = strdup(buf2);
+ char buf3[1024];
+ snprintf(buf3,1024,"gpgpusim_metric_trace_report__%s.log.gz",date);
+ g_metric_trace_filename = strdup(buf3);
+ char buf4[1024];
+ snprintf(buf4,1024,"gpgpusim_steady_state_tracking_report__%s.log.gz",date);
+ g_steady_state_tracking_filename = strdup(buf4);
+
+ if(g_steady_power_levels_enabled){
+ sscanf(gpu_steady_state_definition,"%lf:%lf", &gpu_steady_power_deviation,&gpu_steady_min_period);
+ }
+
+ //NOTE: After changing the nonlinear model to only scaling idle core,
+ //NOTE: The min_inc_per_active_sm is not used any more
+ if (g_use_nonlinear_model)
+ sscanf(gpu_nonlinear_model_config,"%lf:%lf", &gpu_idle_core_power,&gpu_min_inc_per_active_sm);
+
+ }
+ void reg_options(class OptionParser * opp);
+
+ char *g_power_config_name;
+
+ bool m_valid;
+ bool g_power_simulation_enabled;
+ bool g_power_trace_enabled;
+ bool g_steady_power_levels_enabled;
+ bool g_power_per_cycle_dump;
+ bool g_power_simulator_debug;
+ char *g_power_filename;
+ char *g_power_trace_filename;
+ char *g_metric_trace_filename;
+ char * g_steady_state_tracking_filename;
+ int g_power_trace_zlevel;
+ char * gpu_steady_state_definition;
+ double gpu_steady_power_deviation;
+ double gpu_steady_min_period;
+
+ //Nonlinear power model
+ bool g_use_nonlinear_model;
+ char * gpu_nonlinear_model_config;
+ double gpu_idle_core_power;
+ double gpu_min_inc_per_active_sm;
+
+
+};
+
+
+
struct memory_config {
memory_config()
{
@@ -124,6 +207,7 @@ struct memory_config {
m_address_mapping.init(m_n_mem);
m_L2_config.init();
m_valid = true;
+ icnt_flit_size = 32; // Default 32
}
void reg_options(class OptionParser * opp);
@@ -172,10 +256,11 @@ struct memory_config {
unsigned nbk;
unsigned data_command_freq_ratio; // frequency ratio between DRAM data bus and command bus (2 for GDDR3, 4 for GDDR5)
-
unsigned dram_atom_size; // number of bytes transferred per read or write command
linear_to_raw_address_translation m_address_mapping;
+
+ unsigned icnt_flit_size;
};
// global counters and flags (please try not to add to this list!!!)
@@ -183,7 +268,7 @@ extern unsigned long long gpu_sim_cycle;
extern unsigned long long gpu_tot_sim_cycle;
extern bool g_interactive_debugger_enabled;
-class gpgpu_sim_config : public gpgpu_functional_sim_config {
+class gpgpu_sim_config : public power_config, public gpgpu_functional_sim_config {
public:
gpgpu_sim_config() { m_valid = false; }
void reg_options(class OptionParser * opp);
@@ -192,10 +277,12 @@ public:
gpu_stat_sample_freq = 10000;
gpu_runtime_stat_flag = 0;
sscanf(gpgpu_runtime_stat, "%d:%x", &gpu_stat_sample_freq, &gpu_runtime_stat_flag);
- m_shader_config.init();
+ m_shader_config.init();
ptx_set_tex_cache_linesize(m_shader_config.m_L1T_config.get_line_sz());
m_memory_config.init();
init_clock_domains();
+ power_config::init();
+
// initialize file name if it is not set
time_t curr_time;
@@ -220,10 +307,10 @@ public:
private:
void init_clock_domains(void );
+
bool m_valid;
shader_core_config m_shader_config;
memory_config m_memory_config;
-
// clock domains - frequency
double core_freq;
double icnt_freq;
@@ -239,7 +326,8 @@ private:
unsigned gpu_max_insn_opt;
unsigned gpu_max_cta_opt;
char *gpgpu_runtime_stat;
- bool gpgpu_flush_cache;
+ bool gpgpu_flush_l1_cache;
+ bool gpgpu_flush_l2_cache;
bool gpu_deadlock_detect;
int gpgpu_dram_sched_queue_size;
int gpgpu_cflog_interval;
@@ -251,10 +339,14 @@ private:
char *g_visualizer_filename;
int g_visualizer_zlevel;
+
// statistics collection
int gpu_stat_sample_freq;
int gpu_runtime_stat_flag;
+
+
+
friend class gpgpu_sim;
};
@@ -276,6 +368,8 @@ public:
void update_stats();
void deadlock_check();
+ void get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc );
+
int shared_mem_size() const;
int num_registers_per_core() const;
int wrp_size() const;
@@ -288,7 +382,7 @@ public:
kernel_info_t *select_kernel();
const gpgpu_sim_config &get_config() const { return m_config; }
- void gpu_print_stat() const;
+ void gpu_print_stat();
void dump_pipeline( int mask, int s, int m ) const;
//The next three functions added to be used by the functional simulation function
@@ -313,12 +407,13 @@ public:
*/
simt_core_cluster * getSIMTCluster();
+
private:
// clocks
void reinit_clock_domains(void);
int next_clock_domain(void);
void issue_block2core();
-
+ void print_dram_L2_stats(FILE *fout) const;
void L2c_print_cache_stat() const;
void shader_print_runtime_stat( FILE *fout );
void shader_print_l1_miss_stat( FILE *fout ) const;
@@ -338,7 +433,8 @@ private:
std::list<unsigned> m_finished_kernel;
unsigned m_total_cta_launched;
unsigned m_last_cluster_issue;
-
+ float * average_pipeline_duty_cycle;
+ float * active_sms;
// time of next rising edge
double core_time;
double icnt_time;
@@ -358,14 +454,25 @@ private:
// stats
class shader_core_stats *m_shader_stats;
class memory_stats_t *m_memory_stats;
+ class power_stat_t *m_power_stats;
+#ifdef GPGPUSIM_POWER_MODEL
+ class gpgpu_sim_wrapper *m_gpgpusim_wrapper;
+#endif
unsigned long long gpu_tot_issued_cta;
unsigned long long last_gpu_sim_insn;
+
+
+
public:
unsigned long long gpu_sim_insn;
unsigned long long gpu_tot_sim_insn;
unsigned long long gpu_sim_insn_last_update;
unsigned gpu_sim_insn_last_update_sid;
+
+
+
+
};
#endif
diff --git a/src/gpgpu-sim/icnt_wrapper.cc b/src/gpgpu-sim/icnt_wrapper.cc
index 1c2ad86..f8c981d 100644
--- a/src/gpgpu-sim/icnt_wrapper.cc
+++ b/src/gpgpu-sim/icnt_wrapper.cc
@@ -34,6 +34,7 @@ icnt_push_p icnt_push;
icnt_pop_p icnt_pop;
icnt_transfer_p icnt_transfer;
icnt_busy_p icnt_busy;
+icnt_get_flit_size_p icnt_get_flit_size;
int g_network_mode;
char* g_network_config_filename;
@@ -56,6 +57,7 @@ void icnt_init( unsigned int n_shader, unsigned int n_mem )
icnt_pop = interconnect_pop;
icnt_transfer = advance_interconnect;
icnt_busy = interconnect_busy;
+ icnt_get_flit_size = interconnect_get_flit_size;
break;
default:
diff --git a/src/gpgpu-sim/icnt_wrapper.h b/src/gpgpu-sim/icnt_wrapper.h
index 6c30bff..f8e6baf 100644
--- a/src/gpgpu-sim/icnt_wrapper.h
+++ b/src/gpgpu-sim/icnt_wrapper.h
@@ -37,6 +37,8 @@ typedef void* (*icnt_pop_p)(unsigned output);
typedef void (*icnt_transfer_p)( );
typedef unsigned (*icnt_busy_p)( );
typedef void (*icnt_drain_p)( );
+typedef unsigned (*icnt_get_flit_size_p)();
+
extern icnt_has_buffer_p icnt_has_buffer;
extern icnt_push_p icnt_push;
@@ -44,6 +46,7 @@ extern icnt_pop_p icnt_pop;
extern icnt_transfer_p icnt_transfer;
extern icnt_busy_p icnt_busy;
extern icnt_drain_p icnt_drain;
+extern icnt_get_flit_size_p icnt_get_flit_size;
extern int g_network_mode;
enum network_mode {
diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc
index c03c47f..281da7f 100644
--- a/src/gpgpu-sim/l2cache.cc
+++ b/src/gpgpu-sim/l2cache.cc
@@ -109,6 +109,7 @@ void memory_partition_unit::cache_cycle( unsigned cycle )
mf->set_reply();
mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
m_L2_icnt_queue->push(mf);
+ n_mem_to_simt+=mf->get_num_flits(false); // Interconnect power stats (# of flits sent to the SMs)
}else{
m_request_tracker.erase(mf);
delete mf;
@@ -127,6 +128,7 @@ void memory_partition_unit::cache_cycle( unsigned cycle )
mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
m_L2_icnt_queue->push(mf);
m_dram_L2_queue->pop();
+ n_mem_to_simt+=mf->get_num_flits(false); // Interconnect power stats (# of flits sent to the SMs)
}
}
@@ -158,6 +160,7 @@ void memory_partition_unit::cache_cycle( unsigned cycle )
mf->set_reply();
mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
m_L2_icnt_queue->push(mf);
+ n_mem_to_simt+=mf->get_num_flits(false); // Interconnect power stats (# of flits sent to the SMs)
}
m_icnt_L2_queue->pop();
} else {
@@ -221,24 +224,75 @@ void memory_partition_unit::print( FILE *fp ) const
void memory_stats_t::print( FILE *fp )
{
- fprintf(fp,"L2_write_miss = %d\n", L2_write_miss);
- fprintf(fp,"L2_write_hit = %d\n", L2_write_hit);
- fprintf(fp,"L2_read_miss = %d\n", L2_read_miss);
- fprintf(fp,"L2_read_hit = %d\n", L2_read_hit);
+
+ fprintf(fp,"gpgpu_l2_write_miss = %d\n", L2_write_miss);
+ fprintf(fp,"gpgpu_l2_write_access = %d\n", L2_write_access);
+ fprintf(fp,"gpgpu_l2_read_miss = %d\n", L2_read_miss);
+ fprintf(fp,"gpgpu_l2_read_access = %d\n", L2_read_access);
+
}
void memory_stats_t::visualizer_print( gzFile visualizer_file )
{
gzprintf(visualizer_file, "Ltwowritemiss: %d\n", L2_write_miss);
- gzprintf(visualizer_file, "Ltwowritehit: %d\n", L2_write_hit);
+ gzprintf(visualizer_file, "Ltwowritehit: %d\n", L2_write_access-L2_write_miss);
gzprintf(visualizer_file, "Ltworeadmiss: %d\n", L2_read_miss);
- gzprintf(visualizer_file, "Ltworeadhit: %d\n", L2_read_hit);
- signed long long average_mf_latency = 0;
- if (mf_num_lat_pw)
- average_mf_latency = mf_tot_lat_pw / mf_num_lat_pw;
- gzprintf(visualizer_file, "averagemflatency: %lld\n", average_mf_latency);
+ gzprintf(visualizer_file, "Ltworeadhit: %d\n", L2_read_access-L2_read_miss);
+ if (num_mfs)
+ gzprintf(visualizer_file, "averagemflatency: %lld\n", mf_total_lat/num_mfs);
}
+void gpgpu_sim::print_dram_L2_stats(FILE *fout) const
+{
+
+ unsigned cmd=0;
+ unsigned activity=0;
+ unsigned nop=0;
+ unsigned act=0;
+ unsigned pre=0;
+ unsigned rd=0;
+ unsigned wr=0;
+ unsigned req=0;
+ unsigned l2_read_access=0;
+ unsigned l2_read_miss=0;
+ unsigned l2_write_access=0;
+ unsigned l2_write_miss=0;
+ unsigned tot_cmd=0;
+ unsigned tot_nop=0;
+ unsigned tot_act=0;
+ unsigned tot_pre=0;
+ unsigned tot_rd=0;
+ unsigned tot_wr=0;
+ unsigned tot_req=0;
+ unsigned tot_l2_read_access=0;
+ unsigned tot_l2_read_miss=0;
+ unsigned tot_l2_write_access=0;
+ unsigned tot_l2_write_miss=0;
+
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++){
+ m_memory_partition_unit[i]->set_dram_power_stats(cmd,activity,nop,act,pre,rd,wr,req);
+ m_memory_partition_unit[i]->set_L2cache_power_stats(l2_read_access,l2_read_miss,l2_write_access,l2_write_miss);
+ tot_cmd+=cmd;
+ tot_nop+=nop;
+ tot_act+=act;
+ tot_pre+=pre;
+ tot_rd+=rd;
+ tot_wr+=wr;
+ tot_req+=req;
+ tot_l2_read_access+=l2_read_access;
+ tot_l2_read_miss+=l2_read_miss;
+ tot_l2_write_access+=l2_write_access;
+ tot_l2_write_miss+=l2_write_miss;
+ }
+ fprintf(fout,"gpgpu_n_l2_cache_read_access = %d\n",tot_l2_read_access );
+ fprintf(fout,"gpgpu_n_l2_cache_read_miss = %d\n",tot_l2_read_miss );
+ fprintf(fout,"gpgpu_n_l2_cache_write_access = %d\n",tot_l2_write_access );
+ fprintf(fout,"gpgpu_n_l2_cache_write_miss = %d\n",tot_l2_write_miss );
+ fprintf(fout,"gpgpu_n_dram_reads = %d\n",tot_rd );
+ fprintf(fout,"gpgpu_n_dram_writes = %d\n",tot_wr );
+ fprintf(fout,"gpgpu_n_dram_activate = %d\n",tot_act );
+
+}
void gpgpu_sim::L2c_print_cache_stat() const
{
unsigned i, j, k;
@@ -341,3 +395,25 @@ void memory_partition_unit::dram_cycle()
m_dram->push(mf);
}
}
+
+void memory_partition_unit::set_dram_power_stats(unsigned &n_cmd,
+ unsigned &n_activity,
+ unsigned &n_nop,
+ unsigned &n_act,
+ unsigned &n_pre,
+ unsigned &n_rd,
+ unsigned &n_wr,
+ unsigned &n_req) const{
+ m_dram->set_dram_power_stats(n_cmd, n_activity, n_nop, n_act, n_pre, n_rd, n_wr, n_req);
+}
+
+void memory_partition_unit::set_L2cache_power_stats(unsigned &n_read_access,
+ unsigned &n_read_miss,
+ unsigned &n_write_access,
+ unsigned &n_write_miss) const{
+ m_L2cache->get_data_stats(n_read_access,n_read_miss,n_write_access,n_write_miss);
+}
+
+void memory_partition_unit::set_icnt_power_stats(unsigned &mem_to_simt) const{
+ mem_to_simt = n_mem_to_simt;
+}
diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h
index c2c624f..3b25565 100644
--- a/src/gpgpu-sim/l2cache.h
+++ b/src/gpgpu-sim/l2cache.h
@@ -77,6 +77,24 @@ public:
void visualize() const { m_dram->visualize(); }
void print( FILE *fp ) const;
+
+ // Power model
+ void set_dram_power_stats(unsigned &n_cmd,
+ unsigned &n_activity,
+ unsigned &n_nop,
+ unsigned &n_act,
+ unsigned &n_pre,
+ unsigned &n_rd,
+ unsigned &n_wr,
+ unsigned &n_req) const;
+
+ void set_L2cache_power_stats(unsigned &n_read_access,
+ unsigned &n_read_miss,
+ unsigned &n_write_access,
+ unsigned &n_write_miss) const;
+
+ void set_icnt_power_stats(unsigned &n_mem_to_simt) const;
+
private:
// data
unsigned m_id;
@@ -116,6 +134,9 @@ private:
std::set<mem_fetch*> m_request_tracker;
friend class L2interface;
+
+ // interconnect power stats
+ unsigned n_mem_to_simt;
};
class L2interface : public mem_fetch_interface {
diff --git a/src/gpgpu-sim/mem_fetch.cc b/src/gpgpu-sim/mem_fetch.cc
index 97721c0..1de10a5 100644
--- a/src/gpgpu-sim/mem_fetch.cc
+++ b/src/gpgpu-sim/mem_fetch.cc
@@ -60,6 +60,7 @@ mem_fetch::mem_fetch( const mem_access_t &access,
m_status = MEM_FETCH_INITIALIZED;
m_status_change = gpu_sim_cycle + gpu_tot_sim_cycle;
m_mem_config = config;
+ icnt_flit_size = config->icnt_flit_size;
}
mem_fetch::~mem_fetch()
@@ -119,3 +120,17 @@ bool mem_fetch::isconst() const
if( m_inst.empty() ) return false;
return (m_inst.space.get_type() == const_space) || (m_inst.space.get_type() == param_space_kernel);
}
+
+/// Returns number of flits traversing interconnect. simt_to_mem specifies the direction
+unsigned mem_fetch::get_num_flits(bool simt_to_mem){
+ unsigned sz=0;
+ if( (simt_to_mem && get_is_write()) || !(simt_to_mem || get_is_write()) )
+ sz = size();
+ else
+ sz = get_ctrl_size();
+
+ return (sz/icnt_flit_size) + ( (sz % icnt_flit_size)? 1:0);
+}
+
+
+
diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h
index 501d52a..c4ba0dc 100644
--- a/src/gpgpu-sim/mem_fetch.h
+++ b/src/gpgpu-sim/mem_fetch.h
@@ -79,6 +79,8 @@ public:
void set_data_size( unsigned size ) { m_data_size=size; }
unsigned get_ctrl_size() const { return m_ctrl_size; }
unsigned size() const { return m_data_size+m_ctrl_size; }
+ bool is_write() {return m_access.is_write();}
+ void set_addr(new_addr_type addr) { m_access.set_addr(addr); }
new_addr_type get_addr() const { return m_access.get_addr(); }
new_addr_type get_partition_addr() const { return m_partition_addr; }
bool get_is_write() const { return m_access.is_write(); }
@@ -100,11 +102,14 @@ public:
enum mem_access_type get_access_type() const { return m_access.get_type(); }
const active_mask_t& get_access_warp_mask() const { return m_access.get_warp_mask(); }
mem_access_byte_mask_t get_access_byte_mask() const { return m_access.get_byte_mask(); }
+
address_type get_pc() const { return m_inst.empty()?-1:m_inst.pc; }
const warp_inst_t &get_inst() { return m_inst; }
enum mem_fetch_status get_status() const { return m_status; }
const memory_config *get_mem_config(){return m_mem_config;}
+
+ unsigned get_num_flits(bool simt_to_mem);
private:
// request source information
unsigned m_request_uid;
@@ -135,6 +140,7 @@ private:
static unsigned sm_next_mf_request_uid;
const class memory_config *m_mem_config;
+ unsigned icnt_flit_size;
};
#endif
diff --git a/src/gpgpu-sim/mem_fetch_status.tup b/src/gpgpu-sim/mem_fetch_status.tup
index 328d517..b4d4e7a 100644
--- a/src/gpgpu-sim/mem_fetch_status.tup
+++ b/src/gpgpu-sim/mem_fetch_status.tup
@@ -31,7 +31,7 @@ MF_TUP_BEGIN( mem_fetch_status )
MF_TUP( IN_L1D_MISS_QUEUE ),
MF_TUP( IN_L1T_MISS_QUEUE ),
MF_TUP( IN_L1C_MISS_QUEUE ),
- MF_TUP( IN_TLB_MISS_QUEUE ),
+ MF_TUP( IN_L1TLB_MISS_QUEUE ),
MF_TUP( IN_VM_MANAGER_QUEUE ),
MF_TUP( IN_ICNT_TO_MEM ),
MF_TUP( IN_PARTITION_ROP_DELAY ),
diff --git a/src/gpgpu-sim/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc
index aed76aa..b86c652 100644
--- a/src/gpgpu-sim/mem_latency_stat.cc
+++ b/src/gpgpu-sim/mem_latency_stat.cc
@@ -66,7 +66,9 @@ memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_conf
m_n_shader=n_shader;
m_memory_config=mem_config;
-
+ total_n_access=0;
+ total_n_reads=0;
+ total_n_writes=0;
max_mrq_latency = 0;
max_dq_latency = 0;
max_mf_latency = 0;
@@ -123,8 +125,8 @@ memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_conf
}
L2_write_miss=0;
- L2_write_hit=0;
- L2_read_hit=0;
+ L2_write_access=0;
+ L2_read_access=0;
L2_read_miss=0;
L2_cbtoL2length = (unsigned int*) calloc(mem_config->m_n_mem, sizeof(unsigned int));
L2_cbtoL2writelength = (unsigned int*) calloc(mem_config->m_n_mem, sizeof(unsigned int));
diff --git a/src/gpgpu-sim/mem_latency_stat.h b/src/gpgpu-sim/mem_latency_stat.h
index 95017d8..83114fa 100644
--- a/src/gpgpu-sim/mem_latency_stat.h
+++ b/src/gpgpu-sim/mem_latency_stat.h
@@ -82,9 +82,9 @@ public:
// stats
+ unsigned L2_write_access;
unsigned L2_write_miss;
- unsigned L2_write_hit;
- unsigned L2_read_hit;
+ unsigned L2_read_access;
unsigned L2_read_miss;
unsigned int *L2_cbtoL2length;
unsigned int *L2_cbtoL2writelength;
@@ -98,6 +98,11 @@ public:
unsigned int **row_access; //row_access[dram chip id][bank id]
unsigned int **max_conc_access2samerow; //max_conc_access2samerow[dram chip id][bank id]
unsigned int **max_servicetime2samerow; //max_servicetime2samerow[dram chip id][bank id]
+
+ // Power stats
+ unsigned total_n_access;
+ unsigned total_n_reads;
+ unsigned total_n_writes;
};
#endif /*MEM_LATENCY_STAT_H*/
diff --git a/src/gpgpu-sim/power_interface.cc b/src/gpgpu-sim/power_interface.cc
new file mode 100644
index 0000000..4f8daca
--- /dev/null
+++ b/src/gpgpu-sim/power_interface.cc
@@ -0,0 +1,125 @@
+// Copyright (c) 2009-2011, Tor M. Aamodt, Ahmed El-Shafiey, Tayler Hetherington
+// The University of British Columbia
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+// Neither the name of The University of British Columbia nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "power_interface.h"
+
+void init_mcpat(const gpgpu_sim_config &config, class gpgpu_sim_wrapper *wrapper, unsigned stat_sample_freq, unsigned tot_inst, unsigned inst){
+
+ wrapper->init_mcpat(config.g_power_config_name, config.g_power_filename, config.g_power_trace_filename,
+ config.g_metric_trace_filename,config.g_steady_state_tracking_filename,config.g_power_simulation_enabled,
+ config.g_power_trace_enabled,config.g_steady_power_levels_enabled,config.g_power_per_cycle_dump,
+ config.gpu_steady_power_deviation,config.gpu_steady_min_period,config.g_power_trace_zlevel,
+ tot_inst+inst,stat_sample_freq
+ );
+
+}
+
+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){
+
+ static bool mcpat_init=true;
+
+ if(mcpat_init){ // If first cycle, don't have any power numbers yet
+ mcpat_init=false;
+ return;
+ }
+
+ if ((tot_cycle+cycle) % stat_sample_freq == 0) {
+
+ wrapper->set_inst_power(shdr_config->gpgpu_clock_gated_lanes,
+ stat_sample_freq, stat_sample_freq,
+ power_stats->get_total_inst(), power_stats->get_total_int_inst(),
+ power_stats->get_total_fp_inst(), power_stats->get_l1d_read_accesses(),
+ power_stats->get_l1d_write_accesses(), power_stats->get_committed_inst());
+
+ // Single RF for both int and fp ops
+ wrapper->set_regfile_power(power_stats->get_regfile_reads(), power_stats->get_regfile_writes(), power_stats->get_non_regfile_operands());
+
+ //Instruction cache stats
+ wrapper->set_icache_power(power_stats->get_inst_c_hits(), power_stats->get_inst_c_misses());
+
+ //Constant Cache, shared memory, texture cache
+ wrapper->set_ccache_power(power_stats->get_constant_c_hits(), power_stats->get_constant_c_misses());
+ wrapper->set_tcache_power(power_stats->get_texture_c_hits(), power_stats->get_texture_c_misses());
+ wrapper->set_shrd_mem_power(power_stats->get_shmem_read_access());
+
+ wrapper->set_l1cache_power(power_stats->get_l1d_read_hits(), power_stats->get_l1d_read_misses(),
+ power_stats->get_l1d_write_hits(), power_stats->get_l1d_write_misses());
+
+
+ wrapper->set_l2cache_power(power_stats->get_l2_read_hits(), power_stats->get_l2_read_misses(),
+ power_stats->get_l2_write_hits(), power_stats->get_l2_write_misses());
+
+
+ float active_sms=(*power_stats->m_active_sms)/stat_sample_freq;
+ float num_cores = shdr_config->num_shader();
+ float num_idle_core = num_cores - active_sms;
+ wrapper->set_idle_core_power(num_idle_core);
+
+ //pipeline power - pipeline_duty_cycle *= percent_active_sms;
+ float pipeline_duty_cycle=((*power_stats->m_average_pipeline_duty_cycle/( stat_sample_freq)) < 0.8)?((*power_stats->m_average_pipeline_duty_cycle)/stat_sample_freq):0.8;
+ wrapper->set_duty_cycle_power(pipeline_duty_cycle);
+
+ //Memory Controller
+ wrapper->set_mem_ctrl_power(power_stats->get_dram_rd(), power_stats->get_dram_wr(), power_stats->get_dram_pre());
+
+ //Execution pipeline accesses
+ //FPU (SP) accesses, Integer ALU (not present in Tesla), Sfu accesses
+ wrapper->set_exec_unit_power(power_stats->get_tot_fpu_accessess(), power_stats->get_ialu_accessess(), power_stats->get_tot_sfu_accessess());
+
+ //Average active lanes for sp and sfu pipelines
+ float avg_sp_active_lanes=(power_stats->get_sp_active_lanes())/stat_sample_freq;
+ float avg_sfu_active_lanes=(power_stats->get_sfu_active_lanes())/stat_sample_freq;
+ assert(avg_sp_active_lanes<=32);
+ assert(avg_sfu_active_lanes<=32);
+ wrapper->set_active_lanes_power((power_stats->get_sp_active_lanes())/stat_sample_freq,
+ (power_stats->get_sfu_active_lanes())/stat_sample_freq);
+
+
+ //NoC stats (32/4)--> Number of 32 bit words in 32B block
+ //unsigned l2cache_tot_access = power_stats->get_l2_read_accesses() + power_stats->get_l2_write_accesses();
+ unsigned n_icnt_simt_to_mem = power_stats->get_icnt_simt_to_mem(); // # flits from SIMT clusters to memory partitions
+ unsigned n_icnt_mem_to_simt = power_stats->get_icnt_mem_to_simt(); // # flits from memory partitions to SIMT clusters
+ //wrapper->set_NoC_power((double)(n_icnt_mem_to_simt + n_icnt_simt_to_mem)); // Number of flits traversing the interconnect
+ wrapper->set_NoC_power(n_icnt_mem_to_simt, n_icnt_simt_to_mem); // Number of flits traversing the interconnect
+
+ wrapper->compute();
+
+
+ wrapper->update_components_power();
+ wrapper->print_trace_files();
+ power_stats->save_stats();
+
+ wrapper->detect_print_steady_state(0,tot_inst+inst);
+
+ wrapper->power_metrics_calculations();
+
+
+ wrapper->dump();
+ }
+ //wrapper->close_files();
+}
+
diff --git a/src/gpgpu-sim/power_interface.h b/src/gpgpu-sim/power_interface.h
new file mode 100644
index 0000000..3033743
--- /dev/null
+++ b/src/gpgpu-sim/power_interface.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2009-2011, Tor M. Aamodt, Ahmed El-Shafiey, Tayler Hetherington
+// The University of British Columbia
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+// Neither the name of The University of British Columbia nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef POWER_INTERFACE_H_
+#define POWER_INTERFACE_H_
+
+#include "gpu-sim.h"
+#include "power_stat.h"
+#include "shader.h"
+
+
+#include "gpgpu_sim_wrapper.h"
+
+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);
+
+
+#endif /* POWER_INTERFACE_H_ */
diff --git a/src/gpgpu-sim/power_stat.cc b/src/gpgpu-sim/power_stat.cc
new file mode 100644
index 0000000..e1f4f8a
--- /dev/null
+++ b/src/gpgpu-sim/power_stat.cc
@@ -0,0 +1,335 @@
+// Copyright (c) 2009-2011, Tor M. Aamodt, Ahmed El-Shafiey, Tayler Hetherington
+// The University of British Columbia
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+// Neither the name of The University of British Columbia nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "../abstract_hardware_model.h"
+#include "power_stat.h"
+#include "gpu-sim.h"
+#include "gpu-misc.h"
+#include "shader.h"
+#include "mem_fetch.h"
+#include "stat-tool.h"
+#include "../cuda-sim/ptx-stats.h"
+#include "visualizer.h"
+#include "dram.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+
+power_mem_stat_t::power_mem_stat_t(const struct memory_config *mem_config, const struct shader_core_config *shdr_config, memory_stats_t *mem_stats, shader_core_stats *shdr_stats){
+ assert( mem_config->m_valid );
+ m_mem_stats = mem_stats;
+ m_config = mem_config;
+ m_core_stats = shdr_stats;
+ m_core_config = shdr_config;
+
+ init();
+}
+
+void power_mem_stat_t::init(){
+ inst_c_read_access[0] = m_core_stats->inst_c_read_access;
+ inst_c_read_miss[0] = m_core_stats->inst_c_read_miss;
+ const_c_read_access[0] = m_core_stats->const_c_read_access;
+ const_c_read_miss[0] = m_core_stats->const_c_read_miss;
+ text_c_read_access[0] = m_core_stats->text_c_read_access;
+ text_c_read_miss[0] = m_core_stats->text_c_read_miss;
+ l1d_read_access[0] = m_core_stats->l1d_read_access;
+ l1d_read_miss[0] = m_core_stats->l1d_read_miss;
+ l1d_write_access[0] = m_core_stats->l1d_write_access;
+ l1d_write_miss[0] = m_core_stats->l1d_write_miss;
+
+ shmem_read_access[0] = m_core_stats->gpgpu_n_shmem_bank_access; // Shared memory access
+
+ inst_c_read_access[1] = (unsigned *)calloc(m_core_config->num_shader(),sizeof(unsigned));
+ inst_c_read_miss[1] = (unsigned *)calloc(m_core_config->num_shader(),sizeof(unsigned));
+ const_c_read_access[1] = (unsigned *)calloc(m_core_config->num_shader(),sizeof(unsigned));
+ const_c_read_miss[1] = (unsigned *)calloc(m_core_config->num_shader(),sizeof(unsigned));
+ text_c_read_access[1] = (unsigned *)calloc(m_core_config->num_shader(),sizeof(unsigned));
+ text_c_read_miss[1] = (unsigned *)calloc(m_core_config->num_shader(),sizeof(unsigned));
+ l1d_read_access[1] = (unsigned *)calloc(m_core_config->num_shader(),sizeof(unsigned));
+ l1d_read_miss[1] = (unsigned *)calloc(m_core_config->num_shader(),sizeof(unsigned));
+ l1d_write_access[1] = (unsigned *)calloc(m_core_config->num_shader(),sizeof(unsigned));
+ l1d_write_miss[1] = (unsigned *)calloc(m_core_config->num_shader(),sizeof(unsigned));
+
+ shmem_read_access[1] = (unsigned *)calloc(m_core_config->num_shader(),sizeof(unsigned));
+
+ // Low-level DRAM/L2-cache stats
+ for(unsigned i=0; i<2; ++i){
+ n_l2_read_access[i] = (unsigned *)calloc(m_config->m_n_mem,sizeof(unsigned));
+ n_l2_read_miss[i] = (unsigned *)calloc(m_config->m_n_mem,sizeof(unsigned));
+ n_l2_write_access[i] = (unsigned *)calloc(m_config->m_n_mem,sizeof(unsigned));
+ n_l2_write_miss[i] = (unsigned *)calloc(m_config->m_n_mem,sizeof(unsigned));
+ n_cmd[i] = (unsigned *)calloc(m_config->m_n_mem,sizeof(unsigned));
+ n_activity[i] = (unsigned *)calloc(m_config->m_n_mem,sizeof(unsigned));
+ n_nop[i] = (unsigned *)calloc(m_config->m_n_mem,sizeof(unsigned));
+ n_act[i] = (unsigned *)calloc(m_config->m_n_mem,sizeof(unsigned));
+ n_pre[i] = (unsigned *)calloc(m_config->m_n_mem,sizeof(unsigned));
+ n_rd[i] = (unsigned *)calloc(m_config->m_n_mem,sizeof(unsigned));
+ n_wr[i] = (unsigned *)calloc(m_config->m_n_mem,sizeof(unsigned));
+ n_req[i] = (unsigned *)calloc(m_config->m_n_mem,sizeof(unsigned));
+
+ // Interconnect stats
+ n_mem_to_simt[i] = (unsigned *)calloc(m_config->m_n_mem,sizeof(unsigned)); // Counted at memory partition
+ n_simt_to_mem[i] = (unsigned *)calloc(m_core_config->num_shader(),sizeof(unsigned)); // Counted at SM
+ }
+}
+
+void power_mem_stat_t::save_stats(){
+ for(unsigned i=0; i<m_core_config->num_shader(); ++i){
+ inst_c_read_access[1][i] = inst_c_read_access[0][i] ;
+ inst_c_read_miss[1][i] = inst_c_read_miss[0][i] ;
+ const_c_read_access[1][i] = const_c_read_access[0][i] ;
+ const_c_read_miss[1][i] = const_c_read_miss[0][i] ;
+ text_c_read_access[1][i] = text_c_read_access[0][i] ;
+ text_c_read_miss[1][i] = text_c_read_miss[0][i] ;
+ l1d_read_access[1][i] = l1d_read_access[0][i] ;
+ l1d_read_miss[1][i] = l1d_read_miss[0][i] ;
+ l1d_write_access[1][i] = l1d_write_access[0][i] ;
+ l1d_write_miss[1][i] = l1d_write_miss[0][i] ;
+ shmem_read_access[1][i] = shmem_read_access[0][i] ; // Shared memory access
+
+ n_simt_to_mem[1][i] = n_simt_to_mem[0][i]; // Interconnect
+ }
+
+ for(unsigned i=0; i<m_config->m_n_mem; ++i){
+ n_l2_read_access[1][i] = n_l2_read_access[0][i];
+ n_l2_read_miss[1][i] = n_l2_read_miss[0][i];
+ n_l2_write_access[1][i] = n_l2_write_access[0][i];
+ n_l2_write_miss[1][i] = n_l2_write_miss[0][i];
+ n_cmd[1][i] = n_cmd[0][i];
+ n_activity[1][i] = n_activity[0][i];
+ n_nop[1][i] = n_nop[0][i];
+ n_act[1][i] = n_act[0][i];
+ n_pre[1][i] = n_pre[0][i];
+ n_rd[1][i] = n_rd[0][i];
+ n_wr[1][i] = n_wr[0][i];
+ n_req[1][i] = n_req[0][i];
+
+ n_mem_to_simt[1][i] = n_mem_to_simt[0][i]; // Interconnect
+ }
+}
+
+void power_mem_stat_t::visualizer_print( gzFile power_visualizer_file ){
+
+}
+
+void power_mem_stat_t::print (FILE *fout) const {
+ fprintf(fout, "\n\n==========Power Metrics -- Memory==========\n");
+ unsigned total_mem_reads=0;
+ unsigned total_mem_writes=0;
+ for(unsigned i=0; i<m_config->m_n_mem; ++i){
+ total_mem_reads += n_rd[0][i];
+ total_mem_writes += n_wr[0][i];
+ }
+ fprintf(fout, "Total memory controller accesses: %u\n", total_mem_reads+total_mem_writes);
+ fprintf(fout, "Total memory controller reads: %u\n", total_mem_reads);
+ fprintf(fout, "Total memory controller writes: %u\n", total_mem_writes);
+ for(unsigned i=0; i<m_core_config->num_shader(); ++i){
+ fprintf(fout, "Shader core %d\n", i);
+ fprintf(fout, "\tTotal instruction cache access: %u\n", inst_c_read_access[0][i]);
+ fprintf(fout, "\tTotal instruction cache miss: %u\n", inst_c_read_miss[0][i]);
+ fprintf(fout, "\tTotal constant cache access: %u\n", const_c_read_access[0][i]);
+ fprintf(fout, "\tTotal constant cache miss: %u\n", const_c_read_miss[0][i]);
+ fprintf(fout, "\tTotal texture cache access: %u\n", text_c_read_access[0][i]);
+ fprintf(fout, "\tTotal texture cache miss: %u\n", text_c_read_miss[0][i]);
+ fprintf(fout, "\tTotal l1d read access: %u\n", l1d_read_access[0][i]);
+ fprintf(fout, "\tTotal l1d read miss: %u\n", l1d_read_miss[0][i]);
+ fprintf(fout, "\tTotal l1d write access: %u\n", l1d_write_access[0][i]);
+ fprintf(fout, "\tTotal l1d write miss: %u\n", l1d_write_miss[0][i]);
+ fprintf(fout, "\tTotal shared memory access: %u\n", shmem_read_access[0][i]);
+ }
+}
+
+
+power_core_stat_t::power_core_stat_t( const struct shader_core_config *shader_config, shader_core_stats *core_stats )
+{
+ assert( shader_config->m_valid );
+ m_config = shader_config;
+ shader_core_power_stats_pod *pod = this;
+ memset(pod,0,sizeof(shader_core_power_stats_pod));
+ m_core_stats=core_stats;
+
+ init();
+
+}
+
+void power_core_stat_t::visualizer_print( gzFile visualizer_file )
+{
+
+}
+
+void power_core_stat_t::print (FILE *fout)
+{
+ // per core statistics
+ fprintf(fout,"Power Metrics: \n");
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ fprintf(fout,"core %u:\n",i);
+ fprintf(fout,"\tpipeline duty cycle =%f\n",m_pipeline_duty_cycle[0][i]);
+ fprintf(fout,"\tTotal Deocded Instructions=%u\n",m_num_decoded_insn[0][i]);
+ fprintf(fout,"\tTotal FP Deocded Instructions=%u\n",m_num_FPdecoded_insn[0][i]);
+ fprintf(fout,"\tTotal INT Deocded Instructions=%u\n",m_num_INTdecoded_insn[0][i]);
+ fprintf(fout,"\tTotal LOAD Queued Instructions=%u\n",m_num_loadqueued_insn[0][i]);
+ fprintf(fout,"\tTotal STORE Queued Instructions=%u\n",m_num_storequeued_insn[0][i]);
+ fprintf(fout,"\tTotal IALU Acesses=%u\n",m_num_ialu_acesses[0][i]);
+ fprintf(fout,"\tTotal FP Acesses=%u\n",m_num_fp_acesses[0][i]);
+ fprintf(fout,"\tTotal IMUL Acesses=%u\n",m_num_imul_acesses[0][i]);
+ fprintf(fout,"\tTotal IMUL24 Acesses=%u\n",m_num_imul24_acesses[0][i]);
+ fprintf(fout,"\tTotal IMUL32 Acesses=%u\n",m_num_imul32_acesses[0][i]);
+ fprintf(fout,"\tTotal IDIV Acesses=%u\n",m_num_idiv_acesses[0][i]);
+ fprintf(fout,"\tTotal FPMUL Acesses=%u\n",m_num_fpmul_acesses[0][i]);
+ fprintf(fout,"\tTotal SFU Acesses=%u\n",m_num_trans_acesses[0][i]);
+ fprintf(fout,"\tTotal FPDIV Acesses=%u\n",m_num_fpdiv_acesses[0][i]);
+ fprintf(fout,"\tTotal SFU Acesses=%u\n",m_num_sfu_acesses[0][i]);
+ fprintf(fout,"\tTotal SP Acesses=%u\n",m_num_sp_acesses[0][i]);
+ fprintf(fout,"\tTotal MEM Acesses=%u\n",m_num_mem_acesses[0][i]);
+ fprintf(fout,"\tTotal SFU Commissions=%u\n",m_num_sfu_committed[0][i]);
+ fprintf(fout,"\tTotal SP Commissions=%u\n",m_num_sp_committed[0][i]);
+ fprintf(fout,"\tTotal MEM Commissions=%u\n",m_num_mem_committed[0][i]);
+ fprintf(fout,"\tTotal REG Reads=%u\n",m_read_regfile_acesses[0][i]);
+ fprintf(fout,"\tTotal REG Writes=%u\n",m_write_regfile_acesses[0][i]);
+ fprintf(fout,"\tTotal NON REG=%u\n",m_non_rf_operands[0][i]);
+ }
+}
+void power_core_stat_t::init()
+{
+ m_pipeline_duty_cycle[0]=m_core_stats->m_pipeline_duty_cycle;
+ m_num_decoded_insn[0]=m_core_stats->m_num_decoded_insn;
+ m_num_FPdecoded_insn[0]=m_core_stats->m_num_FPdecoded_insn;
+ m_num_INTdecoded_insn[0]=m_core_stats->m_num_INTdecoded_insn;
+ m_num_storequeued_insn[0]=m_core_stats->m_num_storequeued_insn;
+ m_num_loadqueued_insn[0]=m_core_stats->m_num_loadqueued_insn;
+ m_num_ialu_acesses[0]=m_core_stats->m_num_ialu_acesses;
+ m_num_fp_acesses[0]=m_core_stats->m_num_fp_acesses;
+ m_num_imul_acesses[0]=m_core_stats->m_num_imul_acesses;
+ m_num_imul24_acesses[0]=m_core_stats->m_num_imul24_acesses;
+ m_num_imul32_acesses[0]=m_core_stats->m_num_imul32_acesses;
+ m_num_fpmul_acesses[0]=m_core_stats->m_num_fpmul_acesses;
+ m_num_idiv_acesses[0]=m_core_stats->m_num_idiv_acesses;
+ m_num_fpdiv_acesses[0]=m_core_stats->m_num_fpdiv_acesses;
+ m_num_sp_acesses[0]=m_core_stats->m_num_sp_acesses;
+ m_num_sfu_acesses[0]=m_core_stats->m_num_sfu_acesses;
+ m_num_trans_acesses[0]=m_core_stats->m_num_trans_acesses;
+ m_num_mem_acesses[0]=m_core_stats->m_num_mem_acesses;
+ m_num_sp_committed[0]=m_core_stats->m_num_sp_committed;
+ m_num_sfu_committed[0]=m_core_stats->m_num_sfu_committed;
+ m_num_mem_committed[0]=m_core_stats->m_num_mem_committed;
+ m_read_regfile_acesses[0]=m_core_stats->m_read_regfile_acesses;
+ m_write_regfile_acesses[0]=m_core_stats->m_write_regfile_acesses;
+ m_non_rf_operands[0]=m_core_stats->m_non_rf_operands;
+ m_active_sp_lanes[0]=m_core_stats->m_active_sp_lanes;
+ m_active_sfu_lanes[0]=m_core_stats->m_active_sfu_lanes;
+ m_num_tex_inst[0]=m_core_stats->m_num_tex_inst;
+
+
+ m_pipeline_duty_cycle[1]=(float*)calloc(m_config->num_shader(),sizeof(float));
+ m_num_decoded_insn[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_FPdecoded_insn[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_INTdecoded_insn[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_storequeued_insn[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_loadqueued_insn[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_ialu_acesses[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_fp_acesses[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_tex_inst[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_imul_acesses[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_imul24_acesses[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_imul32_acesses[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_fpmul_acesses[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_idiv_acesses[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_fpdiv_acesses[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_sp_acesses[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_sfu_acesses[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_trans_acesses[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_mem_acesses[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_sp_committed[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_sfu_committed[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_num_mem_committed[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_read_regfile_acesses[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_write_regfile_acesses[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_non_rf_operands[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_active_sp_lanes[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+ m_active_sfu_lanes[1]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
+}
+
+void power_core_stat_t::save_stats(){
+ for(unsigned i=0; i<m_config->num_shader(); ++i){
+ m_pipeline_duty_cycle[1][i]=m_pipeline_duty_cycle[0][i];
+ m_num_decoded_insn[1][i]= m_num_decoded_insn[0][i];
+ m_num_FPdecoded_insn[1][i]=m_num_FPdecoded_insn[0][i];
+ m_num_INTdecoded_insn[1][i]=m_num_INTdecoded_insn[0][i];
+ m_num_storequeued_insn[1][i]=m_num_storequeued_insn[0][i];
+ m_num_loadqueued_insn[1][i]=m_num_loadqueued_insn[0][i];
+ m_num_ialu_acesses[1][i]=m_num_ialu_acesses[0][i];
+ m_num_fp_acesses[1][i]=m_num_fp_acesses[0][i];
+ m_num_tex_inst[1][i]=m_num_tex_inst[0][i];
+ m_num_imul_acesses[1][i]=m_num_imul_acesses[0][i];
+ m_num_imul24_acesses[1][i]=m_num_imul24_acesses[0][i];
+ m_num_imul32_acesses[1][i]=m_num_imul32_acesses[0][i];
+ m_num_fpmul_acesses[1][i]=m_num_fpmul_acesses[0][i];
+ m_num_idiv_acesses[1][i]=m_num_idiv_acesses[0][i];
+ m_num_fpdiv_acesses[1][i]=m_num_fpdiv_acesses[0][i];
+ m_num_sp_acesses[1][i]=m_num_sp_acesses[0][i];
+ m_num_sfu_acesses[1][i]=m_num_sfu_acesses[0][i];
+ m_num_trans_acesses[1][i]=m_num_trans_acesses[0][i];
+ m_num_mem_acesses[1][i]=m_num_mem_acesses[0][i];
+ m_num_sp_committed[1][i]=m_num_sp_committed[0][i];
+ m_num_sfu_committed[1][i]=m_num_sfu_committed[0][i];
+ m_num_mem_committed[1][i]=m_num_mem_committed[0][i];
+ m_read_regfile_acesses[1][i]=m_read_regfile_acesses[0][i];
+ m_write_regfile_acesses[1][i]=m_write_regfile_acesses[0][i];
+ m_non_rf_operands[1][i]=m_non_rf_operands[0][i];
+ m_active_sp_lanes[1][i]=m_active_sp_lanes[0][i];
+ m_active_sfu_lanes[1][i]=m_active_sfu_lanes[0][i];
+ }
+}
+
+power_stat_t::power_stat_t( const struct shader_core_config *shader_config,float * average_pipeline_duty_cycle,float *active_sms,shader_core_stats * shader_stats, const struct memory_config *mem_config,memory_stats_t * memory_stats)
+{
+ assert( shader_config->m_valid );
+ assert( mem_config->m_valid );
+ pwr_core_stat= new power_core_stat_t(shader_config,shader_stats);
+ pwr_mem_stat= new power_mem_stat_t(mem_config,shader_config, memory_stats, shader_stats);
+ m_average_pipeline_duty_cycle=average_pipeline_duty_cycle;
+ m_active_sms=active_sms;
+ m_config = shader_config;
+ m_mem_config = mem_config;
+}
+
+void power_stat_t::visualizer_print( gzFile visualizer_file )
+{
+ pwr_core_stat->visualizer_print(visualizer_file);
+ pwr_mem_stat->visualizer_print(visualizer_file);
+}
+
+void power_stat_t::print (FILE *fout) const
+{
+ fprintf(fout,"average_pipeline_duty_cycle=%f\n",*m_average_pipeline_duty_cycle);
+ pwr_core_stat->print(fout);
+ pwr_mem_stat->print(fout);
+}
+
diff --git a/src/gpgpu-sim/power_stat.h b/src/gpgpu-sim/power_stat.h
new file mode 100644
index 0000000..299bf43
--- /dev/null
+++ b/src/gpgpu-sim/power_stat.h
@@ -0,0 +1,613 @@
+// Copyright (c) 2009-2011, Tor M. Aamodt, Ahmed El-Shafiey, Tayler Hetherington
+// The University of British Columbia
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+// Neither the name of The University of British Columbia nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef POWER_STAT_H
+#define POWER_STAT_H
+
+#include <stdio.h>
+#include <zlib.h>
+#include "mem_latency_stat.h"
+#include "shader.h"
+#include "gpu-sim.h"
+
+struct shader_core_power_stats_pod {
+ // [0] = Current stat, [1] = last reading
+ float *m_pipeline_duty_cycle[2];
+ unsigned *m_num_decoded_insn[2]; // number of instructions committed by this shader core
+ unsigned *m_num_FPdecoded_insn[2]; // number of instructions committed by this shader core
+ unsigned *m_num_INTdecoded_insn[2]; // number of instructions committed by this shader core
+ unsigned *m_num_storequeued_insn[2];
+ unsigned *m_num_loadqueued_insn[2];
+ unsigned *m_num_ialu_acesses[2];
+ unsigned *m_num_fp_acesses[2];
+ unsigned *m_num_tex_inst[2];
+ unsigned *m_num_imul_acesses[2];
+ unsigned *m_num_imul32_acesses[2];
+ unsigned *m_num_imul24_acesses[2];
+ unsigned *m_num_fpmul_acesses[2];
+ unsigned *m_num_idiv_acesses[2];
+ unsigned *m_num_fpdiv_acesses[2];
+ unsigned *m_num_sp_acesses[2];
+ unsigned *m_num_sfu_acesses[2];
+ unsigned *m_num_trans_acesses[2];
+ unsigned *m_num_mem_acesses[2];
+ unsigned *m_num_sp_committed[2];
+ unsigned *m_num_sfu_committed[2];
+ unsigned *m_num_mem_committed[2];
+ unsigned *m_active_sp_lanes[2];
+ unsigned *m_active_sfu_lanes[2];
+ unsigned *m_read_regfile_acesses[2];
+ unsigned *m_write_regfile_acesses[2];
+ unsigned *m_non_rf_operands[2];
+};
+
+class power_core_stat_t : public shader_core_power_stats_pod {
+public:
+ power_core_stat_t(const struct shader_core_config *shader_config, shader_core_stats *core_stats);
+ void visualizer_print( gzFile visualizer_file );
+ void print (FILE *fout);
+ void init();
+ void save_stats();
+
+private:
+ shader_core_stats * m_core_stats;
+ const shader_core_config *m_config;
+ float average_duty_cycle;
+
+
+};
+
+struct mem_power_stats_pod{
+ // [0] = Current stat, [1] = last reading
+ unsigned *inst_c_read_access[2]; // Instruction cache read access
+ unsigned *inst_c_read_miss[2]; // Instruction cache read miss
+ unsigned *const_c_read_access[2]; // Constant cache read access
+ unsigned *const_c_read_miss[2]; // Constant cache read miss
+ unsigned *text_c_read_access[2]; // Texture cache read access
+ unsigned *text_c_read_miss[2]; // Texture cache read miss
+ unsigned *l1d_read_access[2]; // L1 Data cache read access
+ unsigned *l1d_read_miss[2]; // L1 Data cache read miss
+ unsigned *l1d_write_access[2]; // L1 Data cache write access
+ unsigned *l1d_write_miss[2]; // L1 Data cache write miss
+ unsigned *shmem_read_access[2]; // Shared memory access
+
+ // Low level L2 stats
+ unsigned *n_l2_read_access[2];
+ unsigned *n_l2_read_miss[2];
+ unsigned *n_l2_write_access[2];
+ unsigned *n_l2_write_miss[2];
+
+ // Low level DRAM stats
+ unsigned *n_cmd[2];
+ unsigned *n_activity[2];
+ unsigned *n_nop[2];
+ unsigned *n_act[2];
+ unsigned *n_pre[2];
+ unsigned *n_rd[2];
+ unsigned *n_wr[2];
+ unsigned *n_req[2];
+
+ // Interconnect stats
+ unsigned *n_simt_to_mem[2];
+ unsigned *n_mem_to_simt[2];
+};
+
+
+
+class power_mem_stat_t : public mem_power_stats_pod{
+public:
+ power_mem_stat_t(const struct memory_config *mem_config, const struct shader_core_config *shdr_config, memory_stats_t *mem_stats, shader_core_stats *shdr_stats);
+ void visualizer_print( gzFile visualizer_file );
+ void print (FILE *fout) const;
+ void init();
+ void save_stats();
+private:
+ memory_stats_t *m_mem_stats;
+ shader_core_stats * m_core_stats;
+ const memory_config *m_config;
+ const shader_core_config *m_core_config;
+};
+
+
+class power_stat_t {
+public:
+ power_stat_t( const struct shader_core_config *shader_config,float * average_pipeline_duty_cycle,float * active_sms,shader_core_stats * shader_stats, const struct memory_config *mem_config,memory_stats_t * memory_stats);
+ void visualizer_print( gzFile visualizer_file );
+ void print (FILE *fout) const;
+ void save_stats(){
+ pwr_core_stat->save_stats();
+ pwr_mem_stat->save_stats();
+ *m_average_pipeline_duty_cycle=0;
+ *m_active_sms=0;
+ }
+
+ unsigned get_total_inst(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_decoded_insn[0][i]) - (pwr_core_stat->m_num_decoded_insn[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_total_int_inst(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_INTdecoded_insn[0][i]) - (pwr_core_stat->m_num_INTdecoded_insn[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_total_fp_inst(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_FPdecoded_insn[0][i]) - (pwr_core_stat->m_num_FPdecoded_insn[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_total_load_inst(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_loadqueued_insn[0][i]) - (pwr_core_stat->m_num_loadqueued_insn[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_total_store_inst(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_storequeued_insn[0][i]) - (pwr_core_stat->m_num_storequeued_insn[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_sp_committed_inst(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_sp_committed[0][i]) - (pwr_core_stat->m_num_sp_committed[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_sfu_committed_inst(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_sfu_committed[0][i]) - (pwr_core_stat->m_num_sfu_committed[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_mem_committed_inst(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_mem_committed[0][i]) - (pwr_core_stat->m_num_mem_committed[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_committed_inst(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_mem_committed[0][i]) - (pwr_core_stat->m_num_mem_committed[1][i])
+ +(pwr_core_stat->m_num_sfu_committed[0][i]) - (pwr_core_stat->m_num_sfu_committed[1][i])
+ +(pwr_core_stat->m_num_sp_committed[0][i]) - (pwr_core_stat->m_num_sp_committed[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_regfile_reads(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_read_regfile_acesses[0][i]) - (pwr_core_stat->m_read_regfile_acesses[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_regfile_writes(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_write_regfile_acesses[0][i]) - (pwr_core_stat->m_write_regfile_acesses[1][i]);
+ }
+ return total_inst;
+ }
+
+ float get_pipeline_duty(){
+ float total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_pipeline_duty_cycle[0][i]) - (pwr_core_stat->m_pipeline_duty_cycle[1][i]);
+ }
+ return total_inst;
+ }
+
+ unsigned get_non_regfile_operands(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_non_rf_operands[0][i]) - (pwr_core_stat->m_non_rf_operands[1][i]);
+ }
+ return total_inst;
+ }
+
+ unsigned get_sp_accessess(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_sp_acesses[0][i]) - (pwr_core_stat->m_num_sp_acesses[1][i]);
+ }
+ return total_inst;
+ }
+
+ unsigned get_sfu_accessess(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_sfu_acesses[0][i]) - (pwr_core_stat->m_num_sfu_acesses[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_trans_accessess(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_trans_acesses[0][i]) - (pwr_core_stat->m_num_trans_acesses[1][i]);
+ }
+ return total_inst;
+ }
+
+ unsigned get_mem_accessess(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_mem_acesses[0][i]) - (pwr_core_stat->m_num_mem_acesses[1][i]);
+ }
+ return total_inst;
+ }
+
+ unsigned get_intdiv_accessess(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_idiv_acesses[0][i]) - (pwr_core_stat->m_num_idiv_acesses[1][i]);
+ }
+ return total_inst;
+ }
+
+ unsigned get_fpdiv_accessess(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_fpdiv_acesses[0][i]) - (pwr_core_stat->m_num_fpdiv_acesses[1][i]);
+ }
+ return total_inst;
+ }
+
+ unsigned get_intmul32_accessess(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_imul32_acesses[0][i]) - (pwr_core_stat->m_num_imul32_acesses[1][i]);
+ }
+ return total_inst;
+ }
+
+ unsigned get_intmul24_accessess(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_imul24_acesses[0][i]) - (pwr_core_stat->m_num_imul24_acesses[1][i]);
+ }
+ return total_inst;
+ }
+
+ unsigned get_intmul_accessess(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_imul_acesses[0][i]) - (pwr_core_stat->m_num_imul_acesses[1][i])+
+ (pwr_core_stat->m_num_imul24_acesses[0][i]) - (pwr_core_stat->m_num_imul24_acesses[1][i])+
+ (pwr_core_stat->m_num_imul32_acesses[0][i]) - (pwr_core_stat->m_num_imul32_acesses[1][i]);
+ }
+ return total_inst;
+ }
+
+ unsigned get_fpmul_accessess(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_fp_acesses[0][i]) - (pwr_core_stat->m_num_fp_acesses[1][i]);
+ }
+ return total_inst;
+ }
+
+ float get_sp_active_lanes(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_active_sp_lanes[0][i]) - (pwr_core_stat->m_active_sp_lanes[1][i]);
+ }
+ return (total_inst/m_config->num_shader())/m_config->gpgpu_num_sp_units;
+ }
+
+ float get_sfu_active_lanes(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_active_sfu_lanes[0][i]) - (pwr_core_stat->m_active_sfu_lanes[1][i]); }
+
+ return (total_inst/m_config->num_shader())/m_config->gpgpu_num_sfu_units;
+ }
+
+ unsigned get_tot_fpu_accessess(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_fp_acesses[0][i]) - (pwr_core_stat->m_num_fp_acesses[1][i])+
+ (pwr_core_stat->m_num_fpdiv_acesses[0][i]) - (pwr_core_stat->m_num_fpdiv_acesses[1][i])+
+ (pwr_core_stat->m_num_fpmul_acesses[0][i]) - (pwr_core_stat->m_num_fpmul_acesses[1][i])+
+ (pwr_core_stat->m_num_imul24_acesses[0][i]) - (pwr_core_stat->m_num_imul24_acesses[1][i])+
+ (pwr_core_stat->m_num_imul_acesses[0][i]) - (pwr_core_stat->m_num_imul_acesses[1][i]) ;
+ //printf("imul_accesses0: %d imul_acccesses1: %d imul0 - imul1: %d\n",(pwr_core_stat->m_num_imul_acesses[0][i]),(pwr_core_stat->m_num_imul_acesses[1][i]),(pwr_core_stat->m_num_imul_acesses[0][i]-pwr_core_stat->m_num_imul_acesses[1][i]));
+ //printf("imul24_accesses0: %d imul24_acccesses1: %d imu24l0 - imul241: %d\n",(pwr_core_stat->m_num_imul24_acesses[0][i]),(pwr_core_stat->m_num_imul24_acesses[1][i]),(pwr_core_stat->m_num_imul24_acesses[0][i]-pwr_core_stat->m_num_imul24_acesses[1][i]));
+ //printf("total_insn:%d\n",total_inst);
+
+
+ }
+ total_inst += get_total_load_inst()+get_total_store_inst()+get_tex_inst();
+ return total_inst;
+ }
+
+ unsigned get_tot_sfu_accessess(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=
+ (pwr_core_stat->m_num_idiv_acesses[0][i]) - (pwr_core_stat->m_num_idiv_acesses[1][i])+
+ (pwr_core_stat->m_num_imul32_acesses[0][i]) - (pwr_core_stat->m_num_imul32_acesses[1][i])+
+ (pwr_core_stat->m_num_trans_acesses[0][i]) - (pwr_core_stat->m_num_trans_acesses[1][i]);
+ }
+ return total_inst;
+ }
+
+ unsigned get_ialu_accessess(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_ialu_acesses[0][i]) - (pwr_core_stat->m_num_ialu_acesses[1][i]);
+ }
+ return total_inst;
+ }
+
+ unsigned get_tex_inst(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_core_stat->m_num_tex_inst[0][i]) - (pwr_core_stat->m_num_tex_inst[1][i]);
+ }
+ return total_inst;
+ }
+
+ unsigned get_constant_c_accesses(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_mem_stat->const_c_read_access[0][i]) - (pwr_mem_stat->const_c_read_access[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_constant_c_misses(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_mem_stat->const_c_read_miss[0][i]) - (pwr_mem_stat->const_c_read_miss[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_constant_c_hits(){
+ return (get_constant_c_accesses()-get_constant_c_misses());
+ }
+ unsigned get_texture_c_accesses(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_mem_stat->text_c_read_access[0][i]) - (pwr_mem_stat->text_c_read_access[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_texture_c_misses(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_mem_stat->text_c_read_miss[0][i]) - (pwr_mem_stat->text_c_read_miss[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_texture_c_hits(){
+ return ( get_texture_c_accesses()- get_texture_c_misses());
+ }
+ unsigned get_inst_c_accesses(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_mem_stat->inst_c_read_access[0][i]) - (pwr_mem_stat->inst_c_read_access[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_inst_c_misses(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_mem_stat->inst_c_read_miss[0][i]) - (pwr_mem_stat->inst_c_read_miss[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_inst_c_hits(){
+ return (get_inst_c_accesses()-get_inst_c_misses());
+ }
+ unsigned get_l1d_read_accesses(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_mem_stat->l1d_read_access[0][i]) - (pwr_mem_stat->l1d_read_access[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_l1d_read_misses(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_mem_stat->l1d_read_miss[0][i]) - (pwr_mem_stat->l1d_read_miss[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_l1d_read_hits(){
+ return (get_l1d_read_accesses()-get_l1d_read_misses());
+ }
+ unsigned get_l1d_write_accesses(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_mem_stat->l1d_write_access[0][i]) - (pwr_mem_stat->l1d_write_access[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_l1d_write_misses(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_mem_stat->l1d_write_miss[0][i]) - (pwr_mem_stat->l1d_write_miss[1][i]);
+ }
+ return total_inst;
+ }
+ unsigned get_l1d_write_hits(){
+ return (get_l1d_write_accesses()-get_l1d_write_misses());
+ }
+ unsigned get_cache_misses(){
+ return get_l1d_read_misses()+get_constant_c_misses()+get_l1d_write_misses()+
+ get_texture_c_misses();
+ }
+
+ unsigned get_cache_read_misses(){
+ return get_l1d_read_misses()+get_constant_c_misses()+
+ get_texture_c_misses();
+ }
+
+ unsigned get_cache_write_misses(){
+ return get_l1d_write_misses();
+ }
+
+ unsigned get_shmem_read_access(){
+ unsigned total_inst=0;
+ for(unsigned i=0; i<m_config->num_shader();i++){
+ total_inst+=(pwr_mem_stat->shmem_read_access[0][i]) - (pwr_mem_stat->shmem_read_access[1][i]);
+ }
+ return total_inst;
+ }
+
+ unsigned get_l2_read_accesses(){
+ unsigned total=0;
+ for(unsigned i=0; i<m_mem_config->m_n_mem; ++i){
+ total += (pwr_mem_stat->n_l2_read_access[0][i] - pwr_mem_stat->n_l2_read_access[1][i]);
+ }
+ return total;
+ }
+
+ unsigned get_l2_read_misses(){
+ unsigned total=0;
+ for(unsigned i=0; i<m_mem_config->m_n_mem; ++i){
+ total += (pwr_mem_stat->n_l2_read_miss[0][i] - pwr_mem_stat->n_l2_read_miss[1][i]);
+ }
+ return total;
+ }
+
+ unsigned get_l2_read_hits(){
+ return (get_l2_read_accesses()-get_l2_read_misses());
+ }
+
+ unsigned get_l2_write_accesses(){
+ unsigned total=0;
+ for(unsigned i=0; i<m_mem_config->m_n_mem; ++i){
+ total += (pwr_mem_stat->n_l2_write_access[0][i] - pwr_mem_stat->n_l2_write_access[1][i]);
+ }
+ return total;
+ }
+
+ unsigned get_l2_write_misses(){
+ unsigned total=0;
+ for(unsigned i=0; i<m_mem_config->m_n_mem; ++i){
+ total += (pwr_mem_stat->n_l2_write_miss[0][i] - pwr_mem_stat->n_l2_write_miss[1][i]);
+ }
+ return total;
+ }
+ unsigned get_l2_write_hits(){
+ return (get_l2_write_accesses()-get_l2_write_misses());
+ }
+ unsigned get_dram_cmd(){
+ unsigned total=0;
+ for(unsigned i=0; i<m_mem_config->m_n_mem; ++i){
+ total += (pwr_mem_stat->n_cmd[0][i] - pwr_mem_stat->n_cmd[1][i]);
+ }
+ return total;
+ }
+ unsigned get_dram_activity(){
+ unsigned total=0;
+ for(unsigned i=0; i<m_mem_config->m_n_mem; ++i){
+ total += (pwr_mem_stat->n_activity[0][i] - pwr_mem_stat->n_activity[1][i]);
+ }
+ return total;
+ }
+ unsigned get_dram_nop(){
+ unsigned total=0;
+ for(unsigned i=0; i<m_mem_config->m_n_mem; ++i){
+ total += (pwr_mem_stat->n_nop[0][i] - pwr_mem_stat->n_nop[1][i]);
+ }
+ return total;
+ }
+ unsigned get_dram_act(){
+ unsigned total=0;
+ for(unsigned i=0; i<m_mem_config->m_n_mem; ++i){
+ total += (pwr_mem_stat->n_act[0][i] - pwr_mem_stat->n_act[1][i]);
+ }
+ return total;
+ }
+ unsigned get_dram_pre(){
+ unsigned total=0;
+ for(unsigned i=0; i<m_mem_config->m_n_mem; ++i){
+ total += (pwr_mem_stat->n_pre[0][i] - pwr_mem_stat->n_pre[1][i]);
+ }
+ return total;
+ }
+ unsigned get_dram_rd(){
+ unsigned total=0;
+ for(unsigned i=0; i<m_mem_config->m_n_mem; ++i){
+ total += (pwr_mem_stat->n_rd[0][i] - pwr_mem_stat->n_rd[1][i]);
+ }
+ return total;
+ }
+ unsigned get_dram_wr(){
+ unsigned total=0;
+ for(unsigned i=0; i<m_mem_config->m_n_mem; ++i){
+ total += (pwr_mem_stat->n_wr[0][i] - pwr_mem_stat->n_wr[1][i]);
+ }
+ return total;
+ }
+ unsigned get_dram_req(){
+ unsigned total=0;
+ for(unsigned i=0; i<m_mem_config->m_n_mem; ++i){
+ total += (pwr_mem_stat->n_req[0][i] - pwr_mem_stat->n_req[1][i]);
+ }
+ return total;
+ }
+
+ unsigned get_icnt_simt_to_mem(){
+ unsigned total=0;
+ for(unsigned i=0; i<m_config->num_shader(); ++i){
+ total += (pwr_mem_stat->n_simt_to_mem[0][i] - pwr_mem_stat->n_simt_to_mem[1][i]);
+ }
+ return total;
+ }
+
+ unsigned get_icnt_mem_to_simt(){
+ unsigned total=0;
+ for(unsigned i=0; i<m_mem_config->m_n_mem; ++i){
+ total += (pwr_mem_stat->n_mem_to_simt[0][i] - pwr_mem_stat->n_mem_to_simt[1][i]);
+ }
+ return total;
+ }
+
+ power_core_stat_t * pwr_core_stat;
+ power_mem_stat_t * pwr_mem_stat;
+ float * m_average_pipeline_duty_cycle;
+ float * m_active_sms;
+ const shader_core_config *m_config;
+ const struct memory_config *m_mem_config;
+};
+
+
+#endif /*POWER_LATENCY_STAT_H*/
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index fb8165f..4095cbc 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -209,13 +209,13 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
//m_fu = new simd_function_unit*[m_num_function_units];
for (int k = 0; k < m_config->gpgpu_num_sp_units; k++) {
- m_fu.push_back(new sp_unit( &m_pipeline_reg[EX_WB], m_config ));
+ m_fu.push_back(new sp_unit( &m_pipeline_reg[EX_WB], m_config, this ));
m_dispatch_port.push_back(ID_OC_SP);
m_issue_port.push_back(OC_EX_SP);
}
for (int k = 0; k < m_config->gpgpu_num_sfu_units; k++) {
- m_fu.push_back(new sfu( &m_pipeline_reg[EX_WB], m_config ));
+ m_fu.push_back(new sfu( &m_pipeline_reg[EX_WB], m_config, this ));
m_dispatch_port.push_back(ID_OC_SFU);
m_issue_port.push_back(OC_EX_SFU);
}
@@ -289,13 +289,63 @@ address_type shader_core_ctx::next_pc( int tid ) const
return the_thread->get_pc(); // PC should already be updatd to next PC at this point (was set in shader_decode() last time thread ran)
}
+void gpgpu_sim::get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc )
+{
+ unsigned cluster_id = m_shader_config->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 ) const
+{
+ unsigned warp_id = tid/m_config->warp_size;
+ m_simt_stack[warp_id]->get_pdom_stack_top_info(pc,rpc);
+}
+
void shader_core_stats::print( FILE* fout ) const
{
- unsigned icount_uarch=0;
+ unsigned long long thread_icount_uarch=0;
+ unsigned long long warp_icount_uarch=0;
+ unsigned l1_dcache_read_hits=0;
+ unsigned l1_dcache_read_misses=0;
+ unsigned l1_dcache_write_accesses=0;
+ unsigned l1_dcache_write_misses=0;
+ unsigned icache_hits=0;
+ unsigned icache_misses=0;
+ unsigned ccache_hits=0;
+ unsigned ccache_misses=0;
+ unsigned tcache_hits=0;
+ unsigned tcache_misses=0;
+
+
+
for(unsigned i=0; i < m_config->num_shader(); i++) {
- icount_uarch += m_num_sim_insn[i];
+ thread_icount_uarch += m_num_sim_insn[i];
+ warp_icount_uarch += m_num_sim_winsn[i];
+ l1_dcache_read_hits += l1d_read_access[i]-l1d_read_miss[i];
+ l1_dcache_write_accesses += l1d_write_access[i];
+ l1_dcache_read_misses += l1d_read_miss[i];
+ l1_dcache_write_misses += l1d_write_miss[i];
+ icache_hits+=inst_c_read_access[i]-inst_c_read_miss[i];
+ icache_misses+=inst_c_read_miss[i];
+ tcache_hits+=text_c_read_access[i]-text_c_read_miss[i];
+ tcache_misses+=text_c_read_miss[i];
+ ccache_hits+=const_c_read_access[i]-const_c_read_miss[i];
+ ccache_misses+=const_c_read_miss[i];
}
- fprintf(fout,"gpgpu_n_tot_icount = %u\n", icount_uarch);
+ fprintf(fout,"gpgpu_n_tot_thrd_icount = %lld\n", thread_icount_uarch);
+ fprintf(fout,"gpgpu_n_tot_w_icount = %lld\n", warp_icount_uarch);
+ fprintf(fout,"gpgpu_n_icache_hits = %d\n", icache_hits );
+ fprintf(fout,"gpgpu_n_icache_misses = %d\n", icache_misses );
+ fprintf(fout,"gpgpu_n_l1dcache_read_hits = %d\n", l1_dcache_read_hits );
+ fprintf(fout,"gpgpu_n_l1dcache_read_misses = %d\n", l1_dcache_read_misses );
+ fprintf(fout,"gpgpu_n_l1dcache_write_accesses = %d\n", l1_dcache_write_accesses );
+ fprintf(fout,"gpgpu_n_l1dcache_wirte_misses = %d\n", l1_dcache_write_misses );
+ fprintf(fout,"gpgpu_n_tcache_hits = %d\n", tcache_hits );
+ fprintf(fout,"gpgpu_n_tcache_misses = %d\n", tcache_misses );
+ fprintf(fout,"gpgpu_n_ccache_hits = %d\n", ccache_hits );
+ fprintf(fout,"gpgpu_n_ccache_misses = %d\n", ccache_misses);
+
+
fprintf(fout,"gpgpu_n_stall_shd_mem = %d\n", gpgpu_n_stall_shd_mem );
fprintf(fout,"gpgpu_n_mem_read_local = %d\n", gpgpu_n_mem_read_local);
fprintf(fout,"gpgpu_n_mem_write_local = %d\n", gpgpu_n_mem_write_local);
@@ -407,7 +457,7 @@ void shader_core_stats::visualizer_print( gzFile visualizer_file )
gzprintf(visualizer_file, "\n");
// warp instruction count per shader core
gzprintf(visualizer_file, "shaderwarpinsncount: ");
- for (unsigned i=0;i<m_config->num_shader();i++)
+ for (unsigned i=0;i<m_config->num_shader();i++)
gzprintf(visualizer_file, "%u ", m_num_sim_winsn[i] );
gzprintf(visualizer_file, "\n");
// warp divergence per shader core
@@ -429,10 +479,22 @@ void shader_core_ctx::decode()
m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(0,pI1);
m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline();
if( pI1 ) {
+ m_stats->m_num_decoded_insn[m_sid]++;
+ if(pI1->op2==INT_OP){
+ m_stats->m_num_INTdecoded_insn[m_sid]++;
+ }else if(pI1->op2==FP_OP) {
+ m_stats->m_num_FPdecoded_insn[m_sid]++;
+ }
const warp_inst_t* pI2 = ptx_fetch_inst(pc+pI1->isize);
if( pI2 ) {
m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(1,pI2);
m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline();
+ m_stats->m_num_decoded_insn[m_sid]++;
+ if(pI2->op2==INT_OP){
+ m_stats->m_num_INTdecoded_insn[m_sid]++;
+ }else if(pI2->op2==FP_OP) {
+ m_stats->m_num_FPdecoded_insn[m_sid]++;
+ }
}
}
m_inst_fetch_buffer.m_valid = false;
@@ -508,6 +570,9 @@ void shader_core_ctx::fetch()
m_L1I->cycle();
+ // Power stats
+ m_L1I->get_stats(m_stats->inst_c_read_access[m_sid], m_stats->inst_c_read_miss[m_sid]);
+ assert(m_stats->inst_c_read_access[m_sid]>=m_stats->inst_c_read_miss[m_sid]);
if( m_L1I->access_ready() ) {
mem_fetch *mf = m_L1I->next_access();
m_warp[mf->get_wid()].clear_imiss_pending();
@@ -841,6 +906,7 @@ void shader_core_ctx::execute()
unsigned multiplier = m_fu[n]->clock_multiplier();
for( unsigned c=0; c < multiplier; c++ )
m_fu[n]->cycle();
+ m_fu[n]->active_lanes_in_pipeline();
enum pipeline_stage_name_t issue_port = m_issue_port[n];
register_set& issue_inst = m_pipeline_reg[ issue_port ];
warp_inst_t** ready_reg = issue_inst.get_ready();
@@ -866,20 +932,93 @@ void ldst_unit::print_cache_stats( FILE *fp, unsigned& dl1_accesses, unsigned& d
}
}
-void shader_core_ctx::warp_inst_complete(const warp_inst_t &inst)
+void ldst_unit::get_cache_stats(unsigned &read_accesses, unsigned &write_accesses, unsigned &read_misses, unsigned &write_misses, unsigned cache_type){
+ switch(cache_type){
+ default:
+ case 0: // L1D
+ if( m_L1D ) {
+ //m_L1D->get_stats(accesses, misses);
+ m_L1D->get_data_stats(read_accesses,read_misses,write_accesses, write_misses);
+ }
+ break;
+ case 1:
+ if( m_L1C ){
+ m_L1C->get_stats(read_accesses, read_misses);
+ }
+ break;
+ case 2:
+ if( m_L1T ){
+ m_L1T->get_stats(read_accesses, read_misses);
+ }
+ }
+}
+
+void ldst_unit::set_stats(){
+ // Sets the cache stats in m_stats
+ if( m_L1D ) {
+ m_L1D->get_data_stats(m_stats->l1d_read_access[m_sid], m_stats->l1d_read_miss[m_sid],m_stats->l1d_write_access[m_sid], m_stats->l1d_write_miss[m_sid]);
+ }
+ if( m_L1C ){
+ m_L1C->get_stats(m_stats->const_c_read_access[m_sid], m_stats->const_c_read_miss[m_sid]);
+ }
+ if( m_L1T ){
+ m_L1T->get_stats(m_stats->text_c_read_access[m_sid], m_stats->text_c_read_miss[m_sid]);
+ }
+}
+
+void ldst_unit::set_icnt_power_stats(unsigned &simt_to_mem) const{
+ unsigned l1d=0;
+ unsigned tex=0;
+ unsigned l1c=0;
+
+ m_L1D->set_icnt_power_stats(l1d);
+ m_L1T->set_icnt_power_stats(tex);
+ m_L1C->set_icnt_power_stats(l1c);
+
+ simt_to_mem = n_simt_to_mem+l1d+tex+l1c; // All components that push packets into the interconnect
+}
+
+void shader_core_ctx::warp_inst_complete(const warp_inst_t &inst, bool memory)
{
#if 0
printf("[warp_inst_complete] uid=%u core=%u warp=%u pc=%#x @ time=%llu issued@%llu\n",
inst.get_uid(), m_sid, inst.warp_id(), inst.pc, gpu_tot_sim_cycle + gpu_sim_cycle, inst.get_issue_cycle());
#endif
- m_stats->m_num_sim_insn[m_sid] += inst.issued_count();
- m_stats->m_num_sim_winsn[m_sid]++;
- m_gpu->gpu_sim_insn += inst.issued_count();
- inst.completed(gpu_tot_sim_cycle + gpu_sim_cycle);
+ if(inst.op4==SP__OP)
+ m_stats->m_num_sp_committed[m_sid]++;
+ else if(inst.op4==SFU__OP)
+ m_stats->m_num_sfu_committed[m_sid]++;
+ else if(inst.op4==MEM__OP)
+ m_stats->m_num_mem_committed[m_sid]++;
+
+ if(memory==0){
+ m_stats->m_num_sim_insn[m_sid] += inst.active_count();
+ m_stats->m_num_sim_winsn[m_sid]++;
+ }
+ m_gpu->gpu_sim_insn += inst.active_count();
+ inst.completed(gpu_tot_sim_cycle + gpu_sim_cycle);
}
void shader_core_ctx::writeback()
{
+ if(m_config->gpgpu_clock_gated_lanes==false){
+ m_stats->m_pipeline_duty_cycle[m_sid]=roundUp((m_stats->m_num_sim_insn[m_sid]-m_stats->m_last_num_sim_insn[m_sid])/(64.0));
+ } else {
+ m_stats->m_pipeline_duty_cycle[m_sid]=(m_stats->m_num_sim_insn[m_sid]-m_stats->m_last_num_sim_insn[m_sid])/(64.0);
+ }
+
+ //assert(m_stats->m_pipeline_duty_cycle[m_sid]<=4*32);
+ if((m_stats->m_num_sim_winsn[m_sid]-m_stats->m_last_num_sim_winsn[m_sid])<5){
+ m_stats->inst_per_cycle[(m_stats->m_num_sim_winsn[m_sid]-m_stats->m_last_num_sim_winsn[m_sid])][m_sid]++;
+ }
+ else{
+ m_stats->inst_per_cycle[5][m_sid]++;
+ }
+
+
+ m_stats->m_last_num_sim_insn[m_sid]=m_stats->m_num_sim_insn[m_sid];
+ m_stats->m_last_num_sim_winsn[m_sid]=m_stats->m_num_sim_winsn[m_sid];
+
warp_inst_t** preg = m_pipeline_reg[EX_WB].get_ready();
warp_inst_t* pipe_reg = (preg==NULL)? NULL:*preg;
while( preg and !pipe_reg->empty() ) {
@@ -903,7 +1042,7 @@ void shader_core_ctx::writeback()
unsigned warp_id = pipe_reg->warp_id();
m_scoreboard->releaseRegisters( pipe_reg );
m_warp[warp_id].dec_inst_in_pipeline();
- warp_inst_complete(*pipe_reg);
+ warp_inst_complete(*pipe_reg,0);
m_gpu->gpu_sim_insn_last_update_sid = m_sid;
m_gpu->gpu_sim_insn_last_update = gpu_sim_cycle;
m_last_inst_gpu_sim_cycle = gpu_sim_cycle;
@@ -918,6 +1057,11 @@ bool ldst_unit::shared_cycle( warp_inst_t &inst, mem_stage_stall_type &rc_fail,
{
if( inst.space.get_type() != shared_space )
return true;
+
+ if(inst.has_dispatch_delay()){
+ m_stats->gpgpu_n_shmem_bank_access[m_sid]++;
+ }
+
bool stall = inst.dispatch_delay();
if( stall ) {
fail_type = S_MEM;
@@ -1019,6 +1163,7 @@ bool ldst_unit::memory_cycle( warp_inst_t &inst, mem_stage_stall_type &stall_rea
} else {
mem_fetch *mf = m_mf_allocator->alloc(inst,access);
m_icnt->push(mf);
+ n_simt_to_mem+=mf->get_num_flits(true); // Interconnect power stats (# of flits sent to the memory partitions)
inst.accessq_pop_back();
//inst.clear_active( access.get_warp_mask() );
if( inst.is_load() ) {
@@ -1057,9 +1202,9 @@ void ldst_unit::fill( mem_fetch *mf )
m_response_fifo.push_back(mf);
}
-void ldst_unit::flush()
-{
- // no L1D
+void ldst_unit::flush(){
+ // Flush L1D cache
+ m_L1D->flush();
}
simd_function_unit::simd_function_unit( const shader_core_config *config )
@@ -1068,20 +1213,61 @@ simd_function_unit::simd_function_unit( const shader_core_config *config )
m_dispatch_reg = new warp_inst_t(config);
}
-sfu::sfu( register_set* result_port, const shader_core_config *config )
- : pipelined_simd_unit(result_port,config,config->max_sfu_latency)
+
+sfu:: sfu( register_set* result_port, const shader_core_config *config,shader_core_ctx *core )
+ : pipelined_simd_unit(result_port,config,config->max_sfu_latency,core)
{
m_name = "SFU";
}
-sp_unit::sp_unit( register_set* result_port, const shader_core_config *config )
- : pipelined_simd_unit(result_port,config,config->max_sp_latency)
+void sfu::issue( register_set& source_reg )
+{
+ warp_inst_t** ready_reg = source_reg.get_ready();
+ //m_core->incexecstat((*ready_reg));
+
+ (*ready_reg)->op4=SFU__OP;
+ m_core->incsfu_stat(m_core->get_sid(),m_core->get_config()->warp_size,(*ready_reg)->latency);
+ pipelined_simd_unit::issue(source_reg);
+}
+
+void ldst_unit::active_lanes_in_pipeline(){
+ unsigned active_count=pipelined_simd_unit::get_active_lanes_in_pipeline();
+ assert(active_count<=m_core->get_config()->warp_size);
+ m_core->incfumemactivelanes_stat(m_core->get_sid(),active_count);
+}
+void sp_unit::active_lanes_in_pipeline(){
+ unsigned active_count=pipelined_simd_unit::get_active_lanes_in_pipeline();
+ assert(active_count<=m_core->get_config()->warp_size);
+ m_core->incspactivelanes_stat(m_core->get_sid(),active_count);
+ m_core->incfuactivelanes_stat(m_core->get_sid(),active_count);
+ m_core->incfumemactivelanes_stat(m_core->get_sid(),active_count);
+}
+
+void sfu::active_lanes_in_pipeline(){
+ unsigned active_count=pipelined_simd_unit::get_active_lanes_in_pipeline();
+ assert(active_count<=m_core->get_config()->warp_size);
+ m_core->incsfuactivelanes_stat(m_core->get_sid(),active_count);
+ m_core->incfuactivelanes_stat(m_core->get_sid(),active_count);
+ m_core->incfumemactivelanes_stat(m_core->get_sid(),active_count);
+}
+
+sp_unit::sp_unit( register_set* result_port, const shader_core_config *config,shader_core_ctx *core)
+ : pipelined_simd_unit(result_port,config,config->max_sp_latency,core)
{
m_name = "SP ";
}
+void sp_unit :: issue(register_set& source_reg)
+{
+ warp_inst_t** ready_reg = source_reg.get_ready();
+ //m_core->incexecstat((*ready_reg));
+ (*ready_reg)->op4=SP__OP;
+ m_core->incsp_stat(m_core->get_sid(),m_core->get_config()->warp_size,(*ready_reg)->latency);
+ pipelined_simd_unit::issue(source_reg);
+}
+
-pipelined_simd_unit::pipelined_simd_unit( register_set* result_port, const shader_core_config *config, unsigned max_latency )
+pipelined_simd_unit::pipelined_simd_unit( register_set* result_port, const shader_core_config *config, unsigned max_latency,shader_core_ctx *core )
: simd_function_unit(config)
{
m_result_port = result_port;
@@ -1089,8 +1275,29 @@ pipelined_simd_unit::pipelined_simd_unit( register_set* result_port, const shade
m_pipeline_reg = new warp_inst_t*[m_pipeline_depth];
for( unsigned i=0; i < m_pipeline_depth; i++ )
m_pipeline_reg[i] = new warp_inst_t( config );
+ m_core=core;
+}
+
+
+void pipelined_simd_unit::issue( register_set& source_reg )
+{
+ //move_warp(m_dispatch_reg,source_reg);
+ warp_inst_t** ready_reg = source_reg.get_ready();
+ m_core->incexecstat((*ready_reg));
+ //source_reg.move_out_to(m_dispatch_reg);
+ simd_function_unit::issue(source_reg);
}
+/*
+ virtual void issue( register_set& source_reg )
+ {
+ //move_warp(m_dispatch_reg,source_reg);
+ //source_reg.move_out_to(m_dispatch_reg);
+ simd_function_unit::issue(source_reg);
+ }
+*/
+
+
ldst_unit::ldst_unit( mem_fetch_interface *icnt,
shader_core_mem_fetch_allocator *mf_allocator,
shader_core_ctx *core,
@@ -1098,9 +1305,9 @@ ldst_unit::ldst_unit( mem_fetch_interface *icnt,
Scoreboard *scoreboard,
const shader_core_config *config,
const memory_config *mem_config,
- shader_core_stats *stats,
+ shader_core_stats *stats,
unsigned sid,
- unsigned tpc ) : pipelined_simd_unit(NULL,config,3), m_next_wb(config)
+ unsigned tpc ) : pipelined_simd_unit(NULL,config,3,core), m_next_wb(config)
{
m_memory_config = mem_config;
m_icnt = icnt;
@@ -1131,6 +1338,32 @@ ldst_unit::ldst_unit( mem_fetch_interface *icnt,
m_last_inst_gpu_tot_sim_cycle=0;
}
+void ldst_unit:: issue( register_set &reg_set )
+{
+ warp_inst_t* inst = *(reg_set.get_ready());
+ // stat collection
+ m_core->mem_instruction_stats(*inst);
+
+ // record how many pending register writes/memory accesses there are for this instruction
+ assert(inst->empty() == false);
+ if (inst->is_load() and inst->space.get_type() != shared_space) {
+ unsigned warp_id = inst->warp_id();
+ unsigned n_accesses = inst->accessq_count();
+ for (unsigned r = 0; r < 4; r++) {
+ unsigned reg_id = inst->out[r];
+ if (reg_id > 0) {
+ m_pending_writes[warp_id][reg_id] += n_accesses;
+ }
+ }
+ }
+
+
+ inst->op4=MEM__OP;
+ m_core->mem_instruction_stats(*inst);
+ m_core->incmem_stat(m_core->get_sid(),m_core->get_config()->warp_size,1);
+ pipelined_simd_unit::issue(reg_set);
+}
+
void ldst_unit::writeback()
{
// process next instruction that is going to writeback
@@ -1154,7 +1387,7 @@ void ldst_unit::writeback()
}
}
if( insn_completed ) {
- m_core->warp_inst_complete(m_next_wb);
+ m_core->warp_inst_complete(m_next_wb, 1);
}
m_next_wb.clear();
m_last_inst_gpu_sim_cycle = gpu_sim_cycle;
@@ -1227,7 +1460,7 @@ unsigned ldst_unit::clock_multiplier() const
{
return m_config->mem_warp_parts;
}
-
+/*
void ldst_unit::issue( register_set &reg_set )
{
warp_inst_t* inst = *(reg_set.get_ready());
@@ -1249,7 +1482,7 @@ void ldst_unit::issue( register_set &reg_set )
pipelined_simd_unit::issue(reg_set);
}
-
+*/
void ldst_unit::cycle()
{
writeback();
@@ -1337,7 +1570,7 @@ void ldst_unit::cycle()
}
}
if( !pending_requests ) {
- m_core->warp_inst_complete(*m_dispatch_reg);
+ m_core->warp_inst_complete(*m_dispatch_reg, 1);
m_scoreboard->releaseRegisters(m_dispatch_reg);
}
m_core->dec_inst_in_pipeline(warp_id);
@@ -1346,10 +1579,13 @@ void ldst_unit::cycle()
} else {
// stores exit pipeline here
m_core->dec_inst_in_pipeline(warp_id);
- m_core->warp_inst_complete(*m_dispatch_reg);
+ m_core->get_gpu()->gpu_sim_insn += m_dispatch_reg->active_count();
+ m_core->warp_inst_complete(*m_dispatch_reg,1);
m_dispatch_reg->clear();
}
}
+ // Sets stats in m_stats object
+ set_stats();
}
void shader_core_ctx::register_cta_thread_exit( unsigned cta_num )
@@ -1481,7 +1717,81 @@ void warp_inst_t::print( FILE *fout ) const
ptx_print_insn( pc, fout );
fprintf(fout, "\n");
}
+void shader_core_ctx::incexecstat(warp_inst_t *&inst)
+{
+ if(inst->op5==TEX)
+ inctex_stat(get_sid(),inst->active_count(),1);
+
+ switch(inst->op3){
+ case INT__OP:
+ incialu_stat(get_sid(),inst->active_count(),25);
+ break;
+ case INT_MUL_OP:
+ if(m_config->gpgpu_shader_registers==32768) //i.e. FERMI
+ incimul_stat(get_sid(),inst->active_count(),7.2);
+ else
+ incimul_stat(get_sid(),inst->active_count(),16);
+ break;
+ case INT_MUL24_OP:
+ incimul24_stat(get_sid(),inst->active_count(),4.2);
+ break;
+ case INT_MUL32_OP:
+ incimul32_stat(get_sid(),inst->active_count(),4);
+ break;
+ case INT_DIV_OP:
+ incidiv_stat(get_sid(),inst->active_count(),40);
+ break;
+ case FP__OP:
+ if(m_config->gpgpu_shader_registers==32768)
+ incfpalu_stat(get_sid(),inst->active_count(),1);
+ else
+ incfpalu_stat(get_sid(),inst->active_count(),1.7);
+ break;
+ case FP_MUL_OP:
+ if(m_config->gpgpu_shader_registers==32768)
+ incfpmul_stat(get_sid(),inst->active_count(),1.8);
+ else
+ incfpmul_stat(get_sid(),inst->active_count(),1.8);
+ break;
+ case FP_DIV_OP:
+ if(m_config->gpgpu_shader_registers==32768)
+ incfpdiv_stat(get_sid(),inst->active_count(),48);
+ else
+ incfpdiv_stat(get_sid(),inst->active_count(),22);
+ break;
+ case FP_SQRT_OP:
+ if(m_config->gpgpu_shader_registers==32768)
+ inctrans_stat(get_sid(),inst->active_count(),25);
+ else
+ inctrans_stat(get_sid(),inst->active_count(),8);
+
+ break;
+ case FP_LG_OP:
+ if (m_config->gpgpu_shader_registers==32768)
+ inctrans_stat(get_sid(),inst->active_count(),35);
+ else
+ inctrans_stat(get_sid(),inst->active_count(),0.3);
+ break;
+ case FP_SIN_OP:
+ if(m_config->gpgpu_shader_registers==32768)
+ inctrans_stat(get_sid(),inst->active_count(),12);
+ else
+ inctrans_stat(get_sid(),inst->active_count(),40);
+
+ break;
+ case FP_EXP_OP:
+ if(m_config->gpgpu_shader_registers==32768)
+ inctrans_stat(get_sid(),inst->active_count(),35);
+ else
+ inctrans_stat(get_sid(),inst->active_count(),9);
+ break;
+
+
+ default:
+ break;
+ }
+}
void shader_core_ctx::print_stage(unsigned int stage, FILE *fout ) const
{
m_pipeline_reg[stage].print(fout);
@@ -1710,6 +2020,7 @@ unsigned int shader_core_config::max_cta( const kernel_info_t &k ) const
void shader_core_ctx::cycle()
{
+ m_stats->shader_cycles[m_sid]++;
writeback();
execute();
read_operands();
@@ -2010,6 +2321,19 @@ void shader_core_ctx::print_cache_stats( FILE *fp, unsigned& dl1_accesses, unsig
m_ldst_unit->print_cache_stats( fp, dl1_accesses, dl1_misses );
}
+void shader_core_ctx::get_cache_stats(unsigned &read_accesses, unsigned &write_accesses, unsigned &read_misses, unsigned &write_misses, unsigned cache_type) {
+ m_ldst_unit->get_cache_stats(read_accesses, write_accesses, read_misses, write_misses, cache_type);
+}
+
+void shader_core_ctx::set_icnt_power_stats(unsigned &n_simt_to_mem) const{
+ unsigned l1i=0;
+
+ m_L1I->set_icnt_power_stats(l1i);
+ m_ldst_unit->set_icnt_power_stats(n_simt_to_mem);
+
+ n_simt_to_mem+=l1i; // l1i + l1d + l1c + l1t + any non-cached access
+}
+
bool shd_warp_t::functional_done() const
{
return get_n_completed() == m_warp_size;
@@ -2151,6 +2475,22 @@ bool opndcoll_rfu_t::writeback( const warp_inst_t &inst )
return false;
}
}
+ for(unsigned i=0;i<(unsigned)regs.size();i++){
+ if(m_shader->get_config()->gpgpu_clock_gated_reg_file){
+ unsigned active_count=0;
+ for(unsigned i=0;i<m_shader->get_config()->warp_size;i=i+m_shader->get_config()->n_regfile_gating_group){
+ for(unsigned j=0;j<m_shader->get_config()->n_regfile_gating_group;j++){
+ if(inst.get_active_mask().test(i+j)){
+ active_count+=m_shader->get_config()->n_regfile_gating_group;
+ break;
+ }
+ }
+ }
+ m_shader->incregfile_writes(m_shader->get_sid(),active_count);
+ }else{
+ m_shader->incregfile_writes(m_shader->get_sid(),m_shader->get_config()->warp_size);//inst.active_count());
+ }
+ }
return true;
}
@@ -2160,6 +2500,22 @@ void opndcoll_rfu_t::dispatch_ready_cu()
dispatch_unit_t &du = m_dispatch_units[p];
collector_unit_t *cu = du.find_ready();
if( cu ) {
+ for(unsigned i=0;i<(cu->get_num_operands()-cu->get_num_regs());i++){
+ if(m_shader->get_config()->gpgpu_clock_gated_reg_file){
+ unsigned active_count=0;
+ for(unsigned i=0;i<m_shader->get_config()->warp_size;i=i+m_shader->get_config()->n_regfile_gating_group){
+ for(unsigned j=0;j<m_shader->get_config()->n_regfile_gating_group;j++){
+ if(cu->get_active_mask().test(i+j)){
+ active_count+=m_shader->get_config()->n_regfile_gating_group;
+ break;
+ }
+ }
+ }
+ m_shader->incnon_rf_operands(m_shader->get_sid(),active_count);
+ }else{
+ m_shader->incnon_rf_operands(m_shader->get_sid(),m_shader->get_config()->warp_size);//cu->get_active_count());
+ }
+ }
cu->dispatch();
}
}
@@ -2208,7 +2564,21 @@ void opndcoll_rfu_t::allocate_reads()
unsigned cu = op.get_oc_id();
unsigned operand = op.get_operand();
m_cu[cu]->collect_operand(operand);
- }
+ if(m_shader->get_config()->gpgpu_clock_gated_reg_file){
+ unsigned active_count=0;
+ for(unsigned i=0;i<m_shader->get_config()->warp_size;i=i+m_shader->get_config()->n_regfile_gating_group){
+ for(unsigned j=0;j<m_shader->get_config()->n_regfile_gating_group;j++){
+ if(op.get_active_mask().test(i+j)){
+ active_count+=m_shader->get_config()->n_regfile_gating_group;
+ break;
+ }
+ }
+ }
+ m_shader->incregfile_reads(m_shader->get_sid(),active_count);
+ }else{
+ m_shader->incregfile_reads(m_shader->get_sid(),m_shader->get_config()->warp_size);//op.get_active_count());
+ }
+ }
}
bool opndcoll_rfu_t::collector_unit_t::ready() const
@@ -2348,6 +2718,14 @@ unsigned simt_core_cluster::get_n_active_cta() const
return n;
}
+unsigned simt_core_cluster::get_n_active_sms() const
+{
+ unsigned n=0;
+ for( unsigned i=0; i < m_config->n_simt_cores_per_cluster; i++ )
+ n += m_core[i]->isactive();
+ return n;
+}
+
unsigned simt_core_cluster::issue_block2core()
{
unsigned num_blocks_issued=0;
@@ -2443,6 +2821,12 @@ void simt_core_cluster::icnt_cycle()
}
}
+void simt_core_cluster::get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc ) const
+{
+ unsigned cid = m_config->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[m_config->sid_to_cid(sid)]->display_pipeline(fout,print_mem,mask);
@@ -2462,6 +2846,18 @@ void simt_core_cluster::print_cache_stats( FILE *fp, unsigned& dl1_accesses, uns
}
}
+void simt_core_cluster::get_cache_stats(unsigned &read_accesses, unsigned &write_accesses, unsigned &read_misses, unsigned &write_misses, unsigned cache_type) const {
+ for ( unsigned i = 0; i < m_config->n_simt_cores_per_cluster; ++i ) {
+ m_core[ i ]->get_cache_stats(read_accesses, write_accesses, read_misses, write_misses, cache_type);
+ }
+}
+
+void simt_core_cluster::set_icnt_stats(unsigned &n_simt_to_mem) const {
+ for ( unsigned i = 0; i < m_config->n_simt_cores_per_cluster; ++i ) {
+ m_core[i]->set_icnt_power_stats(n_simt_to_mem);
+ }
+}
+
void shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid)
{
if( inst.has_callback(t) )
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index 262a3be..047f4da 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -53,6 +53,8 @@
#include "stats.h"
#include "gpu-cache.h"
+
+
#define NO_OP_FLAG 0xFF
/* READ_PACKET_SIZE:
@@ -413,7 +415,24 @@ private:
if( m_warp ) return m_warp->warp_id();
else if( m_cu ) return m_cu->get_warp_id();
else abort();
- return 0;
+ }
+ unsigned get_active_count() const
+ {
+ if( m_warp ) return m_warp->active_count();
+ else if( m_cu ) return m_cu->get_active_count();
+ else abort();
+ }
+ const active_mask_t & get_active_mask()
+ {
+ if( m_warp ) return m_warp->get_active_mask();
+ else if( m_cu ) return m_cu->get_active_mask();
+ else abort();
+ }
+ unsigned get_op3() const
+ {
+ if( m_warp ) return m_warp->op3;
+ else if( m_cu ) return m_cu->get_op3();
+ else abort();
}
unsigned get_oc_id() const { return m_cu->get_id(); }
unsigned get_bank() const { return m_bank; }
@@ -605,6 +624,9 @@ private:
void dump(FILE *fp, const shader_core_ctx *shader ) const;
unsigned get_warp_id() const { return m_warp_id; }
+ unsigned get_active_count() const { return m_warp->active_count(); }
+ const active_mask_t & get_active_mask() const { return m_warp->get_active_mask(); }
+ unsigned get_op3() const { return m_warp->op3; }
unsigned get_id() const { return m_cuid; } // returns CU hw id
// modifiers
@@ -619,7 +641,12 @@ private:
{
m_not_ready.reset(op);
}
-
+ unsigned get_num_operands() const{
+ return m_warp->get_num_operands();
+ }
+ unsigned get_num_regs() const{
+ return m_warp->get_num_regs();
+ }
void dispatch();
bool is_free(){return m_free;}
@@ -762,6 +789,7 @@ public:
// modifiers
virtual void issue( register_set& source_reg ) { source_reg.move_out_to(m_dispatch_reg); occupied.set(m_dispatch_reg->latency);}
virtual void cycle() = 0;
+ virtual void active_lanes_in_pipeline() = 0;
// accessors
virtual unsigned clock_multiplier() const { return 1; }
@@ -782,7 +810,7 @@ protected:
class pipelined_simd_unit : public simd_function_unit {
public:
- pipelined_simd_unit( register_set* result_port, const shader_core_config *config, unsigned max_latency );
+ pipelined_simd_unit( register_set* result_port, const shader_core_config *config, unsigned max_latency, shader_core_ctx *core );
//modifiers
virtual void cycle()
@@ -800,14 +828,26 @@ public:
}
occupied >>=1;
}
-
+ virtual void issue( register_set& source_reg );
+ virtual unsigned get_active_lanes_in_pipeline()
+ {
+ active_mask_t active_lanes;
+ active_lanes.reset();
+ for( unsigned stage=0; (stage+1)<m_pipeline_depth; stage++ ){
+ if( !m_pipeline_reg[stage]->empty() )
+ active_lanes|=m_pipeline_reg[stage]->get_active_mask();
+ }
+ return active_lanes.count();
+ }
+ virtual void active_lanes_in_pipeline() = 0;
+/*
virtual void issue( register_set& source_reg )
{
//move_warp(m_dispatch_reg,source_reg);
//source_reg.move_out_to(m_dispatch_reg);
simd_function_unit::issue(source_reg);
}
-
+*/
// accessors
virtual bool stallable() const { return false; }
virtual bool can_issue( const warp_inst_t &inst ) const
@@ -828,12 +868,13 @@ protected:
unsigned m_pipeline_depth;
warp_inst_t **m_pipeline_reg;
register_set *m_result_port;
+ class shader_core_ctx *m_core;
};
class sfu : public pipelined_simd_unit
{
public:
- sfu( register_set* result_port, const shader_core_config *config );
+ sfu( register_set* result_port, const shader_core_config *config, shader_core_ctx *core );
virtual bool can_issue( const warp_inst_t &inst ) const
{
switch(inst.op) {
@@ -843,12 +884,14 @@ public:
}
return pipelined_simd_unit::can_issue(inst);
}
+ virtual void active_lanes_in_pipeline();
+ virtual void issue( register_set& source_reg );
};
class sp_unit : public pipelined_simd_unit
{
public:
- sp_unit( register_set* result_port, const shader_core_config *config );
+ sp_unit( register_set* result_port, const shader_core_config *config, shader_core_ctx *core );
virtual bool can_issue( const warp_inst_t &inst ) const
{
switch(inst.op) {
@@ -860,6 +903,8 @@ public:
}
return pipelined_simd_unit::can_issue(inst);
}
+ virtual void active_lanes_in_pipeline();
+ virtual void issue( register_set& source_reg );
};
class simt_core_cluster;
@@ -900,10 +945,16 @@ public:
}
return m_dispatch_reg->empty();
}
+
+ virtual void active_lanes_in_pipeline();
virtual bool stallable() const { return true; }
bool response_buffer_full() const;
void print(FILE *fout) const;
void print_cache_stats( FILE *fp, unsigned& dl1_accesses, unsigned& dl1_misses );
+ void get_cache_stats(unsigned &read_accesses, unsigned &write_accesses, unsigned &read_misses, unsigned &write_misses, unsigned cache_type);
+ void set_stats();
+
+ void set_icnt_power_stats(unsigned &simt_to_mem) const;
private:
bool shared_cycle( warp_inst_t &inst, mem_stage_stall_type &rc_fail, mem_stage_access_type &fail_type);
@@ -940,6 +991,9 @@ private:
// for debugging
unsigned long long m_last_inst_gpu_sim_cycle;
unsigned long long m_last_inst_gpu_tot_sim_cycle;
+
+ // Interconnect power stats
+ unsigned n_simt_to_mem;
};
enum pipeline_stage_name_t {
@@ -969,6 +1023,7 @@ struct shader_core_config : public core_config
shader_core_config(){
pipeline_widths_string = NULL;
}
+
void init()
{
int ntok = sscanf(gpgpu_shader_core_pipeline_opt,"%d:%d",
@@ -1019,8 +1074,11 @@ struct shader_core_config : public core_config
// data
char *gpgpu_shader_core_pipeline_opt;
bool gpgpu_perfect_mem;
+ bool gpgpu_clock_gated_reg_file;
+ bool gpgpu_clock_gated_lanes;
enum divergence_support_t model;
unsigned n_thread_per_shader;
+ unsigned n_regfile_gating_group;
unsigned max_warps_per_shader;
unsigned max_cta_per_core; //Limit on number of concurrent CTAs in shader core
@@ -1033,7 +1091,8 @@ struct shader_core_config : public core_config
cache_config m_L1T_config;
cache_config m_L1C_config;
cache_config m_L1D_config;
-
+ cache_config m_L2D_config;
+
bool gpgpu_dwf_reg_bankconflict;
int gpgpu_num_sched_per_core;
@@ -1080,8 +1139,44 @@ struct shader_core_config : public core_config
};
struct shader_core_stats_pod {
+
+ unsigned long long **inst_per_cycle;
+ unsigned long long *shader_cycles;
unsigned *m_num_sim_insn; // number of scalar thread instructions committed by this shader core
unsigned *m_num_sim_winsn; // number of warp instructions committed by this shader core
+ unsigned *m_last_num_sim_insn;
+ unsigned *m_last_num_sim_winsn;
+ unsigned *m_num_decoded_insn; // number of instructions decoded by this shader core
+ float *m_pipeline_duty_cycle;
+ unsigned *m_num_FPdecoded_insn;
+ unsigned *m_num_INTdecoded_insn;
+ unsigned *m_num_storequeued_insn;
+ unsigned *m_num_loadqueued_insn;
+ unsigned *m_num_ialu_acesses;
+ unsigned *m_num_fp_acesses;
+ unsigned *m_num_imul_acesses;
+ unsigned *m_num_tex_inst;
+ unsigned *m_num_fpmul_acesses;
+ unsigned *m_num_idiv_acesses;
+ unsigned *m_num_fpdiv_acesses;
+ unsigned *m_num_sp_acesses;
+ unsigned *m_num_sfu_acesses;
+ unsigned *m_num_trans_acesses;
+ unsigned *m_num_mem_acesses;
+ unsigned *m_num_sp_committed;
+ unsigned *m_num_tlb_hits;
+ unsigned *m_num_tlb_accesses;
+ unsigned *m_num_sfu_committed;
+ unsigned *m_num_mem_committed;
+ unsigned *m_read_regfile_acesses;
+ unsigned *m_write_regfile_acesses;
+ unsigned *m_non_rf_operands;
+ unsigned *m_num_imul24_acesses;
+ unsigned *m_num_imul32_acesses;
+ unsigned *m_active_sp_lanes;
+ unsigned *m_active_sfu_lanes;
+ unsigned *m_active_fu_lanes;
+ unsigned *m_active_fu_mem_lanes;
unsigned *m_n_diverge; // number of divergence occurring in this shader
unsigned gpgpu_n_load_insn;
unsigned gpgpu_n_store_insn;
@@ -1114,9 +1209,23 @@ struct shader_core_stats_pod {
unsigned made_write_mfs;
unsigned made_read_mfs;
+
+ // Power stats
+ unsigned *gpgpu_n_shmem_bank_access;
+ unsigned *inst_c_read_access; // Instruction cache read access
+ unsigned *inst_c_read_miss; // Instruction cache read miss
+ unsigned *const_c_read_access; // Constant cache read access
+ unsigned *const_c_read_miss; // Constant cache read miss
+ unsigned *text_c_read_access; // Texture cache read access
+ unsigned *text_c_read_miss; // Texture cache read miss
+ unsigned *l1d_read_access; // L1 Data cache read access
+ unsigned *l1d_read_miss; // L1 Data cache read miss
+ unsigned *l1d_write_access; // L1 Data cache write access
+ unsigned *l1d_write_miss; // L1 Data cache write miss
+
};
-class shader_core_stats : private shader_core_stats_pod {
+class shader_core_stats : public shader_core_stats_pod {
public:
shader_core_stats( const shader_core_config *config )
{
@@ -1124,11 +1233,64 @@ public:
shader_core_stats_pod *pod = this;
memset(pod,0,sizeof(shader_core_stats_pod));
+ inst_per_cycle=(unsigned long long **) calloc(6,sizeof(unsigned long long *));
+ for(unsigned i=0;i<6;i++){
+ inst_per_cycle[i]=(unsigned long long *) calloc(config->num_shader(),sizeof(unsigned long long ));
+ }
+ shader_cycles=(unsigned long long *) calloc(config->num_shader(),sizeof(unsigned long long ));
m_num_sim_insn = (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
m_num_sim_winsn = (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_last_num_sim_winsn = (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_last_num_sim_insn = (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_pipeline_duty_cycle=(float*) calloc(config->num_shader(),sizeof(float));
+ m_num_decoded_insn = (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_FPdecoded_insn = (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_storequeued_insn=(unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_loadqueued_insn=(unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_INTdecoded_insn = (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_ialu_acesses = (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_fp_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_tex_inst= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_imul_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_imul24_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_imul32_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_fpmul_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_idiv_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_fpdiv_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_sp_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_sfu_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_trans_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_mem_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_sp_committed= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_tlb_hits=(unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_tlb_accesses=(unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_active_sp_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_active_sfu_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_active_fu_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_active_fu_mem_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_sfu_committed= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_num_mem_committed= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_read_regfile_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_write_regfile_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
+ m_non_rf_operands=(unsigned*) calloc(config->num_shader(),sizeof(unsigned));
m_n_diverge = (unsigned*) calloc(config->num_shader(),sizeof(unsigned));
shader_cycle_distro = (unsigned*) calloc(config->warp_size+3, sizeof(unsigned));
last_shader_cycle_distro = (unsigned*) calloc(m_config->warp_size+3, sizeof(unsigned));
+
+ // Power stats
+ inst_c_read_access = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
+ inst_c_read_miss = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
+ const_c_read_access = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
+ const_c_read_miss = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
+ text_c_read_access = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
+ text_c_read_miss = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
+ l1d_read_access = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
+ l1d_read_miss = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
+ l1d_write_access = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
+ l1d_write_miss = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
+
+ gpgpu_n_shmem_bank_access = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
+
}
void new_grid()
{
@@ -1141,6 +1303,7 @@ public:
private:
const shader_core_config *m_config;
+ friend class power_stat_t;
friend class shader_core_ctx;
friend class ldst_unit;
friend class simt_core_cluster;
@@ -1216,13 +1379,20 @@ public:
printf("GPGPU-Sim uArch: Shader %d bind to kernel %u \'%s\'\n", m_sid, m_kernel->get_uid(),
m_kernel->name().c_str() );
}
-
+
+ float roundUp(float num){
+ return (int)num+((num-(int)(num)>0)?0.5:0.0);
+ }
+
+
// accessors
bool fetch_unit_response_buffer_full() const;
bool ldst_unit_response_buffer_full() const;
unsigned get_not_completed() const { return m_not_completed; }
unsigned get_n_active_cta() const { return m_n_active_cta; }
+ unsigned isactive() const {if(m_n_active_cta>0) return 1; else return 0;}
kernel_info_t *get_kernel() { return m_kernel; }
+ unsigned get_sid() const {return m_sid;}
// used by functional simulation:
// modifiers
@@ -1230,6 +1400,7 @@ public:
// accessors
virtual bool warp_waiting_at_barrier( unsigned warp_id ) const;
+ void get_pdom_stack_top_info( unsigned tid, unsigned *pc, unsigned *rpc ) const;
// used by pipeline timing model components:
// modifiers
@@ -1240,18 +1411,128 @@ public:
void store_ack( class mem_fetch *mf );
bool warp_waiting_at_mem_barrier( unsigned warp_id );
void set_max_cta( const kernel_info_t &kernel );
- void warp_inst_complete(const warp_inst_t &inst);
+ void warp_inst_complete(const warp_inst_t &inst,bool memory);
// accessors
std::list<unsigned> get_regs_written( const inst_t &fvt ) const;
const shader_core_config *get_config() const { return m_config; }
void print_cache_stats( FILE *fp, unsigned& dl1_accesses, unsigned& dl1_misses );
+ void get_cache_stats(unsigned &read_accesses, unsigned &write_accesses, unsigned &read_misses, unsigned &write_misses, unsigned cache_type);
+
+ void set_icnt_power_stats(unsigned &n_simt_to_mem) const;
// debug:
void display_simt_state(FILE *fout, int mask ) const;
void display_pipeline( FILE *fout, int print_mem, int mask3bit ) const;
+ void incload_stat(unsigned sid) {m_stats->m_num_loadqueued_insn[sid]++;}
+ void incstore_stat(unsigned sid) {m_stats->m_num_storequeued_insn[sid]++;}
+ void incialu_stat(unsigned sid,unsigned active_count,double latency) {
+ if(m_config->gpgpu_clock_gated_lanes==false){
+ m_stats->m_num_ialu_acesses[sid]=m_stats->m_num_ialu_acesses[sid]+active_count*latency
+ + inactive_lanes_accesses_nonsfu(active_count, latency);
+ }else {
+ m_stats->m_num_ialu_acesses[sid]=m_stats->m_num_ialu_acesses[sid]+active_count*latency;
+ }
+ }
+ void inctex_stat(unsigned sid,unsigned active_count,double latency){
+ m_stats->m_num_tex_inst[sid]=m_stats->m_num_tex_inst[sid]+active_count*latency;
+ }
+ void incimul_stat(unsigned sid,unsigned active_count,double latency) {
+ if(m_config->gpgpu_clock_gated_lanes==false){
+ m_stats->m_num_imul_acesses[sid]=m_stats->m_num_imul_acesses[sid]+active_count*latency
+ + inactive_lanes_accesses_nonsfu(active_count, latency);
+ }else {
+ m_stats->m_num_imul_acesses[sid]=m_stats->m_num_imul_acesses[sid]+active_count*latency;
+ }
+ }
+ void incimul24_stat(unsigned sid,unsigned active_count,double latency) {
+ if(m_config->gpgpu_clock_gated_lanes==false){
+ m_stats->m_num_imul24_acesses[sid]=m_stats->m_num_imul24_acesses[sid]+active_count*latency
+ + inactive_lanes_accesses_nonsfu(active_count, latency);
+ }else {
+ m_stats->m_num_imul24_acesses[sid]=m_stats->m_num_imul24_acesses[sid]+active_count*latency;
+ }
+ }
+ void incimul32_stat(unsigned sid,unsigned active_count,double latency) {
+ if(m_config->gpgpu_clock_gated_lanes==false){
+ m_stats->m_num_imul32_acesses[sid]=m_stats->m_num_imul32_acesses[sid]+active_count*latency
+ + inactive_lanes_accesses_sfu(active_count, latency);
+ }else{
+ m_stats->m_num_imul32_acesses[sid]=m_stats->m_num_imul32_acesses[sid]+active_count*latency;
+ }
+ //printf("Int_Mul -- Active_count: %d\n",active_count);
+ }
+ void incidiv_stat(unsigned sid,unsigned active_count,double latency) {
+ if(m_config->gpgpu_clock_gated_lanes==false){
+ m_stats->m_num_idiv_acesses[sid]=m_stats->m_num_idiv_acesses[sid]+active_count*latency
+ + inactive_lanes_accesses_sfu(active_count, latency);
+ }else {
+ m_stats->m_num_idiv_acesses[sid]=m_stats->m_num_idiv_acesses[sid]+active_count*latency;
+ }
+ }
+ void incfpalu_stat(unsigned sid,unsigned active_count,double latency) {
+ if(m_config->gpgpu_clock_gated_lanes==false){
+ m_stats->m_num_fp_acesses[sid]=m_stats->m_num_fp_acesses[sid]+active_count*latency
+ + inactive_lanes_accesses_nonsfu(active_count, latency);
+ }else {
+ m_stats->m_num_fp_acesses[sid]=m_stats->m_num_fp_acesses[sid]+active_count*latency;
+ }
+ }
+ void incfpmul_stat(unsigned sid,unsigned active_count,double latency) {
+ // printf("FP MUL stat increament\n");
+ if(m_config->gpgpu_clock_gated_lanes==false){
+ m_stats->m_num_fpmul_acesses[sid]=m_stats->m_num_fpmul_acesses[sid]+active_count*latency
+ + inactive_lanes_accesses_nonsfu(active_count, latency);
+ }else {
+ m_stats->m_num_fpmul_acesses[sid]=m_stats->m_num_fpmul_acesses[sid]+active_count*latency;
+ }
+ }
+ void incfpdiv_stat(unsigned sid,unsigned active_count,double latency) {
+ if(m_config->gpgpu_clock_gated_lanes==false){
+ m_stats->m_num_fpdiv_acesses[sid]=m_stats->m_num_fpdiv_acesses[sid]+active_count*latency
+ + inactive_lanes_accesses_sfu(active_count, latency);
+ }else {
+ m_stats->m_num_fpdiv_acesses[sid]=m_stats->m_num_fpdiv_acesses[sid]+active_count*latency;
+ }
+ }
+ void inctrans_stat(unsigned sid,unsigned active_count,double latency) {
+ if(m_config->gpgpu_clock_gated_lanes==false){
+ m_stats->m_num_trans_acesses[sid]=m_stats->m_num_trans_acesses[sid]+active_count*latency
+ + inactive_lanes_accesses_sfu(active_count, latency);
+ }else{
+ m_stats->m_num_trans_acesses[sid]=m_stats->m_num_trans_acesses[sid]+active_count*latency;
+ }
+ }
+
+ void incsfu_stat(unsigned sid,unsigned active_count,double latency) {m_stats->m_num_sfu_acesses[sid]=m_stats->m_num_sfu_acesses[sid]+active_count*latency;}
+ void incsp_stat(unsigned sid,unsigned active_count,double latency) {m_stats->m_num_sp_acesses[sid]=m_stats->m_num_sp_acesses[sid]+active_count*latency;}
+ void incmem_stat(unsigned sid,unsigned active_count,double latency) {
+ if(m_config->gpgpu_clock_gated_lanes==false){
+ m_stats->m_num_mem_acesses[sid]=m_stats->m_num_mem_acesses[sid]+active_count*latency
+ + inactive_lanes_accesses_nonsfu(active_count, latency);
+ }else {
+ m_stats->m_num_mem_acesses[sid]=m_stats->m_num_mem_acesses[sid]+active_count*latency;
+ }
+ }
+ void incexecstat(warp_inst_t *&inst);
+
+ void incregfile_reads(unsigned sid,unsigned active_count) {m_stats->m_read_regfile_acesses[sid]=m_stats->m_read_regfile_acesses[sid]+active_count;}
+ void incregfile_writes(unsigned sid,unsigned active_count){m_stats->m_write_regfile_acesses[sid]=m_stats->m_write_regfile_acesses[sid]+active_count;}
+ void incnon_rf_operands(unsigned sid,unsigned active_count){m_stats->m_non_rf_operands[sid]=m_stats->m_non_rf_operands[sid]+active_count;}
+
+ void incspactivelanes_stat(unsigned sid,unsigned active_count) {m_stats->m_active_sp_lanes[sid]=m_stats->m_active_sp_lanes[sid]+active_count;}
+ void incsfuactivelanes_stat(unsigned sid,unsigned active_count) {m_stats->m_active_sfu_lanes[sid]=m_stats->m_active_sfu_lanes[sid]+active_count;}
+ void incfuactivelanes_stat(unsigned sid,unsigned active_count) {m_stats->m_active_fu_lanes[sid]=m_stats->m_active_fu_lanes[sid]+active_count;}
+ void incfumemactivelanes_stat(unsigned sid,unsigned active_count) {m_stats->m_active_fu_mem_lanes[sid]=m_stats->m_active_fu_mem_lanes[sid]+active_count;}
private:
+ unsigned inactive_lanes_accesses_sfu(unsigned active_count,double latency){
+ return ( ((32-active_count)>>1)*latency) + ( ((32-active_count)>>3)*latency) + ( ((32-active_count)>>3)*latency);
+ }
+ unsigned inactive_lanes_accesses_nonsfu(unsigned active_count,double latency){
+ return ( ((32-active_count)>>1)*latency);
+ }
+
int test_res_bus(int latency);
void init_warps(unsigned cta_id, unsigned start_thread, unsigned end_thread);
virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid);
@@ -1362,14 +1643,19 @@ public:
m_response_fifo.push_back(mf);
}
+ void get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc ) const;
unsigned max_cta( const kernel_info_t &kernel );
unsigned get_not_completed() const;
void print_not_completed( FILE *fp ) const;
unsigned get_n_active_cta() const;
+ unsigned get_n_active_sms() const;
gpgpu_sim *get_gpu() { return m_gpu; }
void display_pipeline( unsigned sid, FILE *fout, int print_mem, int mask );
void print_cache_stats( FILE *fp, unsigned& dl1_accesses, unsigned& dl1_misses ) const;
+ void get_cache_stats(unsigned &read_accesses, unsigned &write_accesses, unsigned &read_misses, unsigned &write_misses, unsigned cache_type) const;
+
+ void set_icnt_stats(unsigned &n_simt_to_mem) const;
private:
unsigned m_cluster_id;
diff --git a/src/gpgpu-sim/stats.h b/src/gpgpu-sim/stats.h
index 76304d2..c1b3f2a 100644
--- a/src/gpgpu-sim/stats.h
+++ b/src/gpgpu-sim/stats.h
@@ -38,13 +38,18 @@ enum mem_stage_access_type {
L_MEM_ST,
N_MEM_STAGE_ACCESS_TYPE
};
-
+enum tlb_request_status {
+ TLB_HIT = 0,
+ TLB_READY,
+ TLB_PENDING
+};
enum mem_stage_stall_type {
NO_RC_FAIL = 0,
BK_CONF,
MSHR_RC_FAIL,
ICNT_RC_FAIL,
COAL_STALL,
+ TLB_STALL,
WB_ICNT_RC_FAIL,
WB_CACHE_RSRV_FAIL,
N_MEM_STAGE_STALL_TYPE
diff --git a/src/gpgpu-sim/visualizer.cc b/src/gpgpu-sim/visualizer.cc
index c07fbb7..dcb1175 100644
--- a/src/gpgpu-sim/visualizer.cc
+++ b/src/gpgpu-sim/visualizer.cc
@@ -32,6 +32,8 @@
#include "shader.h"
#include "../option_parser.h"
#include "mem_latency_stat.h"
+#include "power_stat.h"
+//#include "../../../mcpat/processor.h"
#include "stat-tool.h"
#include "gpu-cache.h"
@@ -65,7 +67,8 @@ void gpgpu_sim::visualizer_printstat()
m_memory_partition_unit[i]->visualizer_print(visualizer_file);
m_shader_stats->visualizer_print(visualizer_file);
m_memory_stats->visualizer_print(visualizer_file);
-
+ m_power_stats->visualizer_print(visualizer_file);
+ //proc->visualizer_print(visualizer_file);
// other parameters for graphing
gzprintf(visualizer_file, "globalcyclecount: %lld\n", gpu_sim_cycle);
gzprintf(visualizer_file, "globalinsncount: %lld\n", gpu_sim_insn);