diff options
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.cc | 15 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.h | 8 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 10 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.h | 19 | ||||
| -rw-r--r-- | src/gpgpu-sim/histogram.cc | 162 | ||||
| -rw-r--r-- | src/gpgpu-sim/histogram.h | 41 | ||||
| -rw-r--r-- | src/gpgpu-sim/l2cache.cc | 3 | ||||
| -rw-r--r-- | src/gpgpu-sim/stat-tool.cc | 922 | ||||
| -rw-r--r-- | src/gpgpu-sim/stat-tool.h | 251 | ||||
| -rw-r--r-- | src/gpgpu-sim/visualizer.cc | 2 |
10 files changed, 767 insertions, 666 deletions
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index faa817f..c1acc83 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -81,7 +81,7 @@ cache_t::cache_t( const char *name, const char *opt, enum cache_write_policy wp, int core_id, - int type_id) + int type_id ) { unsigned int nset; unsigned int line_sz; @@ -120,19 +120,18 @@ cache_t::cache_t( const char *name, enum cache_request_status cache_t::access( new_addr_type addr, bool write, unsigned int cycle, address_type *wb_address ) { + m_access++; + unsigned set_index = (addr >> m_line_sz_log2) & ( (1<<m_nset_log2) - 1 ); + new_addr_type tag = addr >> (m_line_sz_log2 + m_nset_log2); + bool all_reserved = true; cache_block_t *pending_line = NULL; cache_block_t *clean_line = NULL; - new_addr_type bank_addr = addr; // offset within bank - unsigned set = (bank_addr >> m_line_sz_log2) & ( (1<<m_nset_log2) - 1 ); - unsigned long long tag = bank_addr >> (m_line_sz_log2 + m_nset_log2); - - m_access++; shader_cache_access_log(m_core_id, m_type_id, 0); for (unsigned way=0; way<m_assoc; way++) { - cache_block_t *line = &(m_lines[set*m_assoc+way] ); + cache_block_t *line = &(m_lines[set_index*m_assoc+way] ); if (line->tag == tag) { if (line->status & RESERVED) { pending_line = line; @@ -185,7 +184,7 @@ enum cache_request_status cache_t::access( new_addr_type addr, bool write, unsig cache_block_t *wb_line = NULL; for (unsigned way=0; way<m_assoc; way++) { - cache_block_t *line = &(m_lines[set*m_assoc+way] ); + cache_block_t *line = &(m_lines[set_index*m_assoc+way] ); if (line->status & VALID && !(line->status & RESERVED)) { if (!wb_line) { wb_line = line; diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index ff071e0..21cdbbc 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -106,9 +106,9 @@ struct cache_block_t { #define RANDOM 'R' enum cache_write_policy { - no_writes, //line replacement when new line arrives - write_back, //line replacement when new line arrives - write_through //reservation based, use much handle reservation full error. + no_writes, // line replacement when new line arrives + write_back, // line replacement when new line arrives + write_through // reservation based, use much handle reservation full error. }; class cache_t { @@ -159,8 +159,6 @@ private: int m_core_id; // which shader core is using this int m_type_id; // what kind of cache is this (normal, texture, constant) - - class linear_histogram_logger *m_logger; }; #endif diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 06a4c15..dc4241b 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -109,9 +109,6 @@ bool g_interactive_debugger_enabled=false; unsigned long long gpu_sim_cycle = 0; unsigned long long gpu_tot_sim_cycle = 0; -unsigned int gpgpu_n_sent_writes = 0; -unsigned int gpgpu_n_processed_writes = 0; - // performance counter for stalls due to congestion. unsigned int gpu_stall_wr_back = 0; unsigned int gpu_stall_dramfull = 0; @@ -126,7 +123,6 @@ int gpu_runtime_stat_flag = 0; unsigned long long gpu_max_cycle = 0; unsigned long long gpu_max_insn = 0; -unsigned g_next_mf_request_uid = 1; int g_total_cta_left; // GPGPU-Sim timing model options @@ -560,7 +556,6 @@ unsigned int gpgpu_sim::run_gpu_sim() not_completed = 1; mem_busy = 1; icnt2mem_busy = 1; - g_next_mf_request_uid = 1; more_thread = 1; gpu_sim_insn = 0; m_shader_stats->gpu_sim_insn_no_ld_const = 0; @@ -705,8 +700,6 @@ void gpgpu_sim::gpu_print_stat() const printf("gpu_tot_ipc = %12.4f\n", (float)gpu_tot_sim_insn / gpu_tot_sim_cycle); printf("gpu_tot_completed_thread = %lld\n", gpu_tot_completed_thread); printf("gpu_tot_issued_cta = %lld\n", gpu_tot_issued_cta); - printf("gpgpu_n_sent_writes = %d\n", gpgpu_n_sent_writes); - printf("gpgpu_n_processed_writes = %d\n", gpgpu_n_processed_writes); // performance counter for stalls due to congestion. printf("gpu_stall_by_MSHRwb= %d\n", m_shader_stats->gpu_stall_by_MSHRwb); @@ -1095,9 +1088,6 @@ void gpgpu_sim::cycle() if ( ::icnt_has_buffer( m_shader_config->mem2device(i), response_size ) ) { if (!mf->get_is_write()) mf->set_return_timestamp(gpu_sim_cycle+gpu_tot_sim_cycle); - else { - gpgpu_n_processed_writes++; - } ::icnt_push( m_shader_config->mem2device(i), mf->get_tpc(), mf, response_size ); m_memory_partition_unit[i]->pop(); } else { diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 0ba1bb8..762cea2 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -153,18 +153,16 @@ struct memory_config { // global config extern int gpgpu_mem_address_mask; - extern int gpu_runtime_stat_flag; extern int gpgpu_cflog_interval; - extern bool g_interactive_debugger_enabled; - extern int g_ptx_inst_debug_to_file; extern char* g_ptx_inst_debug_file; extern int g_ptx_inst_debug_thread_uid; - - +// global counters +extern unsigned long long gpu_sim_cycle; +extern unsigned long long gpu_tot_sim_cycle; class gpgpu_sim : public gpgpu_t { public: @@ -279,15 +277,4 @@ public: unsigned gpu_sim_insn_last_update_sid; }; -// global counters - -extern unsigned long long gpu_sim_cycle; -extern unsigned long long gpu_tot_sim_cycle; -extern unsigned g_next_mf_request_uid; - -// stats - -extern unsigned int gpgpu_n_sent_writes; -extern unsigned int gpgpu_n_processed_writes; - #endif diff --git a/src/gpgpu-sim/histogram.cc b/src/gpgpu-sim/histogram.cc new file mode 100644 index 0000000..d6f6283 --- /dev/null +++ b/src/gpgpu-sim/histogram.cc @@ -0,0 +1,162 @@ +/* + * histogram.cc + * + * Copyright (c) 2009 by Tor M. Aamodt, Wilson W. L. Fung and the + * University of British Columbia + * Vancouver, BC V6T 1Z4 + * All Rights Reserved. + * + * THIS IS A LEGAL DOCUMENT BY DOWNLOADING GPGPU-SIM, YOU ARE AGREEING TO THESE + * TERMS AND CONDITIONS. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * NOTE: The files libcuda/cuda_runtime_api.c and src/cuda-sim/cuda-math.h + * are derived from the CUDA Toolset available from http://www.nvidia.com/cuda + * (property of NVIDIA). The files benchmarks/BlackScholes/ and + * benchmarks/template/ are derived from the CUDA SDK available from + * http://www.nvidia.com/cuda (also property of NVIDIA). The files from + * src/intersim/ are derived from Booksim (a simulator provided with the + * textbook "Principles and Practices of Interconnection Networks" available + * from http://cva.stanford.edu/books/ppin/). As such, those files are bound by + * the corresponding legal terms and conditions set forth separately (original + * copyright notices are left in files from these sources and where we have + * modified a file our copyright notice appears before the original copyright + * notice). + * + * Using this version of GPGPU-Sim requires a complete installation of CUDA + * which is distributed seperately by NVIDIA under separate terms and + * conditions. To use this version of GPGPU-Sim with OpenCL requires a + * recent version of NVIDIA's drivers which support OpenCL. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the University of British Columbia nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * 4. This version of GPGPU-SIM is distributed freely for non-commercial use only. + * + * 5. No nonprofit user may place any restrictions on the use of this software, + * including as modified by the user, by any other authorized user. + * + * 6. GPGPU-SIM was developed primarily by Tor M. Aamodt, Wilson W. L. Fung, + * Ali Bakhoda, George L. Yuan, at the University of British Columbia, + * Vancouver, BC V6T 1Z4 + */ + +#include "histogram.h" + +#include <assert.h> + +binned_histogram::binned_histogram (std::string name, int nbins, int* bins) + : m_name(name), m_nbins(nbins), m_bins(NULL), m_bin_cnts(new int[m_nbins]), m_maximum(0), m_sum(0) +{ + if (bins) { + m_bins = new int[m_nbins]; + for (int i = 0; i < nbins; i++) { + m_bins[i] = bins[i]; + } + } + + reset_bins(); +} + +binned_histogram::binned_histogram (const binned_histogram& other) + : m_name(other.m_name), m_nbins(other.m_nbins), m_bins(NULL), + m_bin_cnts(new int[m_nbins]), m_maximum(0), m_sum(0) +{ + for (int i = 0; i < m_nbins; i++) { + m_bin_cnts[i] = other.m_bin_cnts[i]; + } +} + +void binned_histogram::reset_bins () { + for (int i = 0; i < m_nbins; i++) { + m_bin_cnts[i] = 0; + } +} + +void binned_histogram::add2bin (int sample) { + assert(0); + m_maximum = (sample > m_maximum)? sample : m_maximum; +} + +void binned_histogram::fprint (FILE *fout) const +{ + if (m_name.c_str() != NULL) fprintf(fout, "%s = ", m_name.c_str()); + int total_sample = 0; + for (int i = 0; i < m_nbins; i++) { + fprintf(fout, "%d ", m_bin_cnts[i]); + total_sample += m_bin_cnts[i]; + } + fprintf(fout, "max=%d ", m_maximum); + float avg = 0.0f; + if (total_sample > 0) { + avg = (float)m_sum / total_sample; + } + fprintf(fout, "avg=%0.2f ", avg); +} + +binned_histogram::~binned_histogram () { + if (m_bins) delete[] m_bins; + delete[] m_bin_cnts; +} + +pow2_histogram::pow2_histogram (std::string name, int nbins, int* bins) + : binned_histogram (name, nbins, bins) {} + +void pow2_histogram::add2bin (int sample) { + assert(sample >= 0); + + int bin; + int v = sample; + register unsigned int shift; + + bin = (v > 0xFFFF) << 4; v >>= bin; + shift = (v > 0xFF ) << 3; v >>= shift; bin |= shift; + shift = (v > 0xF ) << 2; v >>= shift; bin |= shift; + shift = (v > 0x3 ) << 1; v >>= shift; bin |= shift; + bin |= (v >> 1); + bin += (sample > 0)? 1:0; + + m_bin_cnts[bin] += 1; + + m_maximum = (sample > m_maximum)? sample : m_maximum; + m_sum += sample; +} + +linear_histogram::linear_histogram (int stride, const char *name, int nbins, int* bins) + : binned_histogram (name, nbins, bins), m_stride(stride) +{ +} + +void linear_histogram::add2bin (int sample) { + assert(sample >= 0); + + int bin = sample / m_stride; + if (bin >= m_nbins) bin = m_nbins - 1; + + m_bin_cnts[bin] += 1; + + m_maximum = (sample > m_maximum)? sample : m_maximum; + m_sum += sample; +} diff --git a/src/gpgpu-sim/histogram.h b/src/gpgpu-sim/histogram.h index 5470050..e3d8f57 100644 --- a/src/gpgpu-sim/histogram.h +++ b/src/gpgpu-sim/histogram.h @@ -71,57 +71,44 @@ #include <string> class binned_histogram { -protected: - - std::string m_name; - int m_nbins; - int *m_bins; // bin boundaries - int *m_bin_cnts; // counters - int m_maximum; // the maximum sample - signed long long int m_sum; // for calculating the average - public: - + // creators binned_histogram (std::string name = "", int nbins = 32, int* bins = NULL); - binned_histogram (const binned_histogram& other); + virtual ~binned_histogram (); + // modifiers: void reset_bins (); - void add2bin (int sample); - void fprint (FILE *fout); - - virtual ~binned_histogram (); + // accessors: + void fprint (FILE *fout) const; +protected: + std::string m_name; + int m_nbins; + int *m_bins; // bin boundaries + int *m_bin_cnts; // counters + int m_maximum; // the maximum sample + signed long long int m_sum; // for calculating the average }; class pow2_histogram : public binned_histogram { - public: - pow2_histogram ( std::string name = "", int nbins = 32, int* bins = NULL); - ~pow2_histogram() {} void add2bin (int sample); - }; class linear_histogram : public binned_histogram { - -private: - - int m_stride; - public: - linear_histogram (int stride = 1, const char *name = NULL, int nbins = 32, int* bins = NULL); - ~linear_histogram() {} void add2bin (int sample); - +private: + int m_stride; }; #endif diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index 47ead65..4c77da4 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -402,7 +402,6 @@ void memory_partition_unit::L2c_service_mem_req() mf->set_status(IN_L2TOCBQUEUE_HIT,MR_DRAM_OUTQ,gpu_sim_cycle+gpu_tot_sim_cycle); } else { m_stats->L2_write_hit++; - gpgpu_n_processed_writes++; } } else { // L2 Cache Miss @@ -492,7 +491,6 @@ void memory_partition_unit::process_dram_output() m_missTracker->miss_serviced(mf); mf->set_type(REPLY_DATA); L2tocbqueue->push(mf,gpu_sim_cycle); - gpgpu_n_processed_writes++; L2dramout = NULL; wb_addr = -1; } @@ -521,7 +519,6 @@ bool memory_partition_unit::L2c_write_back( unsigned long long int addr, int bsi L2_WTBK_DATA, m_config ); L2todram_wbqueue->push(mf,gpu_sim_cycle); - gpgpu_n_sent_writes++; return true; } diff --git a/src/gpgpu-sim/stat-tool.cc b/src/gpgpu-sim/stat-tool.cc index af43b72..744a39d 100644 --- a/src/gpgpu-sim/stat-tool.cc +++ b/src/gpgpu-sim/stat-tool.cc @@ -69,153 +69,13 @@ #include <assert.h> #include <zlib.h> #include <string> - -// detect gcc 4.3 and use unordered map (part of c++0x) -// unordered map doesn't play nice with _GLIBCXX_DEBUG, just use a map if its enabled. -#if defined( __GNUC__ ) and not defined( _GLIBCXX_DEBUG ) -#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 - #include <unordered_map> - #define my_hash_map std::unordered_map -#else - #include <ext/hash_map> - namespace std { - using namespace __gnu_cxx; - } - #define my_hash_map std::hash_map -#endif -#else - #include <map> - #define my_hash_map std::map - #define USE_MAP -#endif - -#include "histogram.h" -#include "../abstract_hardware_model.h" - -binned_histogram::binned_histogram (std::string name, int nbins, int* bins) - : m_name(name), m_nbins(nbins), m_bins(NULL), m_bin_cnts(new int[m_nbins]), m_maximum(0), m_sum(0) -{ - if (bins) { - m_bins = new int[m_nbins]; - for (int i = 0; i < nbins; i++) { - m_bins[i] = bins[i]; - } - } - - reset_bins(); -} - -binned_histogram::binned_histogram (const binned_histogram& other) - : m_name(other.m_name), m_nbins(other.m_nbins), m_bins(NULL), - m_bin_cnts(new int[m_nbins]), m_maximum(0), m_sum(0) -{ - for (int i = 0; i < m_nbins; i++) { - m_bin_cnts[i] = other.m_bin_cnts[i]; - } -} - -void binned_histogram::reset_bins () { - for (int i = 0; i < m_nbins; i++) { - m_bin_cnts[i] = 0; - } -} - -void binned_histogram::add2bin (int sample) { - assert(0); - m_maximum = (sample > m_maximum)? sample : m_maximum; -} - -void binned_histogram::fprint (FILE *fout) { - if (m_name.c_str() != NULL) fprintf(fout, "%s = ", m_name.c_str()); - int total_sample = 0; - for (int i = 0; i < m_nbins; i++) { - fprintf(fout, "%d ", m_bin_cnts[i]); - total_sample += m_bin_cnts[i]; - } - fprintf(fout, "max=%d ", m_maximum); - float avg = 0.0f; - if (total_sample > 0) { - avg = (float)m_sum / total_sample; - } - fprintf(fout, "avg=%0.2f ", avg); -} - -binned_histogram::~binned_histogram () { - if (m_bins) delete[] m_bins; - delete[] m_bin_cnts; -} - -pow2_histogram::pow2_histogram (std::string name, int nbins, int* bins) - : binned_histogram (name, nbins, bins) {} - -void pow2_histogram::add2bin (int sample) { - assert(sample >= 0); - - int bin; - int v = sample; - register unsigned int shift; - - bin = (v > 0xFFFF) << 4; v >>= bin; - shift = (v > 0xFF ) << 3; v >>= shift; bin |= shift; - shift = (v > 0xF ) << 2; v >>= shift; bin |= shift; - shift = (v > 0x3 ) << 1; v >>= shift; bin |= shift; - bin |= (v >> 1); - bin += (sample > 0)? 1:0; - - m_bin_cnts[bin] += 1; - - m_maximum = (sample > m_maximum)? sample : m_maximum; - m_sum += sample; -} - -linear_histogram::linear_histogram (int stride, const char *name, int nbins, int* bins) - : binned_histogram (name, nbins, bins), m_stride(stride) -{ -} - -void linear_histogram::add2bin (int sample) { - assert(sample >= 0); - - int bin = sample / m_stride; - if (bin >= m_nbins) bin = m_nbins - 1; - - m_bin_cnts[bin] += 1; - - m_maximum = (sample > m_maximum)? sample : m_maximum; - m_sum += sample; -} - - #include <list> #include <vector> #include <map> #include <algorithm> #include <string> -///////////////////////////////////////////////////////////////////////////////////// -// logger snapshot trigger: -// - automate the snap_shot part of loggers to avoid modifying simulation loop everytime -// a new time-dependent stat is added -///////////////////////////////////////////////////////////////////////////////////// - -class snap_shot_trigger { -protected: - unsigned long long m_snap_shot_interval; - -public: - snap_shot_trigger(unsigned long long interval) : m_snap_shot_interval(interval) {} - virtual ~snap_shot_trigger() {} - - const unsigned long long & get_interval() const { return m_snap_shot_interval;} - - void try_snap_shot(unsigned long long current_cycle) { - if ((current_cycle % m_snap_shot_interval == 0) && current_cycle != 0) { - snap_shot(current_cycle); - } - } - - virtual void snap_shot(unsigned long long current_cycle) = 0; -}; +//////////////////////////////////////////////////////////////////////////////// static unsigned long long min_snap_shot_interval = 0; static unsigned long long next_snap_shot_cycle = 0; @@ -248,19 +108,8 @@ void try_snap_shot (unsigned long long current_cycle) next_snap_shot_cycle = current_cycle + min_snap_shot_interval; // WF: stateful testing, maybe bad } -///////////////////////////////////////////////////////////////////////////////////// -// spill log interface: -// - unified interface to spill log to file to avoid infinite memory usage for logging -///////////////////////////////////////////////////////////////////////////////////// - -class spill_log_interface { - public: - spill_log_interface() {} - virtual ~spill_log_interface() {} - - virtual void spill(FILE *fout, bool final) = 0; -}; - +//////////////////////////////////////////////////////////////////////////////// + static unsigned long long spill_interval = 0; static unsigned long long next_spill_cycle = 0; static std::list<spill_log_interface*> list_spill_log; @@ -296,219 +145,9 @@ void spill_log_to_file (FILE *fout, int final, unsigned long long current_cycle next_spill_cycle = current_cycle + spill_interval; // WF: stateful testing, maybe bad } -///////////////////////////////////////////////////////////////////////////////////// -// thread control-flow locality logger -///////////////////////////////////////////////////////////////////////////////////// -unsigned translate_pc_to_ptxlineno(unsigned pc); -class thread_insn_span { -private: - - typedef my_hash_map<address_type, int> span_count_map; - unsigned long long m_cycle; - int m_n_insn; - span_count_map m_insn_span_count; - -public: - - thread_insn_span(unsigned long long cycle, int n_insn) - : m_cycle(cycle), m_n_insn(n_insn), -#ifdef USE_MAP - m_insn_span_count() -#else - m_insn_span_count(n_insn * 2) -#endif - { } - - ~thread_insn_span() { } - - thread_insn_span(const thread_insn_span& other) - : m_cycle(other.m_cycle), m_n_insn(other.m_n_insn), - m_insn_span_count(other.m_insn_span_count) - { } - - thread_insn_span& operator=(const thread_insn_span& other) - { - printf("thread_insn_span& operator=\n"); - if (this != &other && m_n_insn != other.m_n_insn) { - m_n_insn = other.m_n_insn; - m_insn_span_count = other.m_insn_span_count; - m_cycle = other.m_cycle; - } - return *this; - } - - thread_insn_span& operator+=(const thread_insn_span& other) - { - assert(m_n_insn == other.m_n_insn); // no way to aggregate if they are different programs - span_count_map::const_iterator i_sc = other.m_insn_span_count.begin(); - for (; i_sc != other.m_insn_span_count.end(); ++i_sc) { - m_insn_span_count[i_sc->first] += i_sc->second; - } - return *this; - } - - void set_span( address_type pc ) { - if( ((int)pc) >= 0 ) - m_insn_span_count[pc] += 1; - } - - void reset(unsigned long long cycle) { - m_cycle = cycle; - m_insn_span_count.clear(); - } - - void print_span(FILE *fout) { - fprintf(fout, "%d: ", (int)m_cycle); - span_count_map::const_iterator i_sc = m_insn_span_count.begin(); - for (; i_sc != m_insn_span_count.end(); ++i_sc) { - fprintf(fout, "%d ", i_sc->first); - } - fprintf(fout, "\n"); - } - - void print_histo(FILE *fout) { - fprintf(fout, "%d:", (int)m_cycle); - span_count_map::const_iterator i_sc = m_insn_span_count.begin(); - for (; i_sc != m_insn_span_count.end(); ++i_sc) { - fprintf(fout, "%d ", i_sc->second); - } - fprintf(fout, "\n"); - } - - void print_sparse_histo(FILE *fout) { - int n_printed_entries = 0; - span_count_map::const_iterator i_sc = m_insn_span_count.begin(); - for (; i_sc != m_insn_span_count.end(); ++i_sc) { - unsigned ptx_lineno = translate_pc_to_ptxlineno(i_sc->first); - fprintf(fout, "%u %d ", ptx_lineno, i_sc->second); - n_printed_entries++; - } - if (n_printed_entries == 0) { - fprintf(fout, "0 0 "); - } - fprintf(fout, "\n"); - } - - void print_sparse_histo(gzFile fout) { - int n_printed_entries = 0; - span_count_map::const_iterator i_sc = m_insn_span_count.begin(); - for (; i_sc != m_insn_span_count.end(); ++i_sc) { - unsigned ptx_lineno = translate_pc_to_ptxlineno(i_sc->first); - gzprintf(fout, "%u %d ", ptx_lineno, i_sc->second); - n_printed_entries++; - } - if (n_printed_entries == 0) { - gzprintf(fout, "0 0 "); - } - gzprintf(fout, "\n"); - } -}; - -class thread_CFlocality : public snap_shot_trigger, public spill_log_interface { -private: - - std::string m_name; - - int m_nthreads; - std::vector<address_type> m_thread_pc; - - unsigned long long m_cycle; - thread_insn_span m_thd_span; - std::list<thread_insn_span> m_thd_span_archive; - -public: - - thread_CFlocality(std::string name, unsigned long long snap_shot_interval, - int nthreads, int n_insn, address_type start_pc, unsigned long long start_cycle = 0) - : snap_shot_trigger(snap_shot_interval), m_name(name), - m_nthreads(nthreads), m_thread_pc(nthreads, start_pc), m_cycle(start_cycle), - m_thd_span(start_cycle, n_insn) - { - std::fill(m_thread_pc.begin(), m_thread_pc.end(), -1); // so that hw thread with no work assigned will not clobber results - } - - ~thread_CFlocality() {} - - void update_thread_pc( int thread_id, address_type pc ) { - m_thread_pc[thread_id] = pc; - m_thd_span.set_span(pc); - } - - void snap_shot(unsigned long long current_cycle) { - m_thd_span_archive.push_back(m_thd_span); - m_thd_span.reset(current_cycle); - for (int i = 0; i < (int)m_thread_pc.size(); i++) { - m_thd_span.set_span(m_thread_pc[i]); - } - } - - void spill(FILE *fout, bool final) { - std::list<thread_insn_span>::iterator lit = m_thd_span_archive.begin(); - for (; lit != m_thd_span_archive.end(); lit = m_thd_span_archive.erase(lit) ) { - fprintf(fout, "%s-", m_name.c_str()); - lit->print_histo(fout); - } - assert( m_thd_span_archive.empty() ); - if (final) { - fprintf(fout, "%s-", m_name.c_str()); - m_thd_span.print_histo(fout); - } - } - - void print_visualizer(FILE *fout) { - fprintf(fout, "%s: ", m_name.c_str()); - if (m_thd_span_archive.empty()) { - - // visualizer do no require snap_shots - m_thd_span.print_sparse_histo(fout); - - // clean the thread span - m_thd_span.reset(0); - for (int i = 0; i < (int)m_thread_pc.size(); i++) { - m_thd_span.set_span(m_thread_pc[i]); - } - } else { - assert(0); // TODO: implement fall back so that visualizer can work with snap shots - } - } - - void print_visualizer(gzFile fout) { - gzprintf(fout, "%s: ", m_name.c_str()); - if (m_thd_span_archive.empty()) { - - // visualizer do no require snap_shots - m_thd_span.print_sparse_histo(fout); - - // clean the thread span - m_thd_span.reset(0); - for (int i = 0; i < (int)m_thread_pc.size(); i++) { - m_thd_span.set_span(m_thread_pc[i]); - } - } else { - assert(0); // TODO: implement fall back so that visualizer can work with snap shots - } - } - - void print_span(FILE *fout) { - std::list<thread_insn_span>::iterator lit = m_thd_span_archive.begin(); - for (; lit != m_thd_span_archive.end(); ++lit) { - fprintf(fout, "%s-", m_name.c_str()); - lit->print_span(fout); - } - fprintf(fout, "%s-", m_name.c_str()); - m_thd_span.print_span(fout); - } +//////////////////////////////////////////////////////////////////////////////// - void print_histo(FILE *fout) { - std::list<thread_insn_span>::iterator lit = m_thd_span_archive.begin(); - for (; lit != m_thd_span_archive.end(); ++lit) { - fprintf(fout, "%s-", m_name.c_str()); - lit->print_histo(fout); - } - fprintf(fout, "%s-", m_name.c_str()); - m_thd_span.print_histo(fout); - } -}; +unsigned translate_pc_to_ptxlineno(unsigned pc); static int n_thread_CFloggers = 0; static thread_CFlocality** thread_CFlogger = NULL; @@ -577,52 +216,8 @@ void cflog_visualizer_gzprint(gzFile fout) } } -///////////////////////////////////////////////////////////////////////////////////// -// per-insn active thread distribution (warp occ) logger -///////////////////////////////////////////////////////////////////////////////////// - -class insn_warp_occ_logger{ -private: - int m_simd_width; - std::vector<linear_histogram> m_insn_warp_occ; - int m_id; - static int s_ids; - -public: - insn_warp_occ_logger(int simd_width, int n_insn) - : m_simd_width(simd_width), - m_insn_warp_occ(n_insn, linear_histogram(1, "", m_simd_width)), - m_id(s_ids++) {} - - insn_warp_occ_logger(const insn_warp_occ_logger& other) - : m_simd_width(other.m_simd_width), - m_insn_warp_occ(other.m_insn_warp_occ.size(), linear_histogram(1, "", m_simd_width)), - m_id(s_ids++) {} - - insn_warp_occ_logger& operator=(const insn_warp_occ_logger& p) { - printf("insn_warp_occ_logger Operator= called: %02d \n", m_id); - assert(0); - return *this; - } +//////////////////////////////////////////////////////////////////////////////// - ~insn_warp_occ_logger() {} - - void set_id(int id) { - m_id = id; - } - - void log(address_type pc, int warp_occ) { - m_insn_warp_occ[pc].add2bin(warp_occ - 1); - } - - void print(FILE *fout) { - for (unsigned i = 0; i < m_insn_warp_occ.size(); i++) { - fprintf(fout, "InsnWarpOcc%02d-%d", m_id, i); - m_insn_warp_occ[i].fprint(fout); - fprintf(fout, "\n"); - } - } -}; int insn_warp_occ_logger::s_ids = 0; static std::vector<insn_warp_occ_logger> iwo_logger; @@ -649,188 +244,8 @@ void insn_warp_occ_print( FILE *fout ) } } -///////////////////////////////////////////////////////////////////////////////////// -// generic linear histogram logger -///////////////////////////////////////////////////////////////////////////////////// - -class linear_histogram_snapshot { -private: - unsigned long long m_cycle; - std::vector<int> m_linear_histogram; -public: - linear_histogram_snapshot(int n_bins, unsigned long long cycle) - : m_cycle(cycle), - m_linear_histogram(n_bins,0) - { } - - linear_histogram_snapshot(const linear_histogram_snapshot& other) - : m_cycle(other.m_cycle), - m_linear_histogram(other.m_linear_histogram) - { } - - ~linear_histogram_snapshot() { } - - void addsample(int pos) { - assert((size_t)pos < m_linear_histogram.size()); - m_linear_histogram[pos] += 1; - } - - void subsample(int pos) { - assert((size_t)pos < m_linear_histogram.size()); - m_linear_histogram[pos] -= 1; - } - - void reset(unsigned long long cycle) { - m_cycle = cycle; - m_linear_histogram.assign(m_linear_histogram.size(), 0); - } - - void set_cycle(unsigned long long cycle) { - m_cycle = cycle; - } - - void print(FILE *fout) { - fprintf(fout, "%d = ", (int)m_cycle); - for (unsigned int i = 0; i < m_linear_histogram.size(); i++) { - fprintf(fout, "%d ", m_linear_histogram[i]); - } - } - - void print_visualizer(FILE *fout) { - for (unsigned int i = 0; i < m_linear_histogram.size(); i++) { - fprintf(fout, "%d ", m_linear_histogram[i]); - } - } - - void print_visualizer(gzFile fout) { - for (unsigned int i = 0; i < m_linear_histogram.size(); i++) { - gzprintf(fout, "%d ", m_linear_histogram[i]); - } - } -}; +//////////////////////////////////////////////////////////////////////////////// -class linear_histogram_logger : public snap_shot_trigger, public spill_log_interface { -private: - int m_n_bins; - linear_histogram_snapshot m_curr_lin_hist; - std::list<linear_histogram_snapshot> m_lin_hist_archive; - unsigned long long m_cycle; - bool m_reset_at_snap_shot; - std::string m_name; - int m_id; - static int s_ids; - -public: - linear_histogram_logger(int n_bins, - unsigned long long snap_shot_interval, - const char *name, - bool reset_at_snap_shot = true, - unsigned long long start_cycle = 0) - : snap_shot_trigger(snap_shot_interval), - m_n_bins(n_bins), - m_curr_lin_hist(m_n_bins, start_cycle), - m_lin_hist_archive(), - m_cycle(start_cycle), - m_reset_at_snap_shot(reset_at_snap_shot), - m_name(name), - m_id(s_ids++) {} - - linear_histogram_logger(const linear_histogram_logger& other) // WF: Buggy - Not really copying data over - : snap_shot_trigger(other.get_interval()), - m_n_bins(other.m_n_bins), - m_curr_lin_hist(m_n_bins, other.m_cycle), - m_lin_hist_archive(), - m_cycle(other.m_cycle), - m_reset_at_snap_shot(other.m_reset_at_snap_shot), - m_name(other.m_name), - m_id(s_ids++) {} - - // using default assignment operator! - - ~linear_histogram_logger() { - // printf("Destroyer called: %s%02d \n", m_name.c_str(), m_id); - remove_snap_shot_trigger(this); - remove_spill_log(this); - } - - void set_id(int id) { - m_id = id; - } - - void log(int pos) { - m_curr_lin_hist.addsample(pos); - } - - void unlog(int pos) { - m_curr_lin_hist.subsample(pos); - } - - void snap_shot(unsigned long long current_cycle) { - m_lin_hist_archive.push_back(m_curr_lin_hist); - if (m_reset_at_snap_shot) { - m_curr_lin_hist.reset(current_cycle); - } else { - m_curr_lin_hist.set_cycle(current_cycle); - } - } - - void spill(FILE *fout, bool final) { - std::list<linear_histogram_snapshot>::iterator iter = m_lin_hist_archive.begin(); - for (; iter != m_lin_hist_archive.end(); iter = m_lin_hist_archive.erase(iter) ) { - fprintf(fout, "%s%02d-", m_name.c_str(), (m_id >= 0)? m_id : 0); - iter->print(fout); - fprintf(fout, "\n"); - } - assert( m_lin_hist_archive.empty() ); - if (final) { - fprintf(fout, "%s%02d-", m_name.c_str(), (m_id >= 0)? m_id : 0); - m_curr_lin_hist.print(fout); - fprintf(fout, "\n"); - } - } - - void print(FILE *fout) { - std::list<linear_histogram_snapshot>::iterator iter = m_lin_hist_archive.begin(); - for (; iter != m_lin_hist_archive.end(); ++iter) { - fprintf(fout, "%s%02d-", m_name.c_str(), m_id); - iter->print(fout); - fprintf(fout, "\n"); - } - fprintf(fout, "%s%02d-", m_name.c_str(), m_id); - m_curr_lin_hist.print(fout); - fprintf(fout, "\n"); - } - - void print_visualizer(FILE *fout) { - assert(m_lin_hist_archive.empty()); // don't support snapshot for now - fprintf(fout, "%s", m_name.c_str()); - if (m_id >= 0) { - fprintf(fout, "%02d: ", m_id); - } else { - fprintf(fout, ": "); - } - m_curr_lin_hist.print_visualizer(fout); - fprintf(fout, "\n"); - if (m_reset_at_snap_shot) { - m_curr_lin_hist.reset(0); - } - } - - void print_visualizer(gzFile fout) { - assert(m_lin_hist_archive.empty()); // don't support snapshot for now - gzprintf(fout, "%s", m_name.c_str()); - if (m_id >= 0) { - gzprintf(fout, "%02d: ", m_id); - } else { - gzprintf(fout, ": "); - } - m_curr_lin_hist.print_visualizer(fout); - gzprintf(fout, "\n"); - if (m_reset_at_snap_shot) { - m_curr_lin_hist.reset(0); - } - } -}; int linear_histogram_logger::s_ids = 0; ///////////////////////////////////////////////////////////////////////////////////// @@ -1049,9 +464,9 @@ void shader_CTA_count_create( int n_shaders, unsigned long long logging_interva s_CTA_count_logger->set_id(-1); if (logging_interval != 0) { - add_snap_shot_trigger(s_CTA_count_logger); - add_spill_log(s_CTA_count_logger); -} + add_snap_shot_trigger(s_CTA_count_logger); + add_spill_log(s_CTA_count_logger); + } } void shader_CTA_count_log( int shader_id, int nCTAadded ) @@ -1090,3 +505,320 @@ void shader_CTA_count_visualizer_gzprint( gzFile fout ) s_CTA_count_logger->print_visualizer(fout); } + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +thread_insn_span::thread_insn_span(unsigned long long cycle, int n_insn) + : m_cycle(cycle), m_n_insn(n_insn), +#ifdef USE_MAP + m_insn_span_count() +#else + m_insn_span_count(n_insn * 2) +#endif +{ +} + +thread_insn_span::~thread_insn_span() { } + +thread_insn_span::thread_insn_span(const thread_insn_span& other) + : m_cycle(other.m_cycle), m_n_insn(other.m_n_insn), + m_insn_span_count(other.m_insn_span_count) +{ +} + +thread_insn_span& thread_insn_span::operator=(const thread_insn_span& other) +{ + printf("thread_insn_span& operator=\n"); + if (this != &other && m_n_insn != other.m_n_insn) { + m_n_insn = other.m_n_insn; + m_insn_span_count = other.m_insn_span_count; + m_cycle = other.m_cycle; + } + return *this; +} + +thread_insn_span& thread_insn_span::operator+=(const thread_insn_span& other) +{ + assert(m_n_insn == other.m_n_insn); // no way to aggregate if they are different programs + span_count_map::const_iterator i_sc = other.m_insn_span_count.begin(); + for (; i_sc != other.m_insn_span_count.end(); ++i_sc) { + m_insn_span_count[i_sc->first] += i_sc->second; + } + return *this; +} + +void thread_insn_span::set_span( address_type pc ) +{ + if( ((int)pc) >= 0 ) + m_insn_span_count[pc] += 1; +} + +void thread_insn_span::reset(unsigned long long cycle) +{ + m_cycle = cycle; + m_insn_span_count.clear(); +} + +void thread_insn_span::print_span(FILE *fout) const +{ + fprintf(fout, "%d: ", (int)m_cycle); + span_count_map::const_iterator i_sc = m_insn_span_count.begin(); + for (; i_sc != m_insn_span_count.end(); ++i_sc) { + fprintf(fout, "%d ", i_sc->first); + } + fprintf(fout, "\n"); +} + +void thread_insn_span::print_histo(FILE *fout) const +{ + fprintf(fout, "%d:", (int)m_cycle); + span_count_map::const_iterator i_sc = m_insn_span_count.begin(); + for (; i_sc != m_insn_span_count.end(); ++i_sc) { + fprintf(fout, "%d ", i_sc->second); + } + fprintf(fout, "\n"); +} + +void thread_insn_span::print_sparse_histo(FILE *fout) const +{ + int n_printed_entries = 0; + span_count_map::const_iterator i_sc = m_insn_span_count.begin(); + for (; i_sc != m_insn_span_count.end(); ++i_sc) { + unsigned ptx_lineno = translate_pc_to_ptxlineno(i_sc->first); + fprintf(fout, "%u %d ", ptx_lineno, i_sc->second); + n_printed_entries++; + } + if (n_printed_entries == 0) { + fprintf(fout, "0 0 "); + } + fprintf(fout, "\n"); +} + +void thread_insn_span::print_sparse_histo(gzFile fout) const +{ + int n_printed_entries = 0; + span_count_map::const_iterator i_sc = m_insn_span_count.begin(); + for (; i_sc != m_insn_span_count.end(); ++i_sc) { + unsigned ptx_lineno = translate_pc_to_ptxlineno(i_sc->first); + gzprintf(fout, "%u %d ", ptx_lineno, i_sc->second); + n_printed_entries++; + } + if (n_printed_entries == 0) { + gzprintf(fout, "0 0 "); + } + gzprintf(fout, "\n"); +} + +//////////////////////////////////////////////////////////////////////////////// + +thread_CFlocality::thread_CFlocality(std::string name, + unsigned long long snap_shot_interval, + int nthreads, + int n_insn, + address_type start_pc, + unsigned long long start_cycle) + : snap_shot_trigger(snap_shot_interval), m_name(name), + m_nthreads(nthreads), m_thread_pc(nthreads, start_pc), m_cycle(start_cycle), + m_thd_span(start_cycle, n_insn) +{ + std::fill(m_thread_pc.begin(), m_thread_pc.end(), -1); // so that hw thread with no work assigned will not clobber results +} + +thread_CFlocality::~thread_CFlocality() +{ +} + +void thread_CFlocality::update_thread_pc( int thread_id, address_type pc ) +{ + m_thread_pc[thread_id] = pc; + m_thd_span.set_span(pc); +} + +void thread_CFlocality::snap_shot(unsigned long long current_cycle) +{ + m_thd_span_archive.push_back(m_thd_span); + m_thd_span.reset(current_cycle); + for (int i = 0; i < (int)m_thread_pc.size(); i++) { + m_thd_span.set_span(m_thread_pc[i]); + } +} + +void thread_CFlocality::spill(FILE *fout, bool final) +{ + std::list<thread_insn_span>::iterator lit = m_thd_span_archive.begin(); + for (; lit != m_thd_span_archive.end(); lit = m_thd_span_archive.erase(lit) ) { + fprintf(fout, "%s-", m_name.c_str()); + lit->print_histo(fout); + } + assert( m_thd_span_archive.empty() ); + if (final) { + fprintf(fout, "%s-", m_name.c_str()); + m_thd_span.print_histo(fout); + } +} + + +void thread_CFlocality::print_visualizer(FILE *fout) +{ + fprintf(fout, "%s: ", m_name.c_str()); + if (m_thd_span_archive.empty()) { + + // visualizer do no require snap_shots + m_thd_span.print_sparse_histo(fout); + + // clean the thread span + m_thd_span.reset(0); + for (int i = 0; i < (int)m_thread_pc.size(); i++) + m_thd_span.set_span(m_thread_pc[i]); + } else { + assert(0); // TODO: implement fall back so that visualizer can work with snap shots + } +} + +void thread_CFlocality::print_visualizer(gzFile fout) +{ + gzprintf(fout, "%s: ", m_name.c_str()); + if (m_thd_span_archive.empty()) { + + // visualizer do no require snap_shots + m_thd_span.print_sparse_histo(fout); + + // clean the thread span + m_thd_span.reset(0); + for (int i = 0; i < (int)m_thread_pc.size(); i++) { + m_thd_span.set_span(m_thread_pc[i]); + } + } else { + assert(0); // TODO: implement fall back so that visualizer can work with snap shots + } +} + +void thread_CFlocality::print_span(FILE *fout) const +{ + std::list<thread_insn_span>::const_iterator lit = m_thd_span_archive.begin(); + for (; lit != m_thd_span_archive.end(); ++lit) { + fprintf(fout, "%s-", m_name.c_str()); + lit->print_span(fout); + } + fprintf(fout, "%s-", m_name.c_str()); + m_thd_span.print_span(fout); +} + +void thread_CFlocality::print_histo(FILE *fout) const +{ + std::list<thread_insn_span>::const_iterator lit = m_thd_span_archive.begin(); + for (; lit != m_thd_span_archive.end(); ++lit) { + fprintf(fout, "%s-", m_name.c_str()); + lit->print_histo(fout); + } + fprintf(fout, "%s-", m_name.c_str()); + m_thd_span.print_histo(fout); +} + +//////////////////////////////////////////////////////////////////////////////// + +linear_histogram_logger::linear_histogram_logger(int n_bins, + unsigned long long snap_shot_interval, + const char *name, + bool reset_at_snap_shot, + unsigned long long start_cycle ) + : snap_shot_trigger(snap_shot_interval), + m_n_bins(n_bins), + m_curr_lin_hist(m_n_bins, start_cycle), + m_lin_hist_archive(), + m_cycle(start_cycle), + m_reset_at_snap_shot(reset_at_snap_shot), + m_name(name), + m_id(s_ids++) +{ +} + +linear_histogram_logger::linear_histogram_logger(const linear_histogram_logger& other) + : snap_shot_trigger(other.get_interval()), + m_n_bins(other.m_n_bins), + m_curr_lin_hist(m_n_bins, other.m_cycle), + m_lin_hist_archive(), + m_cycle(other.m_cycle), + m_reset_at_snap_shot(other.m_reset_at_snap_shot), + m_name(other.m_name), + m_id(s_ids++) +{ +} + +linear_histogram_logger::~linear_histogram_logger() +{ + remove_snap_shot_trigger(this); + remove_spill_log(this); +} + +void linear_histogram_logger::snap_shot(unsigned long long current_cycle) { + m_lin_hist_archive.push_back(m_curr_lin_hist); + if (m_reset_at_snap_shot) { + m_curr_lin_hist.reset(current_cycle); + } else { + m_curr_lin_hist.set_cycle(current_cycle); + } +} + +void linear_histogram_logger::spill(FILE *fout, bool final) +{ + std::list<linear_histogram_snapshot>::iterator iter = m_lin_hist_archive.begin(); + for (; iter != m_lin_hist_archive.end(); iter = m_lin_hist_archive.erase(iter) ) { + fprintf(fout, "%s%02d-", m_name.c_str(), (m_id >= 0)? m_id : 0); + iter->print(fout); + fprintf(fout, "\n"); + } + assert( m_lin_hist_archive.empty() ); + if (final) { + fprintf(fout, "%s%02d-", m_name.c_str(), (m_id >= 0)? m_id : 0); + m_curr_lin_hist.print(fout); + fprintf(fout, "\n"); + } +} + +void linear_histogram_logger::print(FILE *fout) const +{ + std::list<linear_histogram_snapshot>::const_iterator iter = m_lin_hist_archive.begin(); + for (; iter != m_lin_hist_archive.end(); ++iter) { + fprintf(fout, "%s%02d-", m_name.c_str(), m_id); + iter->print(fout); + fprintf(fout, "\n"); + } + fprintf(fout, "%s%02d-", m_name.c_str(), m_id); + m_curr_lin_hist.print(fout); + fprintf(fout, "\n"); +} + +void linear_histogram_logger::print_visualizer(FILE *fout) +{ + assert(m_lin_hist_archive.empty()); // don't support snapshot for now + fprintf(fout, "%s", m_name.c_str()); + if (m_id >= 0) { + fprintf(fout, "%02d: ", m_id); + } else { + fprintf(fout, ": "); + } + m_curr_lin_hist.print_visualizer(fout); + fprintf(fout, "\n"); + if (m_reset_at_snap_shot) { + m_curr_lin_hist.reset(0); + } +} + +void linear_histogram_logger::print_visualizer(gzFile fout) +{ + assert(m_lin_hist_archive.empty()); // don't support snapshot for now + gzprintf(fout, "%s", m_name.c_str()); + if (m_id >= 0) { + gzprintf(fout, "%02d: ", m_id); + } else { + gzprintf(fout, ": "); + } + m_curr_lin_hist.print_visualizer(fout); + gzprintf(fout, "\n"); + if (m_reset_at_snap_shot) { + m_curr_lin_hist.reset(0); + } +} + diff --git a/src/gpgpu-sim/stat-tool.h b/src/gpgpu-sim/stat-tool.h index 3ebe750..ebac6c2 100644 --- a/src/gpgpu-sim/stat-tool.h +++ b/src/gpgpu-sim/stat-tool.h @@ -67,9 +67,260 @@ #define STAT_TOOL_H #include "../abstract_hardware_model.h" +#include "histogram.h" + #include <stdio.h> #include <zlib.h> +// detect gcc 4.3 and use unordered map (part of c++0x) +// unordered map doesn't play nice with _GLIBCXX_DEBUG, just use a map if its enabled. +#if defined( __GNUC__ ) and not defined( _GLIBCXX_DEBUG ) +#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 + #include <unordered_map> + #define my_hash_map std::unordered_map +#else + #include <ext/hash_map> + namespace std { + using namespace __gnu_cxx; + } + #define my_hash_map std::hash_map +#endif +#else + #include <map> + #define my_hash_map std::map + #define USE_MAP +#endif + +///////////////////////////////////////////////////////////////////////////////////// +// logger snapshot trigger: +// - automate the snap_shot part of loggers to avoid modifying simulation loop everytime +// a new time-dependent stat is added +///////////////////////////////////////////////////////////////////////////////////// + +class snap_shot_trigger { +public: + snap_shot_trigger(unsigned long long interval) : m_snap_shot_interval(interval) {} + virtual ~snap_shot_trigger() {} + + void try_snap_shot(unsigned long long current_cycle) { + if ((current_cycle % m_snap_shot_interval == 0) && current_cycle != 0) { + snap_shot(current_cycle); + } + } + + virtual void snap_shot(unsigned long long current_cycle) = 0; + + const unsigned long long & get_interval() const { return m_snap_shot_interval;} + +protected: + unsigned long long m_snap_shot_interval; +}; + + +///////////////////////////////////////////////////////////////////////////////////// +// spill log interface: +// - unified interface to spill log to file to avoid infinite memory usage for logging +///////////////////////////////////////////////////////////////////////////////////// + +class spill_log_interface { +public: + spill_log_interface() {} + virtual ~spill_log_interface() {} + + virtual void spill(FILE *fout, bool final) = 0; +}; + +///////////////////////////////////////////////////////////////////////////////////// +// thread control-flow locality logger +///////////////////////////////////////////////////////////////////////////////////// + +class thread_insn_span { +public: + thread_insn_span(unsigned long long cycle, int n_insn); + thread_insn_span(const thread_insn_span& other); + ~thread_insn_span(); + + thread_insn_span& operator=(const thread_insn_span& other); + thread_insn_span& operator+=(const thread_insn_span& other); + void set_span( address_type pc ); + void reset(unsigned long long cycle); + + void print_span(FILE *fout) const; + void print_histo(FILE *fout) const; + void print_sparse_histo(FILE *fout) const; + void print_sparse_histo(gzFile fout) const; + +private: + typedef my_hash_map<address_type, int> span_count_map; + unsigned long long m_cycle; + int m_n_insn; + span_count_map m_insn_span_count; +}; + +class thread_CFlocality : public snap_shot_trigger, public spill_log_interface { +public: + thread_CFlocality(std::string name, unsigned long long snap_shot_interval, + int nthreads, int n_insn, address_type start_pc, unsigned long long start_cycle = 0); + ~thread_CFlocality(); + + void update_thread_pc( int thread_id, address_type pc ); + void snap_shot(unsigned long long current_cycle); + void spill(FILE *fout, bool final); + + void print_visualizer(FILE *fout); + void print_visualizer(gzFile fout); + void print_span(FILE *fout) const; + void print_histo(FILE *fout) const; +private: + std::string m_name; + + int m_nthreads; + std::vector<address_type> m_thread_pc; + + unsigned long long m_cycle; + thread_insn_span m_thd_span; + std::list<thread_insn_span> m_thd_span_archive; +}; + +///////////////////////////////////////////////////////////////////////////////////// +// per-insn active thread distribution (warp occ) logger +///////////////////////////////////////////////////////////////////////////////////// + +class insn_warp_occ_logger { +public: + insn_warp_occ_logger(int simd_width, int n_insn) + : m_simd_width(simd_width), + m_insn_warp_occ(n_insn, linear_histogram(1, "", m_simd_width)), + m_id(s_ids++) {} + + insn_warp_occ_logger(const insn_warp_occ_logger& other) + : m_simd_width(other.m_simd_width), + m_insn_warp_occ(other.m_insn_warp_occ.size(), linear_histogram(1, "", m_simd_width)), + m_id(s_ids++) {} + + ~insn_warp_occ_logger() {} + + insn_warp_occ_logger& operator=(const insn_warp_occ_logger& p) { + printf("insn_warp_occ_logger Operator= called: %02d \n", m_id); + assert(0); + return *this; + } + + void set_id(int id) { m_id = id; } + + void log(address_type pc, int warp_occ) { + m_insn_warp_occ[pc].add2bin(warp_occ - 1); + } + + void print(FILE *fout) const + { + for (unsigned i = 0; i < m_insn_warp_occ.size(); i++) { + fprintf(fout, "InsnWarpOcc%02d-%d", m_id, i); + m_insn_warp_occ[i].fprint(fout); + fprintf(fout, "\n"); + } + } + +private: + + int m_simd_width; + std::vector<linear_histogram> m_insn_warp_occ; + int m_id; + static int s_ids; +}; + + +///////////////////////////////////////////////////////////////////////////////////// +// generic linear histogram logger +///////////////////////////////////////////////////////////////////////////////////// + +class linear_histogram_snapshot { +public: + linear_histogram_snapshot(int n_bins, unsigned long long cycle) + : m_cycle(cycle), + m_linear_histogram(n_bins,0) + { } + + linear_histogram_snapshot(const linear_histogram_snapshot& other) + : m_cycle(other.m_cycle), + m_linear_histogram(other.m_linear_histogram) + { } + + ~linear_histogram_snapshot() { } + + void addsample(int pos) { + assert((size_t)pos < m_linear_histogram.size()); + m_linear_histogram[pos] += 1; + } + + void subsample(int pos) { + assert((size_t)pos < m_linear_histogram.size()); + m_linear_histogram[pos] -= 1; + } + + void reset(unsigned long long cycle) { + m_cycle = cycle; + m_linear_histogram.assign(m_linear_histogram.size(), 0); + } + + void set_cycle(unsigned long long cycle) { m_cycle = cycle; } + + void print(FILE *fout) const { + fprintf(fout, "%d = ", (int)m_cycle); + for (unsigned int i = 0; i < m_linear_histogram.size(); i++) { + fprintf(fout, "%d ", m_linear_histogram[i]); + } + } + + void print_visualizer(FILE *fout) const { + for (unsigned int i = 0; i < m_linear_histogram.size(); i++) { + fprintf(fout, "%d ", m_linear_histogram[i]); + } + } + + void print_visualizer(gzFile fout) const { + for (unsigned int i = 0; i < m_linear_histogram.size(); i++) { + gzprintf(fout, "%d ", m_linear_histogram[i]); + } + } + +private: + unsigned long long m_cycle; + std::vector<int> m_linear_histogram; +}; + +class linear_histogram_logger : public snap_shot_trigger, public spill_log_interface { +public: + linear_histogram_logger(int n_bins, + unsigned long long snap_shot_interval, + const char *name, + bool reset_at_snap_shot = true, + unsigned long long start_cycle = 0); + linear_histogram_logger(const linear_histogram_logger& other); + + ~linear_histogram_logger(); + + void set_id(int id) { m_id = id; } + void log(int pos) { m_curr_lin_hist.addsample(pos); } + void unlog(int pos) { m_curr_lin_hist.subsample(pos); } + void snap_shot(unsigned long long current_cycle); + void spill(FILE *fout, bool final); + + void print(FILE *fout) const; + void print_visualizer(FILE *fout); + void print_visualizer(gzFile fout); + +private: + int m_n_bins; + linear_histogram_snapshot m_curr_lin_hist; + std::list<linear_histogram_snapshot> m_lin_hist_archive; + unsigned long long m_cycle; + bool m_reset_at_snap_shot; + std::string m_name; + int m_id; + static int s_ids; +}; + void try_snap_shot (unsigned long long current_cycle); void set_spill_interval (unsigned long long interval); void spill_log_to_file (FILE *fout, int final, unsigned long long current_cycle); diff --git a/src/gpgpu-sim/visualizer.cc b/src/gpgpu-sim/visualizer.cc index 15dc157..440f9e0 100644 --- a/src/gpgpu-sim/visualizer.cc +++ b/src/gpgpu-sim/visualizer.cc @@ -197,8 +197,6 @@ void gpgpu_sim::visualizer_printstat() gzprintf(visualizer_file, "globalinsncount: %lld\n", gpu_sim_insn); gzprintf(visualizer_file, "globaltotinsncount: %lld\n", gpu_tot_sim_insn); gzprintf(visualizer_file, "gpucompletedthreads: %lld\n", m_shader_stats->gpu_completed_thread); - gzprintf(visualizer_file, "gpgpunsentwrites: %d\n", gpgpu_n_sent_writes); - gzprintf(visualizer_file, "gpgpunprocessedwrites: %d\n", gpgpu_n_processed_writes); gzprintf(visualizer_file, "gpgpu_n_cache_bkconflict: %d\n", m_shader_stats->gpgpu_n_cache_bkconflict); gzprintf(visualizer_file, "gpgpu_n_shmem_bkconflict: %d\n", m_shader_stats->gpgpu_n_shmem_bkconflict); gzprintf(visualizer_file, "gpu_stall_by_MSHRwb: %d\n", m_shader_stats->gpu_stall_by_MSHRwb); |
