summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim
diff options
context:
space:
mode:
authorNick <[email protected]>2019-02-19 18:40:45 -0500
committerNick <[email protected]>2019-02-19 18:40:45 -0500
commit13f07a2c820422db7e4e88e43d692dfe8e1b8cad (patch)
treee0e16e9f83880f9860be0ae846c467e3c8f2dd88 /src/gpgpu-sim
parent4ed2d9e106d797eeaf5199100984dc7c658cdc1e (diff)
Add initial infrastrucutre to support L2 (and other) cache statistics for AerialVision
Diffstat (limited to 'src/gpgpu-sim')
-rw-r--r--src/gpgpu-sim/gpu-cache.cc80
-rw-r--r--src/gpgpu-sim/gpu-cache.h14
-rw-r--r--src/gpgpu-sim/gpu-sim.cc7
-rw-r--r--src/gpgpu-sim/l2cache.cc5
-rw-r--r--src/gpgpu-sim/l2cache.h3
5 files changed, 109 insertions, 0 deletions
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc
index ba81440..d050946 100644
--- a/src/gpgpu-sim/gpu-cache.cc
+++ b/src/gpgpu-sim/gpu-cache.cc
@@ -600,9 +600,11 @@ void mshr_table::display( FILE *fp ) const{
/***************************************************************** Caches *****************************************************************/
cache_stats::cache_stats(){
m_stats.resize(NUM_MEM_ACCESS_TYPE);
+ m_stats_pw.resize(NUM_MEM_ACCESS_TYPE);
m_fail_stats.resize(NUM_MEM_ACCESS_TYPE);
for(unsigned i=0; i<NUM_MEM_ACCESS_TYPE; ++i){
m_stats[i].resize(NUM_CACHE_REQUEST_STATUS, 0);
+ m_stats_pw[i].resize(NUM_CACHE_REQUEST_STATUS, 0);
m_fail_stats[i].resize(NUM_CACHE_RESERVATION_FAIL_STATUS, 0);
}
m_cache_port_available_cycles = 0;
@@ -623,6 +625,15 @@ void cache_stats::clear(){
m_cache_fill_port_busy_cycles = 0;
}
+void cache_stats::clear_pw(){
+ ///
+ /// Zero out per-window cache statistics
+ ///
+ for(unsigned i=0; i<NUM_MEM_ACCESS_TYPE; ++i){
+ std::fill(m_stats_pw[i].begin(), m_stats_pw[i].end(), 0);
+ }
+}
+
void cache_stats::inc_stats(int access_type, int access_outcome){
///
/// Increment the stat corresponding to (access_type, access_outcome) by 1.
@@ -632,6 +643,16 @@ void cache_stats::inc_stats(int access_type, int access_outcome){
m_stats[access_type][access_outcome]++;
}
+
+void cache_stats::inc_stats_pw(int access_type, int access_outcome){
+ ///
+ /// Increment the corresponding per-window cache stat
+ ///
+ if(!check_valid(access_type, access_outcome))
+ assert(0 && "Unknown cache access type or access outcome");
+ m_stats_pw[access_type][access_outcome]++;
+}
+
void cache_stats::inc_fail_stats(int access_type, int fail_outcome){
if(!check_fail_valid(access_type, fail_outcome))
@@ -718,6 +739,9 @@ cache_stats &cache_stats::operator+=(const cache_stats &cs){
for(unsigned status=0; status<NUM_CACHE_REQUEST_STATUS; ++status){
m_stats[type][status] += cs(type, status, false);
}
+ for(unsigned status=0; status<NUM_CACHE_REQUEST_STATUS; ++status){
+ m_stats_pw[type][status] += cs(type, status, false);
+ }
for(unsigned status=0; status<NUM_CACHE_RESERVATION_FAIL_STATUS; ++status){
m_fail_stats[type][status] += cs(type, status, true);
}
@@ -745,6 +769,11 @@ void cache_stats::print_stats(FILE *fout, const char *cache_name) const{
mem_access_type_str((enum mem_access_type)type),
cache_request_status_str((enum cache_request_status)status),
m_stats[type][status]);
+ fprintf(fout, "\t%s[%s][%s] = %u\n",
+ m_cache_name.c_str(),
+ mem_access_type_str((enum mem_access_type)type),
+ cache_request_status_str((enum cache_request_status)status),
+ m_stats_pw[type][status]);
if(status != RESERVATION_FAIL)
total_access[type]+= m_stats[type][status];
}
@@ -804,6 +833,24 @@ unsigned cache_stats::get_stats(enum mem_access_type *access_type, unsigned num_
}
return total;
}
+
+unsigned cache_stats::get_stats_pw(enum mem_access_type *access_type, unsigned num_access_type, enum cache_request_status *access_status, unsigned num_access_status) const{
+ ///
+ /// Returns a sum of the stats corresponding to each "access_type" and "access_status" pair.
+ /// "access_type" is an array of "num_access_type" mem_access_types.
+ /// "access_status" is an array of "num_access_status" cache_request_statuses.
+ ///
+ unsigned total=0;
+ for(unsigned type =0; type < num_access_type; ++type){
+ for(unsigned status=0; status < num_access_status; ++status){
+ if(!check_valid((int)access_type[type], (int)access_status[status]))
+ assert(0 && "Unknown cache access type or access outcome");
+ total += m_stats_pw[access_type[type]][access_status[status]];
+ }
+ }
+ return total;
+}
+
void cache_stats::get_sub_stats(struct cache_sub_stats &css) const{
///
/// Overwrites "css" with the appropriate statistics from this cache.
@@ -834,6 +881,35 @@ void cache_stats::get_sub_stats(struct cache_sub_stats &css) const{
css = t_css;
}
+void cache_stats::get_sub_stats_pw(struct cache_sub_stats &css) const{
+ ///
+ /// Overwrites "css" with the appropriate statistics from this cache.
+ ///
+ struct cache_sub_stats t_css;
+ t_css.clear();
+
+ for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
+ for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
+ if(status == HIT || status == MISS || status == SECTOR_MISS || status == HIT_RESERVED)
+ t_css.accesses += m_stats_pw[type][status];
+
+ if(status == MISS || status == SECTOR_MISS)
+ t_css.misses += m_stats_pw[type][status];
+
+ if(status == HIT_RESERVED)
+ t_css.pending_hits += m_stats_pw[type][status];
+
+ if(status == RESERVATION_FAIL)
+ t_css.res_fails += m_stats_pw[type][status];
+ }
+ }
+
+ t_css.port_available_cycles = m_cache_port_available_cycles;
+ t_css.data_port_busy_cycles = m_cache_data_port_busy_cycles;
+ t_css.fill_port_busy_cycles = m_cache_fill_port_busy_cycles;
+
+ css = t_css;
+}
bool cache_stats::check_valid(int type, int status) const{
///
/// Verify a valid access_type/access_status
@@ -1501,6 +1577,7 @@ read_only_cache::access( new_addr_type addr,
}
m_stats.inc_stats(mf->get_access_type(), m_stats.select_stats_status(status, cache_status));
+ m_stats.inc_stats_pw(mf->get_access_type(), m_stats.select_stats_status(status, cache_status));
return cache_status;
}
@@ -1575,6 +1652,8 @@ data_cache::access( new_addr_type addr,
= process_tag_probe( wr, probe_status, addr, cache_index, mf, time, events );
m_stats.inc_stats(mf->get_access_type(),
m_stats.select_stats_status(probe_status, access_status));
+ m_stats.inc_stats_pw(mf->get_access_type(),
+ m_stats.select_stats_status(probe_status, access_status));
return access_status;
}
@@ -1639,6 +1718,7 @@ enum cache_request_status tex_cache::access( new_addr_type addr, mem_fetch *mf,
cache_status = HIT_RESERVED;
}
m_stats.inc_stats(mf->get_access_type(), m_stats.select_stats_status(status, cache_status));
+ m_stats.inc_stats_pw(mf->get_access_type(), m_stats.select_stats_status(status, cache_status));
return cache_status;
}
diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h
index e663cf6..c1061ef 100644
--- a/src/gpgpu-sim/gpu-cache.h
+++ b/src/gpgpu-sim/gpu-cache.h
@@ -978,7 +978,11 @@ class cache_stats {
public:
cache_stats();
void clear();
+ // Clear AerialVision cache stats after each window
+ void clear_pw();
void inc_stats(int access_type, int access_outcome);
+ // Increment AerialVision cache stats
+ void inc_stats_pw(int access_type, int access_outcome);
void inc_fail_stats(int access_type, int fail_outcome);
enum cache_request_status select_stats_status(enum cache_request_status probe, enum cache_request_status access) const;
unsigned &operator()(int access_type, int access_outcome, bool fail_outcome);
@@ -991,12 +995,18 @@ public:
unsigned get_stats(enum mem_access_type *access_type, unsigned num_access_type, enum cache_request_status *access_status, unsigned num_access_status) const;
void get_sub_stats(struct cache_sub_stats &css) const;
+ // Get per-window cache stats for AerialVision
+ unsigned get_stats_pw(enum mem_access_type *access_type, unsigned num_access_type, enum cache_request_status *access_status, unsigned num_access_status) const;
+ void get_sub_stats_pw(struct cache_sub_stats &css) const;
+
void sample_cache_port_utility(bool data_port_busy, bool fill_port_busy);
private:
bool check_valid(int type, int status) const;
bool check_fail_valid(int type, int fail) const;
std::vector< std::vector<unsigned> > m_stats;
+ // AerialVision cache stats (per-window)
+ std::vector< std::vector<unsigned> > m_stats_pw;
std::vector< std::vector<unsigned> > m_fail_stats;
unsigned long long m_cache_port_available_cycles;
@@ -1082,6 +1092,10 @@ public:
void get_sub_stats(struct cache_sub_stats &css) const {
m_stats.get_sub_stats(css);
}
+ // Per-window sub stats for AerialVision support
+ void get_sub_stats_pw(struct cache_sub_stats &css) const {
+ m_stats.get_sub_stats_pw(css);
+ }
// accessors for cache bandwidth availability
bool data_port_free() const { return m_bandwidth_management.data_port_free(); }
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index ec570bf..c253367 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -1148,6 +1148,9 @@ void gpgpu_sim::gpu_print_stat()
cache_stats l2_stats;
struct cache_sub_stats l2_css;
struct cache_sub_stats total_l2_css;
+ cache_stats l2_stats_pw;
+ struct cache_sub_stats l2_css_pw;
+ struct cache_sub_stats total_l2_css_pw;
l2_stats.clear();
l2_css.clear();
total_l2_css.clear();
@@ -1156,11 +1159,15 @@ void gpgpu_sim::gpu_print_stat()
for (unsigned i=0;i<m_memory_config->m_n_mem_sub_partition;i++){
m_memory_sub_partition[i]->accumulate_L2cache_stats(l2_stats);
m_memory_sub_partition[i]->get_L2cache_sub_stats(l2_css);
+ m_memory_sub_partition[i]->get_L2cache_sub_stats_pw(l2_css_pw);
fprintf( stdout, "L2_cache_bank[%d]: Access = %u, Miss = %u, Miss_rate = %.3lf, Pending_hits = %u, Reservation_fails = %u\n",
i, l2_css.accesses, l2_css.misses, (double)l2_css.misses / (double)l2_css.accesses, l2_css.pending_hits, l2_css.res_fails);
+ fprintf( stdout, "L2_cache_bank[%d]: Access = %u, Miss = %u, Miss_rate = %.3lf, Pending_hits = %u, Reservation_fails = %u\n",
+ i, l2_css_pw.accesses, l2_css_pw.misses, (double)l2_css_pw.misses / (double)l2_css_pw.accesses, l2_css_pw.pending_hits, l2_css_pw.res_fails);
total_l2_css += l2_css;
+ total_l2_css_pw += l2_css_pw;
}
if (!m_memory_config->m_L2_config.disabled() && m_memory_config->m_L2_config.get_num_lines()) {
//L2c_print_cache_stat();
diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc
index 25da107..a662446 100644
--- a/src/gpgpu-sim/l2cache.cc
+++ b/src/gpgpu-sim/l2cache.cc
@@ -718,6 +718,11 @@ void memory_sub_partition::get_L2cache_sub_stats(struct cache_sub_stats &css) co
}
}
+void memory_sub_partition::get_L2cache_sub_stats_pw(struct cache_sub_stats &css) const{
+ if (!m_config->m_L2_config.disabled()) {
+ m_L2cache->get_sub_stats_pw(css);
+ }
+}
void memory_sub_partition::visualizer_print( gzFile visualizer_file )
{
// TODO: Add visualizer stats for L2 cache
diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h
index 18c0a8b..57f3e94 100644
--- a/src/gpgpu-sim/l2cache.h
+++ b/src/gpgpu-sim/l2cache.h
@@ -180,6 +180,9 @@ public:
void accumulate_L2cache_stats(class cache_stats &l2_stats) const;
void get_L2cache_sub_stats(struct cache_sub_stats &css) const;
+ // Support for getting per-window L2 stats for AerialVision
+ void get_L2cache_sub_stats_pw(struct cache_sub_stats &css) const;
+
void force_l2_tag_update(new_addr_type addr, unsigned time, mem_access_sector_mask_t mask)
{
m_L2cache->force_tag_access( addr, m_memcpy_cycle_offset + time, mask );