summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilson Fung <[email protected]>2013-06-23 02:59:55 -0800
committerAndrew Boktor <[email protected]>2014-08-14 13:50:48 -0700
commitd0d12843ce57c1b0c1e77bae2a43bf222af19375 (patch)
tree07d17add206d8b8d6e83b89954afd8dcd98ac967
parent33c2bb5ba2f0b45474fe2a72d87886692d6bf4ca (diff)
Interconnection traffic breakdown stats (integration from TM branch).
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 16495]
-rw-r--r--CHANGES1
-rw-r--r--src/abstract_hardware_model.cc20
-rw-r--r--src/abstract_hardware_model.h35
-rw-r--r--src/gpgpu-sim/shader.cc19
-rw-r--r--src/gpgpu-sim/shader.h19
-rw-r--r--src/gpgpu-sim/traffic_breakdown.cc50
-rw-r--r--src/gpgpu-sim/traffic_breakdown.h37
7 files changed, 155 insertions, 26 deletions
diff --git a/CHANGES b/CHANGES
index b403bc0..0f41234 100644
--- a/CHANGES
+++ b/CHANGES
@@ -22,6 +22,7 @@ Version 3.2.1+edits (development branch) versus 3.2.1
- Added new option '-liveness_message_freq'. It throttles the number of
simulation liveness messages printed by the timing model (defaults to
1 message per second in wall clock time).
+- Added breakdown for interconnection traffic based on memory access type.
- Bug Fixes:
- Fixed the flit count sent to GPUWattch for atomic operations.
- Fix for Bug 51 - Updated the function declaration of
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index 5ef7599..fd227e1 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -110,20 +110,14 @@ address_type line_size_based_tag_func(new_addr_type address, new_addr_type line_
const char * mem_access_type_str(enum mem_access_type access_type)
{
- static const char * access_type_str[] = {
- "GLOBAL_ACC_R",
- "LOCAL_ACC_R",
- "CONST_ACC_R",
- "TEXTURE_ACC_R",
- "GLOBAL_ACC_W",
- "LOCAL_ACC_W",
- "L1_WRBK_ACC",
- "L2_WRBK_ACC",
- "INST_ACC_R",
- "L2_WR_ALLOC_R"
- };
+ #define MA_TUP_BEGIN(X) static const char* access_type_str[] = {
+ #define MA_TUP(X) #X
+ #define MA_TUP_END(X) };
+ MEM_ACCESS_TYPE_TUP_DEF
+ #undef MA_TUP_BEGIN
+ #undef MA_TUP
+ #undef MA_TUP_END
- assert(sizeof(access_type_str) / sizeof(const char*) == NUM_MEM_ACCESS_TYPE);
assert(access_type < NUM_MEM_ACCESS_TYPE);
return access_type_str[access_type];
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index f0966e6..9a29bc3 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -541,19 +541,28 @@ const unsigned MAX_MEMORY_ACCESS_SIZE = 128;
typedef std::bitset<MAX_MEMORY_ACCESS_SIZE> mem_access_byte_mask_t;
#define NO_PARTIAL_WRITE (mem_access_byte_mask_t())
-enum mem_access_type {
- GLOBAL_ACC_R,
- LOCAL_ACC_R,
- CONST_ACC_R,
- TEXTURE_ACC_R,
- GLOBAL_ACC_W,
- LOCAL_ACC_W,
- L1_WRBK_ACC,
- L2_WRBK_ACC,
- INST_ACC_R,
- L2_WR_ALLOC_R,
- NUM_MEM_ACCESS_TYPE
-};
+#define MEM_ACCESS_TYPE_TUP_DEF \
+MA_TUP_BEGIN( mem_access_type ) \
+ MA_TUP( GLOBAL_ACC_R ), \
+ MA_TUP( LOCAL_ACC_R), \
+ MA_TUP( CONST_ACC_R), \
+ MA_TUP( TEXTURE_ACC_R), \
+ MA_TUP( GLOBAL_ACC_W), \
+ MA_TUP( LOCAL_ACC_W), \
+ MA_TUP( L1_WRBK_ACC), \
+ MA_TUP( L2_WRBK_ACC), \
+ MA_TUP( INST_ACC_R), \
+ MA_TUP( L2_WR_ALLOC_R), \
+ MA_TUP( NUM_MEM_ACCESS_TYPE) \
+MA_TUP_END( mem_access_type )
+
+#define MA_TUP_BEGIN(X) enum X {
+#define MA_TUP(X) X
+#define MA_TUP_END(X) };
+MEM_ACCESS_TYPE_TUP_DEF
+#undef MA_TUP_BEGIN
+#undef MA_TUP
+#undef MA_TUP_END
const char * mem_access_type_str(enum mem_access_type access_type);
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 410a333..830b8c1 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -45,6 +45,7 @@
#include "icnt_wrapper.h"
#include <string.h>
#include <limits.h>
+#include "traffic_breakdown.h"
#include "shader_trace.h"
#define PRIORITIZE_MSHR_OVER_WB 1
@@ -425,6 +426,9 @@ void shader_core_stats::print( FILE* fout ) const
for (unsigned i = 3; i < m_config->warp_size + 3; i++)
fprintf(fout, "\tW%d:%d", i-2, shader_cycle_distro[i]);
fprintf(fout, "\n");
+
+ m_outgoing_traffic_stats->print(fout);
+ m_incoming_traffic_stats->print(fout);
}
void shader_core_stats::event_warp_issued( unsigned s_id, unsigned warp_id, unsigned num_issued, unsigned dynamic_warp_id ) {
@@ -3087,6 +3091,15 @@ void simt_core_cluster::icnt_inject_request_packet(class mem_fetch *mf)
case L2_WR_ALLOC_R: m_stats->gpgpu_n_mem_l2_write_allocate++; break;
default: assert(0);
}
+
+ // The packet size varies depending on the type of request:
+ // - For write request and atomic request, the packet contains the data
+ // - For read request (i.e. not write nor atomic), the packet only has control metadata
+ unsigned int packet_size = mf->size();
+ if (!mf->get_is_write() && !mf->isatomic()) {
+ packet_size = mf->get_ctrl_size();
+ }
+ m_stats->m_outgoing_traffic_stats->record_traffic(mf, packet_size);
unsigned destination = mf->get_tlx_addr().chip;
mf->set_status(IN_ICNT_TO_MEM,gpu_sim_cycle+gpu_tot_sim_cycle);
if (!mf->get_is_write() && !mf->isatomic())
@@ -3121,6 +3134,12 @@ void simt_core_cluster::icnt_cycle()
return;
assert(mf->get_tpc() == m_cluster_id);
assert(mf->get_type() == READ_REPLY || mf->get_type() == WRITE_ACK );
+
+ // The packet size varies depending on the type of request:
+ // - For read request and atomic request, the packet contains the data
+ // - For write-ack, the packet only has control metadata
+ unsigned int packet_size = (mf->get_is_write())? mf->get_ctrl_size() : mf->size();
+ m_stats->m_incoming_traffic_stats->record_traffic(mf, packet_size);
mf->set_status(IN_CLUSTER_TO_SHADER_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle);
//m_memory_stats->memlatstat_read_done(mf,m_shader_config->max_warps_per_shader);
m_response_fifo.push_back(mf);
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index 2fb27ee..76133e2 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -52,6 +52,7 @@
#include "mem_fetch.h"
#include "stats.h"
#include "gpu-cache.h"
+#include "traffic_breakdown.h"
@@ -1421,12 +1422,26 @@ public:
n_simt_to_mem = (long *)calloc(config->num_shader(), sizeof(long));
n_mem_to_simt = (long *)calloc(config->num_shader(), sizeof(long));
+ m_outgoing_traffic_stats = new traffic_breakdown("coretomem");
+ m_incoming_traffic_stats = new traffic_breakdown("memtocore");
+
gpgpu_n_shmem_bank_access = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
m_shader_dynamic_warp_issue_distro.resize( config->num_shader() );
m_shader_warp_slot_issue_distro.resize( config->num_shader() );
}
+ ~shader_core_stats()
+ {
+ delete m_outgoing_traffic_stats;
+ delete m_incoming_traffic_stats;
+ free(m_num_sim_insn);
+ free(m_num_sim_winsn);
+ free(m_n_diverge);
+ free(shader_cycle_distro);
+ free(last_shader_cycle_distro);
+ }
+
void new_grid()
{
}
@@ -1449,6 +1464,10 @@ public:
private:
const shader_core_config *m_config;
+
+ traffic_breakdown *m_outgoing_traffic_stats; // core to memory partitions
+ traffic_breakdown *m_incoming_traffic_stats; // memory partition to core
+
// Counts the instructions issued for each dynamic warp.
std::vector< std::vector<unsigned> > m_shader_dynamic_warp_issue_distro;
std::vector<unsigned> m_last_shader_dynamic_warp_issue_distro;
diff --git a/src/gpgpu-sim/traffic_breakdown.cc b/src/gpgpu-sim/traffic_breakdown.cc
new file mode 100644
index 0000000..b21b8d8
--- /dev/null
+++ b/src/gpgpu-sim/traffic_breakdown.cc
@@ -0,0 +1,50 @@
+#include "traffic_breakdown.h"
+#include "mem_fetch.h"
+
+void traffic_breakdown::print(FILE* fout)
+{
+ for (traffic_stat_t::const_iterator i_stat = m_stats.begin(); i_stat != m_stats.end(); i_stat++) {
+ unsigned int byte_transferred = 0;
+ for (traffic_class_t::const_iterator i_class = i_stat->second.begin(); i_class != i_stat->second.end(); i_class++) {
+ byte_transferred += i_class->first * i_class->second; // byte/packet x #packets
+ }
+ fprintf(fout, "traffic_breakdown_%s[%s] = %u {", m_network_name.c_str(), i_stat->first.c_str(), byte_transferred);
+ for (traffic_class_t::const_iterator i_class = i_stat->second.begin(); i_class != i_stat->second.end(); i_class++) {
+ fprintf(fout, "%u:%u,", i_class->first, i_class->second);
+ }
+ fprintf(fout, "}\n");
+ }
+}
+
+void traffic_breakdown::record_traffic(class mem_fetch * mf, unsigned int size)
+{
+ m_stats[classify_memfetch(mf)][size] += 1;
+}
+
+std::string traffic_breakdown::classify_memfetch(class mem_fetch * mf)
+{
+ std::string traffic_name;
+
+ enum mem_access_type access_type = mf->get_access_type();
+
+ switch (access_type) {
+ case CONST_ACC_R:
+ case TEXTURE_ACC_R:
+ case GLOBAL_ACC_W:
+ case LOCAL_ACC_R:
+ case LOCAL_ACC_W:
+ case INST_ACC_R:
+ case L1_WRBK_ACC:
+ case L2_WRBK_ACC:
+ case L2_WR_ALLOC_R:
+ traffic_name = mem_access_type_str(access_type);
+ break;
+ case GLOBAL_ACC_R:
+ // check for global atomic operation
+ traffic_name = (mf->isatomic())? "GLOBAL_ATOMIC" : mem_access_type_str(GLOBAL_ACC_R);
+ break;
+ default: assert(0 && "Unknown traffic type");
+ }
+ return traffic_name;
+}
+
diff --git a/src/gpgpu-sim/traffic_breakdown.h b/src/gpgpu-sim/traffic_breakdown.h
new file mode 100644
index 0000000..c9b8df5
--- /dev/null
+++ b/src/gpgpu-sim/traffic_breakdown.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <stdio.h>
+#include <map>
+#include <string>
+
+// Breakdown traffic through the network according to category
+class traffic_breakdown
+{
+public:
+ traffic_breakdown(const std::string &network_name)
+ : m_network_name(network_name)
+ { }
+
+ // print the stats
+ void print(FILE* fout);
+
+ // record the amount and type of traffic introduced by this mem_fetch object
+ void record_traffic(class mem_fetch * mf, unsigned int size);
+
+protected:
+
+ std::string m_network_name;
+
+ /// helper functions to identify the type of traffic sent
+ std::string classify_memfetch(class mem_fetch * mf);
+
+ /// helper functions to identify the size of traffic sent
+ unsigned int packet_size(class mem_fetch * mf);
+
+ typedef std::string mf_packet_type; // use string so that it remains extensible
+ typedef unsigned int mf_packet_size;
+ typedef std::map < mf_packet_size, unsigned int > traffic_class_t;
+ typedef std::map < mf_packet_type, traffic_class_t > traffic_stat_t;
+
+ traffic_stat_t m_stats;
+};