diff options
Diffstat (limited to 'src/gpgpu-sim')
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.cc | 80 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.h | 14 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 7 | ||||
| -rw-r--r-- | src/gpgpu-sim/l2cache.cc | 5 | ||||
| -rw-r--r-- | src/gpgpu-sim/l2cache.h | 3 |
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 ); |
