summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim
diff options
context:
space:
mode:
authorTor Aamodt <[email protected]>2010-10-16 14:25:19 -0800
committerTor Aamodt <[email protected]>2010-10-16 14:25:19 -0800
commit2072e7ff2037c19a0c346e60469949c9437569bf (patch)
tree8235c2c67ca8f231c14d99bc1db660b26812734e /src/gpgpu-sim
parent58459bf7a55010eccf9940cfdb53cbc854b0989c (diff)
1. refactoring histogram/logger so that classes are in header files
2. starting to redo cache_t 3. deleting more perf counters 4. other minor cleaning [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 7869]
Diffstat (limited to 'src/gpgpu-sim')
-rw-r--r--src/gpgpu-sim/gpu-cache.cc15
-rw-r--r--src/gpgpu-sim/gpu-cache.h8
-rw-r--r--src/gpgpu-sim/gpu-sim.cc10
-rw-r--r--src/gpgpu-sim/gpu-sim.h19
-rw-r--r--src/gpgpu-sim/histogram.cc162
-rw-r--r--src/gpgpu-sim/histogram.h41
-rw-r--r--src/gpgpu-sim/l2cache.cc3
-rw-r--r--src/gpgpu-sim/stat-tool.cc922
-rw-r--r--src/gpgpu-sim/stat-tool.h251
-rw-r--r--src/gpgpu-sim/visualizer.cc2
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);