diff options
| -rw-r--r-- | CHANGES | 6 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.cc | 408 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.h | 113 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 64 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.h | 3 | ||||
| -rw-r--r-- | src/gpgpu-sim/l2cache.cc | 89 | ||||
| -rw-r--r-- | src/gpgpu-sim/l2cache.h | 6 | ||||
| -rw-r--r-- | src/gpgpu-sim/mem_latency_stat.cc | 4 | ||||
| -rw-r--r-- | src/gpgpu-sim/mem_latency_stat.h | 8 | ||||
| -rw-r--r-- | src/gpgpu-sim/power_stat.cc | 367 | ||||
| -rw-r--r-- | src/gpgpu-sim/power_stat.h | 975 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 255 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 48 |
13 files changed, 1277 insertions, 1069 deletions
@@ -1,7 +1,11 @@ LOG: Version 3.2.1+edits (development branch) versus 3.2.1 -- Replaced legacy L2 cache access statistics with more meaningful breakdown. - Added NVIDIA Quadro FX5600 GPGPU-Sim and GPUWattch configuration files. +- Added cache_stats class to record all memory accesses and access outcomes + for each cache. Switched from the legacy cache statistics recorded in + the tag_array to the cache access functions. Updated the cache_statistic + printing - providing a more meaningful breakdown. Cleaned up power_stats.cc/h + to reflect the changes in the cache statistics. - Bug Fixes: - Fixed the flit count sent to GPUWattch for atomic operations. - Fix for Bug 51 - Updated the function declaration of diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 28fcd5c..d6282d1 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -97,6 +97,7 @@ void tag_array::init( int core_id, int type_id ) m_access = 0; m_miss = 0; m_pending_hit = 0; + m_res_fail = 0; // initialize snapshot counters for visualizer m_prev_snapshot_access = 0; m_prev_snapshot_miss = 0; @@ -200,7 +201,7 @@ enum cache_request_status tag_array::access( new_addr_type addr, unsigned time, } break; case RESERVATION_FAIL: - m_miss++; + m_res_fail++; shader_cache_access_log(m_core_id, m_type_id, 1); // log cache misses break; } @@ -258,10 +259,12 @@ 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; +void tag_array::get_stats(unsigned &total_access, unsigned &total_misses, unsigned &total_hit_res, unsigned &total_res_fail) const{ + // Update statistics from the tag array + total_access = m_access; + total_misses = m_miss; + total_hit_res = m_pending_hit; + total_res_fail = m_res_fail; } @@ -350,6 +353,150 @@ void mshr_table::display( FILE *fp ) const{ } } /***************************************************************** Caches *****************************************************************/ +cache_stats::cache_stats(){ + m_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); + } +} + +void cache_stats::clear(){ + /// + /// Zero out all current cache statistics + /// + for(std::vector<unsigned> &stats_vec : m_stats){ + std::fill(stats_vec.begin(), stats_vec.end(), 0); + } +} + +void cache_stats::inc_stats(int access_type, int access_outcome){ + /// + /// Increment the stat corresponding to (access_type, access_outcome) by 1. + /// + if(!check_valid(access_type, access_outcome)) + assert(0 && "Unknown cache access type or access outcome"); + + m_stats[access_type][access_outcome]++; +} + +unsigned &cache_stats::operator()(int access_type, int access_outcome){ + /// + /// Simple method to read/modify the stat corresponding to (access_type, access_outcome) + /// Used overloaded () to avoid the need for separate read/write member functions + /// + if(!check_valid(access_type, access_outcome)) + assert(0 && "Unknown cache access type or access outcome"); + + return m_stats[access_type][access_outcome]; +} + +unsigned cache_stats::operator()(int access_type, int access_outcome) const{ + /// + /// Const accessor into m_stats. + /// + if(!check_valid(access_type, access_outcome)) + assert(0 && "Unknown cache access type or access outcome"); + + return m_stats[access_type][access_outcome]; +} + +cache_stats cache_stats::operator+(const cache_stats &cs){ + /// + /// Overloaded + operator to allow for simple stat accumulation + /// + cache_stats ret; + for(unsigned type=0; type<NUM_MEM_ACCESS_TYPE; ++type){ + for(unsigned status=0; status<NUM_CACHE_REQUEST_STATUS; ++status){ + ret(type, status) = m_stats[type][status] + cs(type, status); + } + } + return ret; +} + +cache_stats &cache_stats::operator+=(const cache_stats &cs){ + /// + /// Overloaded += operator to allow for simple stat accumulation + /// + for(unsigned type=0; type<NUM_MEM_ACCESS_TYPE; ++type){ + for(unsigned status=0; status<NUM_CACHE_REQUEST_STATUS; ++status){ + m_stats[type][status] += cs(type, status); + } + } + return *this; +} + +void cache_stats::print_stats(FILE *fout, const char *cache_name) const{ + /// + /// Print out each non-zero cache statistic for every memory access type and status + /// "cache_name" defaults to "Cache_stats" when no argument is provided, otherwise + /// the provided name is used. + /// The printed format is "<cache_name>[<request_type>][<request_status>] = <stat_value>" + /// + std::string m_cache_name = cache_name; + for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { + for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) { + if(m_stats[type][status] > 0){ + 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[type][status]); + } + } + } +} + +unsigned cache_stats::get_stats(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[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. + /// + 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 == HIT_RESERVED) + t_css.accesses += m_stats[type][status]; + + if(status == MISS) + t_css.misses += m_stats[type][status]; + + if(status == HIT_RESERVED) + t_css.pending_hits += m_stats[type][status]; + + if(status == RESERVATION_FAIL) + t_css.res_fails += m_stats[type][status]; + } + } + css = t_css; +} + +bool cache_stats::check_valid(int type, int status) const{ + /// + /// Verify a valid access_type/access_status + /// + if((type >= 0) && (type < NUM_MEM_ACCESS_TYPE) && (status >= 0) && (status < NUM_CACHE_REQUEST_STATUS)) + return true; + else + return false; +} + /// Sends next request to lower level of memory void baseline_cache::cycle(){ if ( !m_miss_queue.empty() ) { @@ -457,7 +604,6 @@ 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; } @@ -474,7 +620,6 @@ 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; } @@ -490,7 +635,6 @@ 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; } @@ -508,54 +652,52 @@ enum cache_request_status data_cache::wr_hit_global_we_local_wb(new_addr_type ad /// Write-allocate miss: Send write request to lower level memory and send a read request for the same block enum cache_request_status data_cache::wr_miss_wa(new_addr_type addr, unsigned cache_index, mem_fetch *mf, unsigned time, std::list<cache_event> &events, enum cache_request_status status) { - new_addr_type block_addr = m_config.block_addr(addr); + new_addr_type block_addr = m_config.block_addr(addr); - // Write allocate, maximum 3 requests (write miss, read request, write back request) - // Conservatively ensure the worst-case request can be handled this cycle - bool mshr_hit = m_mshrs.probe(block_addr); - bool mshr_avail = !m_mshrs.full(block_addr); - if(miss_queue_full(2) || (!(mshr_hit && mshr_avail) && !(!mshr_hit && mshr_avail && (m_miss_queue.size() < m_config.m_miss_queue_size)))) - return RESERVATION_FAIL; + // Write allocate, maximum 3 requests (write miss, read request, write back request) + // Conservatively ensure the worst-case request can be handled this cycle + bool mshr_hit = m_mshrs.probe(block_addr); + bool mshr_avail = !m_mshrs.full(block_addr); + if(miss_queue_full(2) || (!(mshr_hit && mshr_avail) && !(!mshr_hit && mshr_avail && (m_miss_queue.size() < m_config.m_miss_queue_size)))) + return RESERVATION_FAIL; - send_write_request(mf, WRITE_REQUEST_SENT, time, events); - // Tries to send write allocate request, returns true on success and false on failure - //if(!send_write_allocate(mf, addr, block_addr, cache_index, time, events)) - // return RESERVATION_FAIL; + send_write_request(mf, WRITE_REQUEST_SENT, time, events); + // Tries to send write allocate request, returns true on success and false on failure + //if(!send_write_allocate(mf, addr, block_addr, cache_index, time, events)) + // return RESERVATION_FAIL; - const mem_access_t *ma = new mem_access_t( L2_WR_ALLOC_R, - mf->get_addr(), - mf->get_data_size(), - false, // Now performing a read - mf->get_access_warp_mask(), - mf->get_access_byte_mask() ); + const mem_access_t *ma = new mem_access_t( L2_WR_ALLOC_R, + mf->get_addr(), + mf->get_data_size(), + false, // Now performing a read + mf->get_access_warp_mask(), + mf->get_access_byte_mask() ); - mem_fetch *n_mf = new mem_fetch( *ma, - NULL, - mf->get_ctrl_size(), - mf->get_wid(), - mf->get_sid(), - mf->get_tpc(), - mf->get_mem_config()); + mem_fetch *n_mf = new mem_fetch( *ma, + NULL, + mf->get_ctrl_size(), + mf->get_wid(), + mf->get_sid(), + mf->get_tpc(), + mf->get_mem_config()); - bool do_miss = false; - bool wb = false; - cache_block_t evicted; + bool do_miss = false; + bool wb = false; + cache_block_t evicted; - // Send read request resulting from write miss - send_read_request(addr, block_addr, cache_index, n_mf, time, do_miss, wb, evicted, events, false, true); + // Send read request resulting from write miss + send_read_request(addr, block_addr, cache_index, n_mf, time, do_miss, wb, evicted, events, false, true); - if( wb && (m_config.m_write_policy != WRITE_THROUGH) ) { // If evicted block is modified and not a write-through (already modified lower level) - mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr,L2_WRBK_ACC,m_config.get_line_sz(),true); - m_miss_queue.push_back(wb); - wb->set_status(m_miss_queue_status,time); - } - if( do_miss ){ - m_write_access++; - m_write_miss++; - return MISS; - } + if( do_miss ){ + if( wb && (m_config.m_write_policy != WRITE_THROUGH) ) { // If evicted block is modified and not a write-through (already modified lower level) + mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr,L2_WRBK_ACC,m_config.get_line_sz(),true); + m_miss_queue.push_back(wb); + wb->set_status(m_miss_queue_status,time); + } + return MISS; + } - return RESERVATION_FAIL; + return RESERVATION_FAIL; } /// No write-allocate miss: Simply send write request to lower level memory @@ -566,8 +708,6 @@ 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; } @@ -582,8 +722,6 @@ 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; } @@ -591,47 +729,48 @@ enum cache_request_status data_cache::rd_hit_base(new_addr_type addr, unsigned c /// Baseline read miss: Send read request to lower level memory, perform write-back as necessary enum cache_request_status data_cache::rd_miss_base(new_addr_type addr, unsigned cache_index, mem_fetch *mf, unsigned time, std::list<cache_event> &events, enum cache_request_status status ){ - if(miss_queue_full(1)) - return RESERVATION_FAIL; // cannot handle request this cycle (might need to generate two requests) + if(miss_queue_full(1)) + return RESERVATION_FAIL; // cannot handle request this cycle (might need to generate two requests) - new_addr_type block_addr = m_config.block_addr(addr); - bool do_miss = false; - bool wb = false; - cache_block_t evicted; - send_read_request(addr, block_addr, cache_index, mf, time, do_miss, wb, evicted, events, false, false); + new_addr_type block_addr = m_config.block_addr(addr); + bool do_miss = false; + bool wb = false; + cache_block_t evicted; + send_read_request(addr, block_addr, cache_index, mf, time, do_miss, wb, evicted, events, false, false); - if(wb && (m_config.m_write_policy != WRITE_THROUGH) ){ // If evicted block is modified and not a write-through (already modified lower level) - 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 ){ - m_read_access++; - m_read_miss++; - return MISS; - } - return RESERVATION_FAIL; + if( do_miss ){ + if(wb && (m_config.m_write_policy != WRITE_THROUGH) ){ // If evicted block is modified and not a write-through (already modified lower level) + 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); + } + return MISS; + } + return RESERVATION_FAIL; } /// Access cache for read_only_cache: returns RESERVATION_FAIL if request could not be accepted (for any reason) enum cache_request_status read_only_cache::access( new_addr_type addr, mem_fetch *mf, unsigned time, std::list<cache_event> &events ) { - assert( mf->get_data_size() <= m_config.get_line_sz()); - assert(m_config.m_write_policy == READ_ONLY); - assert(!mf->get_is_write()); - new_addr_type block_addr = m_config.block_addr(addr); - unsigned cache_index = (unsigned)-1; - enum cache_request_status status = m_tag_array->probe(block_addr,cache_index); - if ( status == HIT ) { - m_tag_array->access(block_addr,time,cache_index); // update LRU state - return HIT; - }else if ( status != RESERVATION_FAIL ) { - if(!miss_queue_full(0)){ - bool do_miss=false; - send_read_request(addr, block_addr, cache_index, mf, time, do_miss, events, true, false); - if(do_miss) - return MISS; - } - } - return RESERVATION_FAIL; + assert( mf->get_data_size() <= m_config.get_line_sz()); + assert(m_config.m_write_policy == READ_ONLY); + assert(!mf->get_is_write()); + new_addr_type block_addr = m_config.block_addr(addr); + unsigned cache_index = (unsigned)-1; + enum cache_request_status status = m_tag_array->probe(block_addr,cache_index); + + if ( status == HIT ) { + m_tag_array->access(block_addr,time,cache_index); // update LRU state + }else if ( status != RESERVATION_FAIL ) { + if(!miss_queue_full(0)){ + bool do_miss=false; + send_read_request(addr, block_addr, cache_index, mf, time, do_miss, events, true, false); + if(do_miss) + status = MISS; + } + }else{ + status = RESERVATION_FAIL; + } + m_stats.inc_stats(mf->get_access_type(), status); + return status; } /// This is meant to model the first level data cache in Fermi. @@ -639,56 +778,60 @@ enum cache_request_status read_only_cache::access( new_addr_type addr, mem_fetch /// (the policy used in fermi according to the CUDA manual) enum cache_request_status l1_cache::access( new_addr_type addr, mem_fetch *mf, unsigned time, std::list<cache_event> &events ){ - assert( mf->get_data_size() <= m_config.get_line_sz()); - bool wr = mf->get_is_write(); - new_addr_type block_addr = m_config.block_addr(addr); - unsigned cache_index = (unsigned)-1; - enum cache_request_status status = m_tag_array->probe(block_addr,cache_index); + assert( mf->get_data_size() <= m_config.get_line_sz()); + bool wr = mf->get_is_write(); + new_addr_type block_addr = m_config.block_addr(addr); + unsigned cache_index = (unsigned)-1; + enum cache_request_status status = m_tag_array->probe(block_addr,cache_index); + enum cache_request_status cache_status = RESERVATION_FAIL; - // 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 - if(status == HIT){ - return (this->*m_wr_hit)(addr, cache_index, mf, time, events, status); - }else if ( status != RESERVATION_FAIL ) { - return (this->*m_wr_miss)(addr, cache_index, mf, time, events, status); - } - }else{ // Read - if(status == HIT){ - return (this->*m_rd_hit)(addr, cache_index, mf, time, events, status); - }else if ( status != RESERVATION_FAIL ) { - return (this->*m_rd_miss)(addr, cache_index, mf, time, events, status); - } - } - return RESERVATION_FAIL; + // 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 + if(status == HIT){ + cache_status = (this->*m_wr_hit)(addr, cache_index, mf, time, events, status); + }else if ( status != RESERVATION_FAIL ) { + cache_status = (this->*m_wr_miss)(addr, cache_index, mf, time, events, status); + } + }else{ // Read + if(status == HIT){ + cache_status = (this->*m_rd_hit)(addr, cache_index, mf, time, events, status); + }else if ( status != RESERVATION_FAIL ) { + cache_status = (this->*m_rd_miss)(addr, cache_index, mf, time, events, status); + } + } + m_stats.inc_stats(mf->get_access_type(), cache_status); + return cache_status; } /// Models second level shared cache with global write-back and write-allocate policies /// Currently the same as l1_cache, but separated to allow for different implementations enum cache_request_status l2_cache::access( new_addr_type addr, mem_fetch *mf, unsigned time, std::list<cache_event> &events ){ - assert( mf->get_data_size() <= m_config.get_line_sz()); - bool wr = mf->get_is_write(); - new_addr_type block_addr = m_config.block_addr(addr); - unsigned cache_index = (unsigned)-1; - enum cache_request_status status = m_tag_array->probe(block_addr,cache_index); + assert( mf->get_data_size() <= m_config.get_line_sz()); + bool wr = mf->get_is_write(); + new_addr_type block_addr = m_config.block_addr(addr); + unsigned cache_index = (unsigned)-1; + enum cache_request_status status = m_tag_array->probe(block_addr,cache_index); + enum cache_request_status cache_status = RESERVATION_FAIL; - // 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 - if(status == HIT){ - return (this->*m_wr_hit)(addr, cache_index, mf, time, events, status); - }else if ( status != RESERVATION_FAIL ) { - return (this->*m_wr_miss)(addr, cache_index, mf, time, events, status); - } - }else{ // Read - if(status == HIT){ - return (this->*m_rd_hit)(addr, cache_index, mf, time, events, status); - }else if ( status != RESERVATION_FAIL ) { - return (this->*m_rd_miss)(addr, cache_index, mf, time, events, status); - } - } - return RESERVATION_FAIL; + // 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 + if(status == HIT){ + cache_status = (this->*m_wr_hit)(addr, cache_index, mf, time, events, status); + }else if ( status != RESERVATION_FAIL ) { + cache_status = (this->*m_wr_miss)(addr, cache_index, mf, time, events, status); + } + }else{ // Read + if(status == HIT){ + cache_status = (this->*m_rd_hit)(addr, cache_index, mf, time, events, status); + }else if ( status != RESERVATION_FAIL ) { + cache_status = (this->*m_rd_miss)(addr, cache_index, mf, time, events, status); + } + } + m_stats.inc_stats(mf->get_access_type(), cache_status); + return cache_status; } /// Access function for tex_cache @@ -706,6 +849,7 @@ enum cache_request_status tex_cache::access( new_addr_type addr, mem_fetch *mf, new_addr_type block_addr = m_config.block_addr(addr); unsigned cache_index = (unsigned)-1; enum cache_request_status status = m_tags.access(block_addr,time,cache_index); + enum cache_request_status cache_status = RESERVATION_FAIL; assert( status != RESERVATION_FAIL ); assert( status != HIT_RESERVED ); // as far as tags are concerned: HIT or MISS m_fragment_fifo.push( fragment_entry(mf,cache_index,status==MISS,mf->get_data_size()) ); @@ -718,11 +862,13 @@ enum cache_request_status tex_cache::access( new_addr_type addr, mem_fetch *mf, m_request_fifo.push(mf); mf->set_status(m_request_queue_status,time); events.push_back(READ_REQUEST_SENT); - return MISS; + cache_status = MISS; } else { // the value *will* *be* in the cache already - return HIT_RESERVED; + cache_status = HIT_RESERVED; } + m_stats.inc_stats(mf->get_access_type(), cache_status); + return cache_status; } void tex_cache::cycle(){ diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 59e56bc..90805be 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -319,7 +319,8 @@ public: 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; + void get_stats(unsigned &total_access, unsigned &total_misses, unsigned &total_hit_res, unsigned &total_res_fail) const; + void update_cache_parameters(cache_config &config); protected: // This constructor is intended for use only from derived classes that wish to @@ -340,6 +341,7 @@ protected: unsigned m_access; unsigned m_miss; unsigned m_pending_hit; // number of cache miss that hit a line that is allocated but not filled + unsigned m_res_fail; // performance counters for calculating the amount of misses within a time window unsigned m_prev_snapshot_access; @@ -405,6 +407,73 @@ private: /***************************************************************** Caches *****************************************************************/ +/// +/// Simple struct to maintain cache accesses, misses, pending hits, and reservation fails. +/// +struct cache_sub_stats{ + unsigned accesses; + unsigned misses; + unsigned pending_hits; + unsigned res_fails; + + cache_sub_stats(){ + clear(); + } + void clear(){ + accesses = 0; + misses = 0; + pending_hits = 0; + res_fails = 0; + } + cache_sub_stats &operator+=(const cache_sub_stats &css){ + /// + /// Overloading += operator to easily accumulate stats + /// + accesses += css.accesses; + misses += css.misses; + pending_hits += css.pending_hits; + res_fails += css.res_fails; + return *this; + } + + cache_sub_stats operator+(const cache_sub_stats &cs){ + /// + /// Overloading + operator to easily accumulate stats + /// + cache_sub_stats ret; + ret.accesses = accesses + cs.accesses; + ret.misses = misses + cs.misses; + ret.pending_hits = pending_hits + cs.pending_hits; + ret.res_fails = res_fails + cs.res_fails; + return ret; + } +}; + +/// +/// Cache_stats +/// Used to record statistics for each cache. +/// Maintains a record of every 'mem_access_type' and its resulting +/// 'cache_request_status' : [mem_access_type][cache_request_status] +/// +class cache_stats { +public: + cache_stats(); + void clear(); + void inc_stats(int access_type, int access_outcome); + unsigned &operator()(int access_type, int access_outcome); + unsigned operator()(int access_type, int access_outcome) const; + cache_stats operator+(const cache_stats &cs); + cache_stats &operator+=(const cache_stats &cs); + void print_stats(FILE *fout, const char *cache_name = "Cache_stats") const; + + 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; + +private: + bool check_valid(int type, int status) const; + + std::vector<std::vector<unsigned>> m_stats; +}; class cache_t { public: @@ -436,10 +505,6 @@ 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 ~baseline_cache() @@ -470,15 +535,15 @@ 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; + // Stat collection + const cache_stats &get_stats() const { + return m_stats; } - - void get_stats(unsigned &accesses, unsigned &misses) const { - m_tag_array->get_stats(accesses, misses); + unsigned get_stats(enum mem_access_type *access_type, unsigned num_access_type, enum cache_request_status *access_status, unsigned num_access_status) const{ + return m_stats.get_stats(access_type, num_access_type, access_status, num_access_status); + } + void get_sub_stats(struct cache_sub_stats &css) const { + m_stats.get_sub_stats(css); } protected: @@ -525,6 +590,8 @@ protected: extra_mf_fields_lookup m_extra_mf_fields; + cache_stats m_stats; + /// Checks whether this request can be handled on this cycle. num_miss equals max # of misses to be handled on this cycle bool miss_queue_full(unsigned num_miss){ return ( (m_miss_queue.size()+num_miss) >= m_config.m_miss_queue_size ); @@ -535,12 +602,6 @@ protected: /// 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; }; /// Read only cache @@ -600,7 +661,6 @@ public: } } - protected: data_cache( const char *name, cache_config &config, @@ -736,10 +796,17 @@ 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); + // Stat collection + const cache_stats &get_stats() const { + return m_stats; + } + unsigned get_stats(enum mem_access_type *access_type, unsigned num_access_type, enum cache_request_status *access_status, unsigned num_access_status) const{ + return m_stats.get_stats(access_type, num_access_type, access_status, num_access_status); } + void get_sub_stats(struct cache_sub_stats &css) const{ + m_stats.get_sub_stats(css); + } private: std::string m_name; const cache_config &m_config; @@ -863,6 +930,8 @@ private: unsigned m_rob_index; }; + cache_stats m_stats; + typedef std::map<mem_fetch*,extra_mf_fields> extra_mf_fields_lookup; extra_mf_fields_lookup m_extra_mf_fields; diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index c38b133..33393ee 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -883,7 +883,16 @@ void gpgpu_sim::gpu_print_stat() unsigned long long elapsed_time = MAX( curr_time - g_simulation_starttime, 1 ); printf( "gpu_total_sim_rate=%u\n", (unsigned)( ( gpu_tot_sim_insn + gpu_sim_insn ) / elapsed_time ) ); - shader_print_l1_miss_stat( stdout ); + //shader_print_l1_miss_stat( stdout ); + shader_print_cache_stats(stdout); + + cache_stats core_cache_stats; + core_cache_stats.clear(); + for(unsigned i=0; i<m_config.num_cluster(); i++){ + m_cluster[i]->get_cache_stats(core_cache_stats); + } + printf("\nTotal_core_cache_stats:\n"); + core_cache_stats.print_stats(stdout, "Total_core_cache_stats_breakdown"); shader_print_scheduler_stat( stdout, false ); m_shader_stats->print(stdout); @@ -896,12 +905,38 @@ void gpgpu_sim::gpu_print_stat() // performance counter that are not local to one shader m_memory_stats->memlatstat_print(m_memory_config->m_n_mem,m_memory_config->nbk); - for (unsigned i=0;i<m_memory_config->m_n_mem;i++) + for (unsigned i=0;i<m_memory_config->m_n_mem;i++) m_memory_partition_unit[i]->print(stdout); + + // L2 cache stats + cache_stats l2_stats; + struct cache_sub_stats l2_css; + struct cache_sub_stats total_l2_css; + l2_stats.clear(); + l2_css.clear(); + total_l2_css.clear(); + + printf("\n========= L2 cache stats =========\n"); + for (unsigned i=0;i<m_memory_config->m_n_mem;i++){ + m_memory_partition_unit[i]->accumulate_L2cache_stats(l2_stats); + m_memory_partition_unit[i]->get_L2cache_sub_stats(l2_css); + + 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); + + total_l2_css += l2_css; + } if (!m_memory_config->m_L2_config.disabled() && m_memory_config->m_L2_config.get_num_lines()) { - L2c_print_cache_stat(); - m_memory_stats->print_L2cache_stats(stdout); + //L2c_print_cache_stat(); + printf("L2_total_cache_accesses = %u\n", total_l2_css.accesses); + printf("L2_total_cache_misses = %u\n", total_l2_css.misses); + printf("L2_total_cache_miss_rate = %.4lf\n", (double)total_l2_css.misses/(double)total_l2_css.accesses); + printf("L2_total_cache_pending_hits = %u\n", total_l2_css.pending_hits); + printf("L2_total_cache_reservation_fails = %u\n", total_l2_css.res_fails); + printf("L2_total_cache_breakdown:\n"); + l2_stats.print_stats(stdout, "L2_cache_stats_breakdown"); } + if (m_config.gpgpu_cflog_interval != 0) { spill_log_to_file (stdout, 1, gpu_sim_cycle); insn_warp_occ_print(stdout); @@ -924,14 +959,13 @@ void gpgpu_sim::gpu_print_stat() long temp_stm=0; long temp_mts = 0; for(unsigned i=0; i<m_config.num_cluster(); i++){ - m_cluster[i]->set_icnt_stats(temp_stm, temp_mts); + m_cluster[i]->get_icnt_stats(temp_stm, temp_mts); total_simt_to_mem += temp_stm; total_mem_to_simt += temp_mts; } printf("\nicnt_total_pkts_mem_to_simt=%ld\n", total_mem_to_simt); printf("icnt_total_pkts_simt_to_mem=%ld\n", total_simt_to_mem); - time_vector_print(); fflush(stdout); @@ -1128,14 +1162,15 @@ void gpgpu_sim::cycle() 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]); + m_memory_partition_unit[i]->set_dram_power_stats(m_power_stats->pwr_mem_stat->n_cmd[CURRENT_STAT_IDX][i], m_power_stats->pwr_mem_stat->n_activity[CURRENT_STAT_IDX][i], + m_power_stats->pwr_mem_stat->n_nop[CURRENT_STAT_IDX][i], m_power_stats->pwr_mem_stat->n_act[CURRENT_STAT_IDX][i], m_power_stats->pwr_mem_stat->n_pre[CURRENT_STAT_IDX][i], + m_power_stats->pwr_mem_stat->n_rd[CURRENT_STAT_IDX][i], m_power_stats->pwr_mem_stat->n_wr[CURRENT_STAT_IDX][i], m_power_stats->pwr_mem_stat->n_req[CURRENT_STAT_IDX][i]); } } // L2 operations follow L2 clock domain if (clock_mask & L2) { + m_power_stats->pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].clear(); for (unsigned i=0;i<m_memory_config->m_n_mem;i++) { //move memory request from interconnect into memory partition (if not backed up) //Note:This needs to be called in DRAM clock domain if there is no L2 cache in the system @@ -1146,8 +1181,7 @@ 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]->accumulate_L2cache_stats(m_power_stats->pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX]); } } @@ -1156,14 +1190,16 @@ void gpgpu_sim::cycle() } if (clock_mask & CORE) { - // L1 cache + shader core pipeline stages + // L1 cache + shader core pipeline stages + m_power_stats->pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].clear(); 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(); - - m_cluster[i]->set_icnt_stats(m_power_stats->pwr_mem_stat->n_simt_to_mem[0][i], m_power_stats->pwr_mem_stat->n_mem_to_simt[0][i]); } + // Update core icnt/cache stats for GPUWattch + m_cluster[i]->get_icnt_stats(m_power_stats->pwr_mem_stat->n_simt_to_mem[CURRENT_STAT_IDX][i], m_power_stats->pwr_mem_stat->n_mem_to_simt[CURRENT_STAT_IDX][i]); + m_cluster[i]->get_cache_stats(m_power_stats->pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX]); } float temp=0; for (unsigned i=0;i<m_shader_config->num_shader();i++){ diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index cadddac..90f8cb6 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -414,10 +414,11 @@ private: void reinit_clock_domains(void); int next_clock_domain(void); void issue_block2core(); - void print_dram_L2_stats(FILE *fout) const; + void print_dram_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; + void shader_print_cache_stats( FILE *fout ) const; void shader_print_scheduler_stat( FILE* fout, bool print_dynamic_info ) const; void visualizer_printstat(); void print_shader_cycle_distro( FILE *fout ) const; diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index 6623d43..a661b4b 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -171,7 +171,6 @@ void memory_partition_unit::cache_cycle( unsigned cycle ) assert(!read_sent); // L2 cache lock-up: will try again next cycle } - m_stats->memlatstat_L2cache_access(mf, status); } } else { // L2 is disabled or non-texture access to texture-only L2 @@ -219,44 +218,6 @@ void memory_partition_unit::print( FILE *fp ) const m_dram->print(fp); } -void memory_stats_t::print_L2cache_stats( FILE *fp ) -{ - - // 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); - - unsigned total_L2_accesses = 0; - unsigned total_L2_misses = 0; - - for (int type = 0; type < NUM_MEM_ACCESS_TYPE; type++) { - for (int status = 0; status < NUM_CACHE_REQUEST_STATUS; status++) { - if (m_L2CacheAccessBreakdown[type][status] > 0) { - fprintf(fp, "L2CacheAccessBreakdown[%s][%s] = %u\n", - mem_access_type_str((enum mem_access_type)type), - cache_request_status_str((enum cache_request_status)status), - m_L2CacheAccessBreakdown[type][status]); - switch (status) { - case HIT: - case HIT_RESERVED: - total_L2_accesses += m_L2CacheAccessBreakdown[type][status]; - break; - case MISS: - total_L2_accesses += m_L2CacheAccessBreakdown[type][status]; - total_L2_misses += m_L2CacheAccessBreakdown[type][status]; - break; - case RESERVATION_FAIL: break; - default: assert(0); - } - } - } - } - - fprintf(fp, "L2Cache_Total_Accesses = %u\n", total_L2_accesses); - fprintf(fp, "L2Cache_Total_Misses = %u\n", total_L2_misses); -} - void memory_stats_t::visualizer_print( gzFile visualizer_file ) { // gzprintf(visualizer_file, "Ltwowritemiss: %d\n", L2_write_miss); @@ -267,23 +228,8 @@ void memory_stats_t::visualizer_print( gzFile visualizer_file ) gzprintf(visualizer_file, "averagemflatency: %lld\n", mf_total_lat/num_mfs); } -// record the outcome of L2 cache access by this memory request -void memory_stats_t::memlatstat_L2cache_access(mem_fetch *mf, int access_outcome) +void gpgpu_sim::print_dram_stats(FILE *fout) const { - switch(access_outcome) { - case HIT: - case HIT_RESERVED: - case MISS: - case RESERVATION_FAIL: - m_L2CacheAccessBreakdown[mf->get_access_type()][access_outcome] += 1; - break; - default: assert(0 && "Unknown cache access outcome"); break; - } -} - -void gpgpu_sim::print_dram_L2_stats(FILE *fout) const -{ - unsigned cmd=0; unsigned activity=0; unsigned nop=0; @@ -292,10 +238,6 @@ void gpgpu_sim::print_dram_L2_stats(FILE *fout) const 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; @@ -303,14 +245,9 @@ void gpgpu_sim::print_dram_L2_stats(FILE *fout) const 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; @@ -318,19 +255,14 @@ void gpgpu_sim::print_dram_L2_stats(FILE *fout) const 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 ); - + fprintf(fout,"gpgpu_n_dram_commands = %d\n",tot_cmd); + fprintf(fout,"gpgpu_n_dram_noops = %d\n",tot_nop ); + fprintf(fout,"gpgpu_n_dram_precharges = %d\n",tot_pre ); + fprintf(fout,"gpgpu_n_dram_requests = %d\n",tot_req ); } void gpgpu_sim::L2c_print_cache_stat() const { @@ -446,9 +378,10 @@ void memory_partition_unit::set_dram_power_stats(unsigned &n_cmd, 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::accumulate_L2cache_stats(class cache_stats &l2_stats) const { + l2_stats += m_L2cache->get_stats(); +} + +void memory_partition_unit::get_L2cache_sub_stats(struct cache_sub_stats &css) const{ + m_L2cache->get_sub_stats(css); } diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h index 31b9c4a..6ef00a7 100644 --- a/src/gpgpu-sim/l2cache.h +++ b/src/gpgpu-sim/l2cache.h @@ -88,10 +88,8 @@ public: 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 accumulate_L2cache_stats(class cache_stats &l2_stats) const; + void get_L2cache_sub_stats(struct cache_sub_stats &css) const; private: // data diff --git a/src/gpgpu-sim/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc index a2c4177..fde0eff 100644 --- a/src/gpgpu-sim/mem_latency_stat.cc +++ b/src/gpgpu-sim/mem_latency_stat.cc @@ -125,10 +125,6 @@ memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_conf } } - // L2_write_miss=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)); L2_L2tocblength = (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 4bfb165..4968a3b 100644 --- a/src/gpgpu-sim/mem_latency_stat.h +++ b/src/gpgpu-sim/mem_latency_stat.h @@ -40,13 +40,11 @@ public: unsigned memlatstat_done( class mem_fetch *mf ); void memlatstat_read_done( class mem_fetch *mf ); - void memlatstat_L2cache_access( class mem_fetch *mf, int access_outcome ); void memlatstat_dram_access( class mem_fetch *mf ); void memlatstat_icnt2mem_pop( class mem_fetch *mf); void memlatstat_lat_pw(); void memlatstat_print(unsigned n_mem, unsigned gpu_mem_n_bk); - void print_L2cache_stats( FILE *fp ); void visualizer_print( gzFile visualizer_file ); unsigned m_n_shader; @@ -84,12 +82,6 @@ public: // L2 cache stats - typedef std::map<int, std::map<int, unsigned> > L2CacheAccessBreakdown_t; // <access type, outcome, count> - L2CacheAccessBreakdown_t m_L2CacheAccessBreakdown; - // unsigned L2_write_access; - // unsigned L2_write_miss; - // unsigned L2_read_access; - // unsigned L2_read_miss; unsigned int *L2_cbtoL2length; unsigned int *L2_cbtoL2writelength; unsigned int *L2_L2tocblength; diff --git a/src/gpgpu-sim/power_stat.cc b/src/gpgpu-sim/power_stat.cc index 74c8aef..4c995e9 100644 --- a/src/gpgpu-sim/power_stat.cc +++ b/src/gpgpu-sim/power_stat.cc @@ -53,91 +53,53 @@ power_mem_stat_t::power_mem_stat_t(const struct memory_config *mem_config, const } 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 + shmem_read_access[CURRENT_STAT_IDX] = m_core_stats->gpgpu_n_shmem_bank_access; // Shared memory access + shmem_read_access[PREV_STAT_IDX] = (unsigned *)calloc(m_core_config->num_shader(),sizeof(unsigned)); - 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)); + for(unsigned i=0; i<NUM_STAT_IDX; ++i){ + core_cache_stats[i].clear(); + l2_cache_stats[i].clear(); - shmem_read_access[1] = (unsigned *)calloc(m_core_config->num_shader(),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)); - // 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_mem_to_simt[i] = (long *)calloc(m_core_config->n_simt_clusters,sizeof(long)); // Counted at SM - n_simt_to_mem[i] = (long *)calloc(m_core_config->n_simt_clusters,sizeof(long)); // Counted at SM + // Interconnect stats + n_mem_to_simt[i] = (long *)calloc(m_core_config->n_simt_clusters,sizeof(long)); // Counted at SM + n_simt_to_mem[i] = (long *)calloc(m_core_config->n_simt_clusters,sizeof(long)); // 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 - - } + core_cache_stats[PREV_STAT_IDX] = core_cache_stats[CURRENT_STAT_IDX]; + l2_cache_stats[PREV_STAT_IDX] = l2_cache_stats[CURRENT_STAT_IDX]; - 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]; - } + for(unsigned i=0; i<m_core_config->num_shader(); ++i){ + shmem_read_access[PREV_STAT_IDX][i] = shmem_read_access[CURRENT_STAT_IDX][i] ; // Shared memory access + } - for(unsigned i=0; i<m_core_config->n_simt_clusters;i++){ - n_simt_to_mem[1][i] = n_simt_to_mem[0][i]; // Interconnect - n_mem_to_simt[1][i] = n_mem_to_simt[0][i]; // Interconnect + for(unsigned i=0; i<m_config->m_n_mem; ++i){ + n_cmd[PREV_STAT_IDX][i] = n_cmd[CURRENT_STAT_IDX][i]; + n_activity[PREV_STAT_IDX][i] = n_activity[CURRENT_STAT_IDX][i]; + n_nop[PREV_STAT_IDX][i] = n_nop[CURRENT_STAT_IDX][i]; + n_act[PREV_STAT_IDX][i] = n_act[CURRENT_STAT_IDX][i]; + n_pre[PREV_STAT_IDX][i] = n_pre[CURRENT_STAT_IDX][i]; + n_rd[PREV_STAT_IDX][i] = n_rd[CURRENT_STAT_IDX][i]; + n_wr[PREV_STAT_IDX][i] = n_wr[CURRENT_STAT_IDX][i]; + n_req[PREV_STAT_IDX][i] = n_req[CURRENT_STAT_IDX][i]; + } - } + for(unsigned i=0; i<m_core_config->n_simt_clusters;i++){ + n_simt_to_mem[PREV_STAT_IDX][i] = n_simt_to_mem[CURRENT_STAT_IDX][i]; // Interconnect + n_mem_to_simt[PREV_STAT_IDX][i] = n_mem_to_simt[CURRENT_STAT_IDX][i]; // Interconnect + } } void power_mem_stat_t::visualizer_print( gzFile power_visualizer_file ){ @@ -146,29 +108,20 @@ 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]); - } + 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[CURRENT_STAT_IDX][i]; + total_mem_writes += n_wr[CURRENT_STAT_IDX][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); + + fprintf(fout, "Core cache stats:\n"); + core_cache_stats->print_stats(fout); + fprintf(fout, "L2 cache stats:\n"); + l2_cache_stats->print_stats(fout); } @@ -192,125 +145,125 @@ 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]); - } + 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[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal Deocded Instructions=%u\n",m_num_decoded_insn[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal FP Deocded Instructions=%u\n",m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal INT Deocded Instructions=%u\n",m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal LOAD Queued Instructions=%u\n",m_num_loadqueued_insn[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal STORE Queued Instructions=%u\n",m_num_storequeued_insn[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal IALU Acesses=%u\n",m_num_ialu_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal FP Acesses=%u\n",m_num_fp_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal IMUL Acesses=%u\n",m_num_imul_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal IMUL24 Acesses=%u\n",m_num_imul24_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal IMUL32 Acesses=%u\n",m_num_imul32_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal IDIV Acesses=%u\n",m_num_idiv_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal FPMUL Acesses=%u\n",m_num_fpmul_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal SFU Acesses=%u\n",m_num_trans_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal FPDIV Acesses=%u\n",m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal SFU Acesses=%u\n",m_num_sfu_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal SP Acesses=%u\n",m_num_sp_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal MEM Acesses=%u\n",m_num_mem_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal SFU Commissions=%u\n",m_num_sfu_committed[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal SP Commissions=%u\n",m_num_sp_committed[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal MEM Commissions=%u\n",m_num_mem_committed[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal REG Reads=%u\n",m_read_regfile_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal REG Writes=%u\n",m_write_regfile_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout,"\tTotal NON REG=%u\n",m_non_rf_operands[CURRENT_STAT_IDX][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[CURRENT_STAT_IDX]=m_core_stats->m_pipeline_duty_cycle; + m_num_decoded_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_decoded_insn; + m_num_FPdecoded_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_FPdecoded_insn; + m_num_INTdecoded_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_INTdecoded_insn; + m_num_storequeued_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_storequeued_insn; + m_num_loadqueued_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_loadqueued_insn; + m_num_ialu_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_ialu_acesses; + m_num_fp_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_fp_acesses; + m_num_imul_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_imul_acesses; + m_num_imul24_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_imul24_acesses; + m_num_imul32_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_imul32_acesses; + m_num_fpmul_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_fpmul_acesses; + m_num_idiv_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_idiv_acesses; + m_num_fpdiv_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_fpdiv_acesses; + m_num_sp_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_sp_acesses; + m_num_sfu_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_sfu_acesses; + m_num_trans_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_trans_acesses; + m_num_mem_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_mem_acesses; + m_num_sp_committed[CURRENT_STAT_IDX]=m_core_stats->m_num_sp_committed; + m_num_sfu_committed[CURRENT_STAT_IDX]=m_core_stats->m_num_sfu_committed; + m_num_mem_committed[CURRENT_STAT_IDX]=m_core_stats->m_num_mem_committed; + m_read_regfile_acesses[CURRENT_STAT_IDX]=m_core_stats->m_read_regfile_acesses; + m_write_regfile_acesses[CURRENT_STAT_IDX]=m_core_stats->m_write_regfile_acesses; + m_non_rf_operands[CURRENT_STAT_IDX]=m_core_stats->m_non_rf_operands; + m_active_sp_lanes[CURRENT_STAT_IDX]=m_core_stats->m_active_sp_lanes; + m_active_sfu_lanes[CURRENT_STAT_IDX]=m_core_stats->m_active_sfu_lanes; + m_num_tex_inst[CURRENT_STAT_IDX]=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)); + m_pipeline_duty_cycle[PREV_STAT_IDX]=(float*)calloc(m_config->num_shader(),sizeof(float)); + m_num_decoded_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_FPdecoded_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_INTdecoded_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_storequeued_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_loadqueued_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_ialu_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_fp_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_tex_inst[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_imul_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_imul24_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_imul32_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_fpmul_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_idiv_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_fpdiv_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_sp_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_sfu_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_trans_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_mem_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_sp_committed[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_sfu_committed[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_num_mem_committed[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_read_regfile_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_write_regfile_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_non_rf_operands[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_active_sp_lanes[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); + m_active_sfu_lanes[PREV_STAT_IDX]=(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]; - } +for(unsigned i=0; i<m_config->num_shader(); ++i){ + m_pipeline_duty_cycle[PREV_STAT_IDX][i]=m_pipeline_duty_cycle[CURRENT_STAT_IDX][i]; + m_num_decoded_insn[PREV_STAT_IDX][i]= m_num_decoded_insn[CURRENT_STAT_IDX][i]; + m_num_FPdecoded_insn[PREV_STAT_IDX][i]=m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]; + m_num_INTdecoded_insn[PREV_STAT_IDX][i]=m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]; + m_num_storequeued_insn[PREV_STAT_IDX][i]=m_num_storequeued_insn[CURRENT_STAT_IDX][i]; + m_num_loadqueued_insn[PREV_STAT_IDX][i]=m_num_loadqueued_insn[CURRENT_STAT_IDX][i]; + m_num_ialu_acesses[PREV_STAT_IDX][i]=m_num_ialu_acesses[CURRENT_STAT_IDX][i]; + m_num_fp_acesses[PREV_STAT_IDX][i]=m_num_fp_acesses[CURRENT_STAT_IDX][i]; + m_num_tex_inst[PREV_STAT_IDX][i]=m_num_tex_inst[CURRENT_STAT_IDX][i]; + m_num_imul_acesses[PREV_STAT_IDX][i]=m_num_imul_acesses[CURRENT_STAT_IDX][i]; + m_num_imul24_acesses[PREV_STAT_IDX][i]=m_num_imul24_acesses[CURRENT_STAT_IDX][i]; + m_num_imul32_acesses[PREV_STAT_IDX][i]=m_num_imul32_acesses[CURRENT_STAT_IDX][i]; + m_num_fpmul_acesses[PREV_STAT_IDX][i]=m_num_fpmul_acesses[CURRENT_STAT_IDX][i]; + m_num_idiv_acesses[PREV_STAT_IDX][i]=m_num_idiv_acesses[CURRENT_STAT_IDX][i]; + m_num_fpdiv_acesses[PREV_STAT_IDX][i]=m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]; + m_num_sp_acesses[PREV_STAT_IDX][i]=m_num_sp_acesses[CURRENT_STAT_IDX][i]; + m_num_sfu_acesses[PREV_STAT_IDX][i]=m_num_sfu_acesses[CURRENT_STAT_IDX][i]; + m_num_trans_acesses[PREV_STAT_IDX][i]=m_num_trans_acesses[CURRENT_STAT_IDX][i]; + m_num_mem_acesses[PREV_STAT_IDX][i]=m_num_mem_acesses[CURRENT_STAT_IDX][i]; + m_num_sp_committed[PREV_STAT_IDX][i]=m_num_sp_committed[CURRENT_STAT_IDX][i]; + m_num_sfu_committed[PREV_STAT_IDX][i]=m_num_sfu_committed[CURRENT_STAT_IDX][i]; + m_num_mem_committed[PREV_STAT_IDX][i]=m_num_mem_committed[CURRENT_STAT_IDX][i]; + m_read_regfile_acesses[PREV_STAT_IDX][i]=m_read_regfile_acesses[CURRENT_STAT_IDX][i]; + m_write_regfile_acesses[PREV_STAT_IDX][i]=m_write_regfile_acesses[CURRENT_STAT_IDX][i]; + m_non_rf_operands[PREV_STAT_IDX][i]=m_non_rf_operands[CURRENT_STAT_IDX][i]; + m_active_sp_lanes[PREV_STAT_IDX][i]=m_active_sp_lanes[CURRENT_STAT_IDX][i]; + m_active_sfu_lanes[PREV_STAT_IDX][i]=m_active_sfu_lanes[CURRENT_STAT_IDX][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) diff --git a/src/gpgpu-sim/power_stat.h b/src/gpgpu-sim/power_stat.h index 75bdd28..20af2e5 100644 --- a/src/gpgpu-sim/power_stat.h +++ b/src/gpgpu-sim/power_stat.h @@ -31,38 +31,44 @@ #include <stdio.h> #include <zlib.h> #include "mem_latency_stat.h" -#include "shader.h" #include "gpu-sim.h" +typedef enum _stat_idx{ + CURRENT_STAT_IDX = 0, // Current activity count + PREV_STAT_IDX, // Previous sample activity count + NUM_STAT_IDX // Total number of samples +}stat_idx; + + 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]; + // [CURRENT_STAT_IDX] = CURRENT_STAT_IDX stat, [PREV_STAT_IDX] = last reading + float *m_pipeline_duty_cycle[NUM_STAT_IDX]; + unsigned *m_num_decoded_insn[NUM_STAT_IDX]; // number of instructions committed by this shader core + unsigned *m_num_FPdecoded_insn[NUM_STAT_IDX]; // number of instructions committed by this shader core + unsigned *m_num_INTdecoded_insn[NUM_STAT_IDX]; // number of instructions committed by this shader core + unsigned *m_num_storequeued_insn[NUM_STAT_IDX]; + unsigned *m_num_loadqueued_insn[NUM_STAT_IDX]; + unsigned *m_num_ialu_acesses[NUM_STAT_IDX]; + unsigned *m_num_fp_acesses[NUM_STAT_IDX]; + unsigned *m_num_tex_inst[NUM_STAT_IDX]; + unsigned *m_num_imul_acesses[NUM_STAT_IDX]; + unsigned *m_num_imul32_acesses[NUM_STAT_IDX]; + unsigned *m_num_imul24_acesses[NUM_STAT_IDX]; + unsigned *m_num_fpmul_acesses[NUM_STAT_IDX]; + unsigned *m_num_idiv_acesses[NUM_STAT_IDX]; + unsigned *m_num_fpdiv_acesses[NUM_STAT_IDX]; + unsigned *m_num_sp_acesses[NUM_STAT_IDX]; + unsigned *m_num_sfu_acesses[NUM_STAT_IDX]; + unsigned *m_num_trans_acesses[NUM_STAT_IDX]; + unsigned *m_num_mem_acesses[NUM_STAT_IDX]; + unsigned *m_num_sp_committed[NUM_STAT_IDX]; + unsigned *m_num_sfu_committed[NUM_STAT_IDX]; + unsigned *m_num_mem_committed[NUM_STAT_IDX]; + unsigned *m_active_sp_lanes[NUM_STAT_IDX]; + unsigned *m_active_sfu_lanes[NUM_STAT_IDX]; + unsigned *m_read_regfile_acesses[NUM_STAT_IDX]; + unsigned *m_write_regfile_acesses[NUM_STAT_IDX]; + unsigned *m_non_rf_operands[NUM_STAT_IDX]; }; class power_core_stat_t : public shader_core_power_stats_pod { @@ -82,38 +88,25 @@ private: }; 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 + // [CURRENT_STAT_IDX] = CURRENT_STAT_IDX stat, [PREV_STAT_IDX] = last reading + class cache_stats core_cache_stats[NUM_STAT_IDX]; // Total core stats + class cache_stats l2_cache_stats[NUM_STAT_IDX]; // Total L2 partition stats - // 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]; + unsigned *shmem_read_access[NUM_STAT_IDX]; // Shared memory access - // 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]; + // Low level DRAM stats + unsigned *n_cmd[NUM_STAT_IDX]; + unsigned *n_activity[NUM_STAT_IDX]; + unsigned *n_nop[NUM_STAT_IDX]; + unsigned *n_act[NUM_STAT_IDX]; + unsigned *n_pre[NUM_STAT_IDX]; + unsigned *n_rd[NUM_STAT_IDX]; + unsigned *n_wr[NUM_STAT_IDX]; + unsigned *n_req[NUM_STAT_IDX]; // Interconnect stats - long *n_simt_to_mem[2]; - long *n_mem_to_simt[2]; + long *n_simt_to_mem[NUM_STAT_IDX]; + long *n_mem_to_simt[NUM_STAT_IDX]; }; @@ -145,461 +138,483 @@ public: *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; - } + 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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_decoded_insn[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_INTdecoded_insn[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_FPdecoded_insn[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_loadqueued_insn[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_storequeued_insn[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_sp_committed[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_sfu_committed[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_mem_committed[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_mem_committed[PREV_STAT_IDX][i]) + +(pwr_core_stat->m_num_sfu_committed[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_sfu_committed[PREV_STAT_IDX][i]) + +(pwr_core_stat->m_num_sp_committed[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_sp_committed[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_read_regfile_acesses[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_write_regfile_acesses[PREV_STAT_IDX][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; - } + 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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_pipeline_duty_cycle[PREV_STAT_IDX][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_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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_non_rf_operands[PREV_STAT_IDX][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_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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_sp_acesses[PREV_STAT_IDX][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_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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_sfu_acesses[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_trans_acesses[PREV_STAT_IDX][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_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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_mem_acesses[PREV_STAT_IDX][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_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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_idiv_acesses[PREV_STAT_IDX][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_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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_fpdiv_acesses[PREV_STAT_IDX][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_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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_imul32_acesses[PREV_STAT_IDX][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_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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_imul24_acesses[PREV_STAT_IDX][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_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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_imul_acesses[PREV_STAT_IDX][i])+ + (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_imul24_acesses[PREV_STAT_IDX][i])+ + (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_imul32_acesses[PREV_STAT_IDX][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; - } + 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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_fp_acesses[PREV_STAT_IDX][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_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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_active_sp_lanes[PREV_STAT_IDX][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]); } + 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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_active_sfu_lanes[PREV_STAT_IDX][i]); + } - return (total_inst/m_config->num_shader())/m_config->gpgpu_num_sfu_units; - } + 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); + 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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_fp_acesses[PREV_STAT_IDX][i])+ + (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_fpdiv_acesses[PREV_STAT_IDX][i])+ + (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_fpmul_acesses[PREV_STAT_IDX][i])+ + (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_imul24_acesses[PREV_STAT_IDX][i])+ + (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_imul_acesses[PREV_STAT_IDX][i]); + } + 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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_idiv_acesses[PREV_STAT_IDX][i])+ + (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_imul32_acesses[PREV_STAT_IDX][i])+ + (pwr_core_stat->m_num_trans_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_trans_acesses[PREV_STAT_IDX][i]); + } + return total_inst; + } - } - total_inst += get_total_load_inst()+get_total_store_inst()+get_tex_inst(); - 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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_ialu_acesses[PREV_STAT_IDX][i]); + } + 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_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[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_tex_inst[PREV_STAT_IDX][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_constant_c_accesses(){ + enum mem_access_type access_type[] = {CONST_ACC_R}; + enum cache_request_status request_status[] = {HIT, MISS, HIT_RESERVED}; + unsigned num_access_type = sizeof(access_type)/sizeof(enum mem_access_type); + unsigned num_request_status = sizeof(request_status)/sizeof(enum cache_request_status); - 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; - } + return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)); + } + unsigned get_constant_c_misses(){ + enum mem_access_type access_type[] = {CONST_ACC_R}; + enum cache_request_status request_status[] = {MISS}; + unsigned num_access_type = sizeof(access_type)/sizeof(enum mem_access_type); + unsigned num_request_status = sizeof(request_status)/sizeof(enum cache_request_status); - 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; + return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)); + } + unsigned get_constant_c_hits(){ + return (get_constant_c_accesses()-get_constant_c_misses()); + } + unsigned get_texture_c_accesses(){ + enum mem_access_type access_type[] = {TEXTURE_ACC_R}; + enum cache_request_status request_status[] = {HIT, MISS, HIT_RESERVED}; + unsigned num_access_type = sizeof(access_type)/sizeof(enum mem_access_type); + unsigned num_request_status = sizeof(request_status)/sizeof(enum cache_request_status); + + return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)); + } + unsigned get_texture_c_misses(){ + enum mem_access_type access_type[] = {TEXTURE_ACC_R}; + enum cache_request_status request_status[] = {MISS}; + unsigned num_access_type = sizeof(access_type)/sizeof(enum mem_access_type); + unsigned num_request_status = sizeof(request_status)/sizeof(enum cache_request_status); + + return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)); + } + unsigned get_texture_c_hits(){ + return ( get_texture_c_accesses()- get_texture_c_misses()); + } + unsigned get_inst_c_accesses(){ + enum mem_access_type access_type[] = {INST_ACC_R}; + enum cache_request_status request_status[] = {HIT, MISS, HIT_RESERVED}; + unsigned num_access_type = sizeof(access_type)/sizeof(enum mem_access_type); + unsigned num_request_status = sizeof(request_status)/sizeof(enum cache_request_status); + + return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)); + } + unsigned get_inst_c_misses(){ + enum mem_access_type access_type[] = {INST_ACC_R}; + enum cache_request_status request_status[] = {MISS}; + unsigned num_access_type = sizeof(access_type)/sizeof(enum mem_access_type); + unsigned num_request_status = sizeof(request_status)/sizeof(enum cache_request_status); + + return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)); + } + unsigned get_inst_c_hits(){ + return (get_inst_c_accesses()-get_inst_c_misses()); + } + + unsigned get_l1d_read_accesses(){ + enum mem_access_type access_type[] = {GLOBAL_ACC_R, LOCAL_ACC_R}; + enum cache_request_status request_status[] = {HIT, MISS, HIT_RESERVED}; + unsigned num_access_type = sizeof(access_type)/sizeof(enum mem_access_type); + unsigned num_request_status = sizeof(request_status)/sizeof(enum cache_request_status); + + return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)); + } + unsigned get_l1d_read_misses(){ + enum mem_access_type access_type[] = {GLOBAL_ACC_R, LOCAL_ACC_R}; + enum cache_request_status request_status[] = {MISS}; + unsigned num_access_type = sizeof(access_type)/sizeof(enum mem_access_type); + unsigned num_request_status = sizeof(request_status)/sizeof(enum cache_request_status); + + return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)); + } + unsigned get_l1d_read_hits(){ + return (get_l1d_read_accesses()-get_l1d_read_misses()); + } + unsigned get_l1d_write_accesses(){ + enum mem_access_type access_type[] = {GLOBAL_ACC_W, LOCAL_ACC_W}; + enum cache_request_status request_status[] = {HIT, MISS, HIT_RESERVED}; + unsigned num_access_type = sizeof(access_type)/sizeof(enum mem_access_type); + unsigned num_request_status = sizeof(request_status)/sizeof(enum cache_request_status); + + return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)); + } + unsigned get_l1d_write_misses(){ + enum mem_access_type access_type[] = {GLOBAL_ACC_W, LOCAL_ACC_W}; + enum cache_request_status request_status[] = {MISS}; + unsigned num_access_type = sizeof(access_type)/sizeof(enum mem_access_type); + unsigned num_request_status = sizeof(request_status)/sizeof(enum cache_request_status); + + return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)); + } + 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_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_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_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_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[CURRENT_STAT_IDX][i]) - (pwr_mem_stat->shmem_read_access[PREV_STAT_IDX][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_accesses(){ + enum mem_access_type access_type[] = {GLOBAL_ACC_R, LOCAL_ACC_R, CONST_ACC_R, TEXTURE_ACC_R, INST_ACC_R}; + enum cache_request_status request_status[] = {HIT, MISS, HIT_RESERVED}; + unsigned num_access_type = sizeof(access_type)/sizeof(enum mem_access_type); + unsigned num_request_status = sizeof(request_status)/sizeof(enum cache_request_status); - 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; - } + return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)) - + (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)); + } - unsigned get_l2_read_hits(){ - return (get_l2_read_accesses()-get_l2_read_misses()); - } + unsigned get_l2_read_misses(){ + enum mem_access_type access_type[] = {GLOBAL_ACC_R, LOCAL_ACC_R, CONST_ACC_R, TEXTURE_ACC_R, INST_ACC_R}; + enum cache_request_status request_status[] = {MISS}; + unsigned num_access_type = sizeof(access_type)/sizeof(enum mem_access_type); + unsigned num_request_status = sizeof(request_status)/sizeof(enum cache_request_status); - 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; - } + return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)) - + (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)); + } - 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_l2_read_hits(){ + return (get_l2_read_accesses()-get_l2_read_misses()); + } - long get_icnt_simt_to_mem(){ - long total=0; - for(unsigned i=0; i<m_config->n_simt_clusters; ++i){ - total += (pwr_mem_stat->n_simt_to_mem[0][i] - pwr_mem_stat->n_simt_to_mem[1][i]); - } - return total; - } + unsigned get_l2_write_accesses(){ + enum mem_access_type access_type[] = {GLOBAL_ACC_W, LOCAL_ACC_W, L1_WRBK_ACC}; + enum cache_request_status request_status[] = {HIT, MISS, HIT_RESERVED}; + unsigned num_access_type = sizeof(access_type)/sizeof(enum mem_access_type); + unsigned num_request_status = sizeof(request_status)/sizeof(enum cache_request_status); - long get_icnt_mem_to_simt(){ - long total=0; - for(unsigned i=0; i<m_config->n_simt_clusters; ++i){ - total += (pwr_mem_stat->n_mem_to_simt[0][i] - pwr_mem_stat->n_mem_to_simt[1][i]); - } - return total; - } + return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)) - + (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)); + } + + unsigned get_l2_write_misses(){ + enum mem_access_type access_type[] = {GLOBAL_ACC_W, LOCAL_ACC_W, L1_WRBK_ACC}; + enum cache_request_status request_status[] = {MISS}; + unsigned num_access_type = sizeof(access_type)/sizeof(enum mem_access_type); + unsigned num_request_status = sizeof(request_status)/sizeof(enum cache_request_status); + + return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)) - + (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats(access_type, num_access_type, request_status, num_request_status)); + } + 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[CURRENT_STAT_IDX][i] - pwr_mem_stat->n_cmd[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i] - pwr_mem_stat->n_activity[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i] - pwr_mem_stat->n_nop[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i] - pwr_mem_stat->n_act[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i] - pwr_mem_stat->n_pre[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i] - pwr_mem_stat->n_rd[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i] - pwr_mem_stat->n_wr[PREV_STAT_IDX][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[CURRENT_STAT_IDX][i] - pwr_mem_stat->n_req[PREV_STAT_IDX][i]); + } + return total; + } + + long get_icnt_simt_to_mem(){ + long total=0; + for(unsigned i=0; i<m_config->n_simt_clusters; ++i){ + total += (pwr_mem_stat->n_simt_to_mem[CURRENT_STAT_IDX][i] - pwr_mem_stat->n_simt_to_mem[PREV_STAT_IDX][i]); + } + return total; + } + + long get_icnt_mem_to_simt(){ + long total=0; + for(unsigned i=0; i<m_config->n_simt_clusters; ++i){ + total += (pwr_mem_stat->n_mem_to_simt[CURRENT_STAT_IDX][i] - pwr_mem_stat->n_mem_to_simt[PREV_STAT_IDX][i]); + } + return total; + } power_core_stat_t * pwr_core_stat; power_mem_stat_t * pwr_mem_stat; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index c649967..e108963 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -352,46 +352,13 @@ void shader_core_stats::print( FILE* fout ) const { 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++) { 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_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); @@ -400,18 +367,7 @@ void shader_core_stats::print( FILE* fout ) const fprintf(fout,"gpgpu_n_mem_write_global = %d\n", gpgpu_n_mem_write_global); fprintf(fout,"gpgpu_n_mem_texture = %d\n", gpgpu_n_mem_texture); fprintf(fout,"gpgpu_n_mem_const = %d\n", gpgpu_n_mem_const); -/* - unsigned a,m; - for (unsigned i=0, a=0, m=0;i<m_n_shader;i++) - m_sc[i]->L1cache_print(stdout,a,m); - printf("L1 Data Cache Total Miss Rate = %0.3f\n", (float)m/a); - for (i=0,a=0,m=0;i<m_n_shader;i++) - m_sc[i]->L1texcache_print(stdout,a,m); - printf("L1 Texture Cache Total Miss Rate = %0.3f\n", (float)m/a); - for (i=0,a=0,m=0;i<m_n_shader;i++) - m_sc[i]->L1constcache_print(stdout,a,m); - printf("L1 Const Cache Total Miss Rate = %0.3f\n", (float)m/a); -*/ + fprintf(fout, "gpgpu_n_load_insn = %d\n", gpgpu_n_load_insn); fprintf(fout, "gpgpu_n_store_insn = %d\n", gpgpu_n_store_insn); fprintf(fout, "gpgpu_n_shmem_insn = %d\n", gpgpu_n_shmem_insn); @@ -672,9 +628,6 @@ 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(); @@ -1145,38 +1098,25 @@ void ldst_unit::print_cache_stats( FILE *fp, unsigned& dl1_accesses, unsigned& d } } -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::get_cache_stats(cache_stats &cs) { + // Adds stats to 'cs' from each cache + if(m_L1D) + cs += m_L1D->get_stats(); + if(m_L1C) + cs += m_L1C->get_stats(); + if(m_L1T) + cs += m_L1T->get_stats(); + } -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::get_L1D_sub_stats(struct cache_sub_stats &css) const{ + m_L1D->get_sub_stats(css); +} +void ldst_unit::get_L1C_sub_stats(struct cache_sub_stats &css) const{ + m_L1C->get_sub_stats(css); +} +void ldst_unit::get_L1T_sub_stats(struct cache_sub_stats &css) const{ + m_L1T->get_sub_stats(css); } void shader_core_ctx::warp_inst_complete(const warp_inst_t &inst) @@ -1788,7 +1728,6 @@ void ldst_unit::cycle() done &= texture_cycle(pipe_reg, rc_fail, type); done &= memory_cycle(pipe_reg, rc_fail, type); m_mem_rc = rc_fail; - set_stats(); // Sets stats in m_stats object if (!done) { // log stall types and return assert(rc_fail != NO_RC_FAIL); @@ -1933,6 +1872,82 @@ void gpgpu_sim::shader_print_scheduler_stat( FILE* fout, bool print_dynamic_info fprintf( fout, "\n" ); } +void gpgpu_sim::shader_print_cache_stats( FILE *fout ) const{ + + // L1I + struct cache_sub_stats total_css; + struct cache_sub_stats css; + + total_css.clear(); + css.clear(); + + fprintf(fout, "\n========= Core cache stats =========\n"); + fprintf(fout, "L1I_cache:\n"); + for ( unsigned i = 0; i < m_shader_config->n_simt_clusters; ++i ) { + m_cluster[i]->get_L1I_sub_stats(css); + total_css += css; + } + fprintf(fout, "\tL1I_total_cache_accesses: %u\n", total_css.accesses); + fprintf(fout, "\tL1I_total_cache_misses: %u\n", total_css.misses); + if(total_css.accesses > 0){ + fprintf(fout, "\tL1I_total_cache_miss_rate: %.4lf\n", (double)total_css.misses / (double)total_css.accesses); + } + fprintf(fout, "\tL1I_total_cache_pending_hits: %u\n", total_css.pending_hits); + fprintf(fout, "\tL1I_total_cache_reservation_fails: %u\n", total_css.res_fails); + + // L1D + total_css.clear(); + css.clear(); + fprintf(fout, "L1D_cache:\n"); + for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++){ + m_cluster[i]->get_L1D_sub_stats(css); + + fprintf( stdout, "\tL1D_cache_core[%d]: Access = %d, Miss = %d, Miss_rate = %.3lf, Pending_hits = %u, Reservation_fails = %u\n", + i, css.accesses, css.misses, (double)css.misses / (double)css.accesses, css.pending_hits, css.res_fails); + + total_css += css; + } + fprintf(fout, "\tL1D_total_cache_accesses: %u\n", total_css.accesses); + fprintf(fout, "\tL1D_total_cache_misses: %u\n", total_css.misses); + if(total_css.accesses > 0){ + fprintf(fout, "\tL1D_total_cache_miss_rate: %.4lf\n", (double)total_css.misses / (double)total_css.accesses); + } + fprintf(fout, "\tL1D_total_cache_pending_hits: %u\n", total_css.pending_hits); + fprintf(fout, "\tL1D_total_cache_reservation_fails: %u\n", total_css.res_fails); + + + // L1C + total_css.clear(); + css.clear(); + fprintf(fout, "L1C_cache:\n"); + for ( unsigned i = 0; i < m_shader_config->n_simt_clusters; ++i ) { + m_cluster[i]->get_L1C_sub_stats(css); + total_css += css; + } + fprintf(fout, "\tL1C_total_cache_accesses: %u\n", total_css.accesses); + fprintf(fout, "\tL1C_total_cache_misses: %u\n", total_css.misses); + if(total_css.accesses > 0){ + fprintf(fout, "\tL1C_total_cache_miss_rate: %.4lf\n", (double)total_css.misses / (double)total_css.accesses); + } + fprintf(fout, "\tL1C_total_cache_pending_hits: %u\n", total_css.pending_hits); + fprintf(fout, "\tL1C_total_cache_reservation_fails: %u\n", total_css.res_fails); + + // L1T + total_css.clear(); + css.clear(); + fprintf(fout, "L1T_cache:\n"); + for ( unsigned i = 0; i < m_shader_config->n_simt_clusters; ++i ) { + m_cluster[i]->get_L1T_sub_stats(css); + total_css += css; + } + fprintf(fout, "\tL1T_total_cache_accesses: %u\n", total_css.accesses); + fprintf(fout, "\tL1T_total_cache_misses: %u\n", total_css.misses); + if(total_css.accesses > 0){ + fprintf(fout, "\tL1T_total_cache_miss_rate: %.4lf\n", (double)total_css.misses / (double)total_css.accesses); + } + fprintf(fout, "\tL1T_total_cache_pending_hits: %u\n", total_css.pending_hits); + fprintf(fout, "\tL1T_total_cache_reservation_fails: %u\n", total_css.res_fails); +} void gpgpu_sim::shader_print_l1_miss_stat( FILE *fout ) const { @@ -2591,11 +2606,26 @@ 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::get_cache_stats(cache_stats &cs){ + // Adds stats from each cache to 'cs' + cs += m_L1I->get_stats(); // Get L1I stats + m_ldst_unit->get_cache_stats(cs); // Get L1D, L1C, L1T stats } -void shader_core_ctx::set_icnt_power_stats(long &n_simt_to_mem, long &n_mem_to_simt) const{ +void shader_core_ctx::get_L1I_sub_stats(struct cache_sub_stats &css) const{ + m_L1I->get_sub_stats(css); +} +void shader_core_ctx::get_L1D_sub_stats(struct cache_sub_stats &css) const{ + m_ldst_unit->get_L1D_sub_stats(css); +} +void shader_core_ctx::get_L1C_sub_stats(struct cache_sub_stats &css) const{ + m_ldst_unit->get_L1C_sub_stats(css); +} +void shader_core_ctx::get_L1T_sub_stats(struct cache_sub_stats &css) const{ + m_ldst_unit->get_L1T_sub_stats(css); +} + +void shader_core_ctx::get_icnt_power_stats(long &n_simt_to_mem, long &n_mem_to_simt) const{ n_simt_to_mem += m_stats->n_simt_to_mem[m_sid]; n_mem_to_simt += m_stats->n_mem_to_simt[m_sid]; } @@ -3113,22 +3143,67 @@ 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(long &n_simt_to_mem, long &n_mem_to_simt) const { +void simt_core_cluster::get_icnt_stats(long &n_simt_to_mem, long &n_mem_to_simt) const { long simt_to_mem=0; long mem_to_simt=0; for ( unsigned i = 0; i < m_config->n_simt_cores_per_cluster; ++i ) { - m_core[i]->set_icnt_power_stats(simt_to_mem, mem_to_simt); + m_core[i]->get_icnt_power_stats(simt_to_mem, mem_to_simt); } n_simt_to_mem = simt_to_mem; n_mem_to_simt = mem_to_simt; } +void simt_core_cluster::get_cache_stats(cache_stats &cs) const{ + for ( unsigned i = 0; i < m_config->n_simt_cores_per_cluster; ++i ) { + m_core[i]->get_cache_stats(cs); + } +} + +void simt_core_cluster::get_L1I_sub_stats(struct cache_sub_stats &css) const{ + struct cache_sub_stats temp_css; + struct cache_sub_stats total_css; + temp_css.clear(); + total_css.clear(); + for ( unsigned i = 0; i < m_config->n_simt_cores_per_cluster; ++i ) { + m_core[i]->get_L1I_sub_stats(temp_css); + total_css += temp_css; + } + css = total_css; +} +void simt_core_cluster::get_L1D_sub_stats(struct cache_sub_stats &css) const{ + struct cache_sub_stats temp_css; + struct cache_sub_stats total_css; + temp_css.clear(); + total_css.clear(); + for ( unsigned i = 0; i < m_config->n_simt_cores_per_cluster; ++i ) { + m_core[i]->get_L1D_sub_stats(temp_css); + total_css += temp_css; + } + css = total_css; +} +void simt_core_cluster::get_L1C_sub_stats(struct cache_sub_stats &css) const{ + struct cache_sub_stats temp_css; + struct cache_sub_stats total_css; + temp_css.clear(); + total_css.clear(); + for ( unsigned i = 0; i < m_config->n_simt_cores_per_cluster; ++i ) { + m_core[i]->get_L1C_sub_stats(temp_css); + total_css += temp_css; + } + css = total_css; +} +void simt_core_cluster::get_L1T_sub_stats(struct cache_sub_stats &css) const{ + struct cache_sub_stats temp_css; + struct cache_sub_stats total_css; + temp_css.clear(); + total_css.clear(); + for ( unsigned i = 0; i < m_config->n_simt_cores_per_cluster; ++i ) { + m_core[i]->get_L1T_sub_stats(temp_css); + total_css += temp_css; + } + css = total_css; +} + 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 3979ad1..2fb27ee 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1080,7 +1080,11 @@ public: 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 get_cache_stats(cache_stats &cs); + + void get_L1D_sub_stats(struct cache_sub_stats &css) const; + void get_L1C_sub_stats(struct cache_sub_stats &css) const; + void get_L1T_sub_stats(struct cache_sub_stats &css) const; protected: ldst_unit( mem_fetch_interface *icnt, @@ -1362,19 +1366,7 @@ 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 - long *n_simt_to_mem; // Interconnect power stats long *n_mem_to_simt; }; @@ -1426,18 +1418,6 @@ public: 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)); - n_simt_to_mem = (long *)calloc(config->num_shader(), sizeof(long)); n_mem_to_simt = (long *)calloc(config->num_shader(), sizeof(long)); @@ -1584,9 +1564,14 @@ public: 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(long &n_simt_to_mem, long &n_mem_to_simt) const; + void get_cache_stats(cache_stats &cs); + void get_L1I_sub_stats(struct cache_sub_stats &css) const; + void get_L1D_sub_stats(struct cache_sub_stats &css) const; + void get_L1C_sub_stats(struct cache_sub_stats &css) const; + void get_L1T_sub_stats(struct cache_sub_stats &css) const; + + void get_icnt_power_stats(long &n_simt_to_mem, long &n_mem_to_simt) const; // debug: void display_simt_state(FILE *fout, int mask ) const; @@ -1828,9 +1813,14 @@ public: 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(long &n_simt_to_mem, long &n_mem_to_simt) const; + void get_cache_stats(cache_stats &cs) const; + void get_L1I_sub_stats(struct cache_sub_stats &css) const; + void get_L1D_sub_stats(struct cache_sub_stats &css) const; + void get_L1C_sub_stats(struct cache_sub_stats &css) const; + void get_L1T_sub_stats(struct cache_sub_stats &css) const; + + void get_icnt_stats(long &n_simt_to_mem, long &n_mem_to_simt) const; private: unsigned m_cluster_id; |
