summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/abstract_hardware_model.cc8
-rw-r--r--src/abstract_hardware_model.h21
-rw-r--r--src/gpgpu-sim/gpu-cache.cc531
-rw-r--r--src/gpgpu-sim/gpu-cache.h77
-rw-r--r--src/gpgpu-sim/gpu-sim.cc72
-rw-r--r--src/gpgpu-sim/gpu-sim.h18
-rw-r--r--src/gpgpu-sim/l2cache.cc29
-rw-r--r--src/gpgpu-sim/l2cache.h7
-rw-r--r--src/gpgpu-sim/mem_fetch.cc9
-rw-r--r--src/gpgpu-sim/mem_fetch.h10
-rw-r--r--src/gpgpu-sim/power_stat.cc6
-rw-r--r--src/gpgpu-sim/shader.cc42
-rw-r--r--src/gpgpu-sim/shader.h19
-rw-r--r--src/gpgpusim_entrypoint.cc6
-rw-r--r--src/stream_manager.cc12
15 files changed, 609 insertions, 258 deletions
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index fd056c6..e8ddf95 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -49,12 +49,14 @@ void mem_access_t::init(gpgpu_context *ctx) {
m_addr = 0;
m_req_size = 0;
}
+
void warp_inst_t::issue(const active_mask_t &mask, unsigned warp_id,
unsigned long long cycle, int dynamic_warp_id,
- int sch_id) {
+ int sch_id, unsigned long long streamID) {
m_warp_active_mask = mask;
m_warp_issued_mask = mask;
m_uid = ++(m_config->gpgpu_ctx->warp_inst_sm_next_uid);
+ m_streamID = streamID;
m_warp_id = warp_id;
m_dynamic_warp_id = dynamic_warp_id;
issue_cycle = cycle;
@@ -755,7 +757,8 @@ void warp_inst_t::completed(unsigned long long cycle) const {
}
kernel_info_t::kernel_info_t(dim3 gridDim, dim3 blockDim,
- class function_info *entry) {
+ class function_info *entry,
+ unsigned long long streamID) {
m_kernel_entry = entry;
m_grid_dim = gridDim;
m_block_dim = blockDim;
@@ -765,6 +768,7 @@ kernel_info_t::kernel_info_t(dim3 gridDim, dim3 blockDim,
m_next_tid = m_next_cta;
m_num_cores_running = 0;
m_uid = (entry->gpgpu_ctx->kernel_info_m_next_uid)++;
+ m_streamID = streamID;
m_param_mem = new memory_space_impl<8192>("param", 64 * 1024);
// Jin: parent and child kernel management for CDP
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index e5f3b78..98a4039 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -233,7 +233,8 @@ class kernel_info_t {
// m_num_cores_running=0;
// m_param_mem=NULL;
// }
- kernel_info_t(dim3 gridDim, dim3 blockDim, class function_info *entry);
+ kernel_info_t(dim3 gridDim, dim3 blockDim, class function_info *entry,
+ unsigned long long streamID);
kernel_info_t(
dim3 gridDim, dim3 blockDim, class function_info *entry,
std::map<std::string, const struct cudaArray *> nameToCudaArray,
@@ -292,6 +293,7 @@ class kernel_info_t {
m_next_tid.x < m_block_dim.x;
}
unsigned get_uid() const { return m_uid; }
+ unsigned long long get_streamID() const { return m_streamID; }
std::string get_name() const { return name(); }
std::string name() const;
@@ -325,7 +327,8 @@ class kernel_info_t {
class function_info *m_kernel_entry;
- unsigned m_uid;
+ unsigned m_uid; // Kernel ID
+ unsigned long long m_streamID;
// These maps contain the snapshot of the texture mappings at kernel launch
std::map<std::string, const struct cudaArray *> m_NameToCudaArray;
@@ -900,8 +903,8 @@ class mem_fetch_interface {
class mem_fetch_allocator {
public:
virtual mem_fetch *alloc(new_addr_type addr, mem_access_type type,
- unsigned size, bool wr,
- unsigned long long cycle) const = 0;
+ unsigned size, bool wr, unsigned long long cycle,
+ unsigned long long streamID) const = 0;
virtual mem_fetch *alloc(const class warp_inst_t &inst,
const mem_access_t &access,
unsigned long long cycle) const = 0;
@@ -911,7 +914,8 @@ class mem_fetch_allocator {
const mem_access_sector_mask_t &sector_mask,
unsigned size, bool wr, unsigned long long cycle,
unsigned wid, unsigned sid, unsigned tpc,
- mem_fetch *original_mf) const = 0;
+ mem_fetch *original_mf,
+ unsigned long long streamID) const = 0;
};
// the maximum number of destination, source, or address uarch operands in a
@@ -1059,6 +1063,7 @@ class warp_inst_t : public inst_t {
// constructors
warp_inst_t() {
m_uid = 0;
+ m_streamID = (unsigned long long)-1;
m_empty = true;
m_config = NULL;
@@ -1071,6 +1076,7 @@ class warp_inst_t : public inst_t {
}
warp_inst_t(const core_config *config) {
m_uid = 0;
+ m_streamID = (unsigned long long)-1;
assert(config->warp_size <= MAX_WARP_SIZE);
m_config = config;
m_empty = true;
@@ -1098,7 +1104,8 @@ class warp_inst_t : public inst_t {
void clear() { m_empty = true; }
void issue(const active_mask_t &mask, unsigned warp_id,
- unsigned long long cycle, int dynamic_warp_id, int sch_id);
+ unsigned long long cycle, int dynamic_warp_id, int sch_id,
+ unsigned long long streamID);
const active_mask_t &get_active_mask() const { return m_warp_active_mask; }
void completed(unsigned long long cycle)
@@ -1226,11 +1233,13 @@ class warp_inst_t : public inst_t {
void print(FILE *fout) const;
unsigned get_uid() const { return m_uid; }
+ unsigned long long get_streamID() const { return m_streamID; }
unsigned get_schd_id() const { return m_scheduler_id; }
active_mask_t get_warp_active_mask() const { return m_warp_active_mask; }
protected:
unsigned m_uid;
+ unsigned long long m_streamID;
bool m_empty;
bool m_cache_hit;
unsigned long long issue_cycle;
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc
index 32cc56b..cd3c880 100644
--- a/src/gpgpu-sim/gpu-cache.cc
+++ b/src/gpgpu-sim/gpu-cache.cc
@@ -634,14 +634,6 @@ void mshr_table::display(FILE *fp) const {
/***************************************************************** Caches
* *****************************************************************/
cache_stats::cache_stats() {
- m_stats.resize(NUM_MEM_ACCESS_TYPE);
- m_stats_pw.resize(NUM_MEM_ACCESS_TYPE);
- m_fail_stats.resize(NUM_MEM_ACCESS_TYPE);
- for (unsigned i = 0; i < NUM_MEM_ACCESS_TYPE; ++i) {
- m_stats[i].resize(NUM_CACHE_REQUEST_STATUS, 0);
- m_stats_pw[i].resize(NUM_CACHE_REQUEST_STATUS, 0);
- m_fail_stats[i].resize(NUM_CACHE_RESERVATION_FAIL_STATUS, 0);
- }
m_cache_port_available_cycles = 0;
m_cache_data_port_busy_cycles = 0;
m_cache_fill_port_busy_cycles = 0;
@@ -651,11 +643,10 @@ void cache_stats::clear() {
///
/// Zero out all current cache statistics
///
- for (unsigned i = 0; i < NUM_MEM_ACCESS_TYPE; ++i) {
- std::fill(m_stats[i].begin(), m_stats[i].end(), 0);
- std::fill(m_stats_pw[i].begin(), m_stats_pw[i].end(), 0);
- std::fill(m_fail_stats[i].begin(), m_fail_stats[i].end(), 0);
- }
+ m_stats.clear();
+ m_stats_pw.clear();
+ m_fail_stats.clear();
+
m_cache_port_available_cycles = 0;
m_cache_data_port_busy_cycles = 0;
m_cache_fill_port_busy_cycles = 0;
@@ -665,35 +656,67 @@ void cache_stats::clear_pw() {
///
/// Zero out per-window cache statistics
///
- for (unsigned i = 0; i < NUM_MEM_ACCESS_TYPE; ++i) {
- std::fill(m_stats_pw[i].begin(), m_stats_pw[i].end(), 0);
- }
+ m_stats_pw.clear();
}
-void cache_stats::inc_stats(int access_type, int access_outcome) {
+void cache_stats::inc_stats(int access_type, int access_outcome,
+ unsigned long long streamID) {
///
/// Increment the stat corresponding to (access_type, access_outcome) by 1.
///
if (!check_valid(access_type, access_outcome))
assert(0 && "Unknown cache access type or access outcome");
- m_stats[access_type][access_outcome]++;
+ if (m_stats.find(streamID) == m_stats.end()) {
+ std::vector<std::vector<unsigned long long>> new_val;
+ new_val.resize(NUM_MEM_ACCESS_TYPE);
+ for (unsigned j = 0; j < NUM_MEM_ACCESS_TYPE; ++j) {
+ new_val[j].resize(NUM_CACHE_REQUEST_STATUS, 0);
+ }
+ m_stats.insert(std::pair<unsigned long long,
+ std::vector<std::vector<unsigned long long>>>(
+ streamID, new_val));
+ }
+ m_stats.at(streamID)[access_type][access_outcome]++;
}
-void cache_stats::inc_stats_pw(int access_type, int access_outcome) {
+void cache_stats::inc_stats_pw(int access_type, int access_outcome,
+ unsigned long long streamID) {
///
/// Increment the corresponding per-window cache stat
///
if (!check_valid(access_type, access_outcome))
assert(0 && "Unknown cache access type or access outcome");
- m_stats_pw[access_type][access_outcome]++;
+
+ if (m_stats_pw.find(streamID) == m_stats_pw.end()) {
+ std::vector<std::vector<unsigned long long>> new_val;
+ new_val.resize(NUM_MEM_ACCESS_TYPE);
+ for (unsigned j = 0; j < NUM_MEM_ACCESS_TYPE; ++j) {
+ new_val[j].resize(NUM_CACHE_REQUEST_STATUS, 0);
+ }
+ m_stats_pw.insert(std::pair<unsigned long long,
+ std::vector<std::vector<unsigned long long>>>(
+ streamID, new_val));
+ }
+ m_stats_pw.at(streamID)[access_type][access_outcome]++;
}
-void cache_stats::inc_fail_stats(int access_type, int fail_outcome) {
+void cache_stats::inc_fail_stats(int access_type, int fail_outcome,
+ unsigned long long streamID) {
if (!check_fail_valid(access_type, fail_outcome))
assert(0 && "Unknown cache access type or access fail");
- m_fail_stats[access_type][fail_outcome]++;
+ if (m_fail_stats.find(streamID) == m_fail_stats.end()) {
+ std::vector<std::vector<unsigned long long>> new_val;
+ new_val.resize(NUM_MEM_ACCESS_TYPE);
+ for (unsigned j = 0; j < NUM_MEM_ACCESS_TYPE; ++j) {
+ new_val[j].resize(NUM_CACHE_RESERVATION_FAIL_STATUS, 0);
+ }
+ m_fail_stats.insert(std::pair<unsigned long long,
+ std::vector<std::vector<unsigned long long>>>(
+ streamID, new_val));
+ }
+ m_fail_stats.at(streamID)[access_type][fail_outcome]++;
}
enum cache_request_status cache_stats::select_stats_status(
@@ -712,7 +735,8 @@ enum cache_request_status cache_stats::select_stats_status(
}
unsigned long long &cache_stats::operator()(int access_type, int access_outcome,
- bool fail_outcome) {
+ bool fail_outcome,
+ unsigned long long streamID) {
///
/// Simple method to read/modify the stat corresponding to (access_type,
/// access_outcome) Used overloaded () to avoid the need for separate
@@ -722,17 +746,18 @@ unsigned long long &cache_stats::operator()(int access_type, int access_outcome,
if (!check_fail_valid(access_type, access_outcome))
assert(0 && "Unknown cache access type or fail outcome");
- return m_fail_stats[access_type][access_outcome];
+ return m_fail_stats.at(streamID)[access_type][access_outcome];
} else {
if (!check_valid(access_type, access_outcome))
assert(0 && "Unknown cache access type or access outcome");
- return m_stats[access_type][access_outcome];
+ return m_stats.at(streamID)[access_type][access_outcome];
}
}
unsigned long long cache_stats::operator()(int access_type, int access_outcome,
- bool fail_outcome) const {
+ bool fail_outcome,
+ unsigned long long streamID) const {
///
/// Const accessor into m_stats.
///
@@ -740,12 +765,12 @@ unsigned long long cache_stats::operator()(int access_type, int access_outcome,
if (!check_fail_valid(access_type, access_outcome))
assert(0 && "Unknown cache access type or fail outcome");
- return m_fail_stats[access_type][access_outcome];
+ return m_fail_stats.at(streamID)[access_type][access_outcome];
} else {
if (!check_valid(access_type, access_outcome))
assert(0 && "Unknown cache access type or access outcome");
- return m_stats[access_type][access_outcome];
+ return m_stats.at(streamID)[access_type][access_outcome];
}
}
@@ -754,15 +779,74 @@ cache_stats cache_stats::operator+(const cache_stats &cs) {
/// Overloaded + operator to allow for simple stat accumulation
///
cache_stats ret;
- for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
- for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
- ret(type, status, false) =
- m_stats[type][status] + cs(type, status, false);
+ for (auto iter = m_stats.begin(); iter != m_stats.end(); ++iter) {
+ unsigned long long streamID = iter->first;
+ ret.m_stats.insert(std::pair<unsigned long long,
+ std::vector<std::vector<unsigned long long>>>(
+ streamID, m_stats.at(streamID)));
+ }
+ for (auto iter = m_stats_pw.begin(); iter != m_stats_pw.end(); ++iter) {
+ unsigned long long streamID = iter->first;
+ ret.m_stats_pw.insert(
+ std::pair<unsigned long long,
+ std::vector<std::vector<unsigned long long>>>(
+ streamID, m_stats_pw.at(streamID)));
+ }
+ for (auto iter = m_fail_stats.begin(); iter != m_fail_stats.end(); ++iter) {
+ unsigned long long streamID = iter->first;
+ ret.m_fail_stats.insert(
+ std::pair<unsigned long long,
+ std::vector<std::vector<unsigned long long>>>(
+ streamID, m_fail_stats.at(streamID)));
+ }
+ for (auto iter = cs.m_stats.begin(); iter != cs.m_stats.end(); ++iter) {
+ unsigned long long streamID = iter->first;
+ if (ret.m_stats.find(streamID) == ret.m_stats.end()) {
+ ret.m_stats.insert(
+ std::pair<unsigned long long,
+ std::vector<std::vector<unsigned long long>>>(
+ streamID, cs.m_stats.at(streamID)));
+ } else {
+ for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
+ for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
+ ret.m_stats.at(streamID)[type][status] +=
+ cs(type, status, false, streamID);
+ }
+ }
}
- for (unsigned status = 0; status < NUM_CACHE_RESERVATION_FAIL_STATUS;
- ++status) {
- ret(type, status, true) =
- m_fail_stats[type][status] + cs(type, status, true);
+ }
+ for (auto iter = cs.m_stats_pw.begin(); iter != cs.m_stats_pw.end(); ++iter) {
+ unsigned long long streamID = iter->first;
+ if (ret.m_stats_pw.find(streamID) == ret.m_stats_pw.end()) {
+ ret.m_stats_pw.insert(
+ std::pair<unsigned long long,
+ std::vector<std::vector<unsigned long long>>>(
+ streamID, cs.m_stats_pw.at(streamID)));
+ } else {
+ for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
+ for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
+ ret.m_stats_pw.at(streamID)[type][status] +=
+ cs(type, status, false, streamID);
+ }
+ }
+ }
+ }
+ for (auto iter = cs.m_fail_stats.begin(); iter != cs.m_fail_stats.end();
+ ++iter) {
+ unsigned long long streamID = iter->first;
+ if (ret.m_fail_stats.find(streamID) == ret.m_fail_stats.end()) {
+ ret.m_fail_stats.insert(
+ std::pair<unsigned long long,
+ std::vector<std::vector<unsigned long long>>>(
+ streamID, cs.m_fail_stats.at(streamID)));
+ } else {
+ for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
+ for (unsigned status = 0; status < NUM_CACHE_RESERVATION_FAIL_STATUS;
+ ++status) {
+ ret.m_fail_stats.at(streamID)[type][status] +=
+ cs(type, status, true, streamID);
+ }
+ }
}
}
ret.m_cache_port_available_cycles =
@@ -778,16 +862,52 @@ cache_stats &cache_stats::operator+=(const cache_stats &cs) {
///
/// Overloaded += operator to allow for simple stat accumulation
///
- for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
- for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
- m_stats[type][status] += cs(type, status, false);
+ for (auto iter = cs.m_stats.begin(); iter != cs.m_stats.end(); ++iter) {
+ unsigned long long streamID = iter->first;
+ if (m_stats.find(streamID) == m_stats.end()) {
+ m_stats.insert(std::pair<unsigned long long,
+ std::vector<std::vector<unsigned long long>>>(
+ streamID, cs.m_stats.at(streamID)));
+ } else {
+ for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
+ for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
+ m_stats.at(streamID)[type][status] +=
+ cs(type, status, false, streamID);
+ }
+ }
}
- for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
- m_stats_pw[type][status] += cs(type, status, false);
+ }
+ for (auto iter = cs.m_stats_pw.begin(); iter != cs.m_stats_pw.end(); ++iter) {
+ unsigned long long streamID = iter->first;
+ if (m_stats_pw.find(streamID) == m_stats_pw.end()) {
+ m_stats_pw.insert(std::pair<unsigned long long,
+ std::vector<std::vector<unsigned long long>>>(
+ streamID, cs.m_stats_pw.at(streamID)));
+ } else {
+ for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
+ for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
+ m_stats_pw.at(streamID)[type][status] +=
+ cs(type, status, false, streamID);
+ }
+ }
}
- for (unsigned status = 0; status < NUM_CACHE_RESERVATION_FAIL_STATUS;
- ++status) {
- m_fail_stats[type][status] += cs(type, status, true);
+ }
+ for (auto iter = cs.m_fail_stats.begin(); iter != cs.m_fail_stats.end();
+ ++iter) {
+ unsigned long long streamID = iter->first;
+ if (m_fail_stats.find(streamID) == m_fail_stats.end()) {
+ m_fail_stats.insert(
+ std::pair<unsigned long long,
+ std::vector<std::vector<unsigned long long>>>(
+ streamID, cs.m_fail_stats.at(streamID)));
+ } else {
+ for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
+ for (unsigned status = 0; status < NUM_CACHE_RESERVATION_FAIL_STATUS;
+ ++status) {
+ m_fail_stats.at(streamID)[type][status] +=
+ cs(type, status, true, streamID);
+ }
+ }
}
}
m_cache_port_available_cycles += cs.m_cache_port_available_cycles;
@@ -796,46 +916,65 @@ cache_stats &cache_stats::operator+=(const cache_stats &cs) {
return *this;
}
-void cache_stats::print_stats(FILE *fout, const char *cache_name) const {
+void cache_stats::print_stats(FILE *fout, unsigned long long streamID,
+ const char *cache_name) const {
///
- /// Print out each non-zero cache statistic for every memory access type and
- /// status "cache_name" defaults to "Cache_stats" when no argument is
- /// provided, otherwise the provided name is used. The printed format is
+ /// For a given CUDA stream, print out each non-zero cache statistic for every
+ /// memory access type and status "cache_name" defaults to "Cache_stats" when
+ /// no argument is provided, otherwise the provided name is used. The printed
+ /// format is
/// "<cache_name>[<request_type>][<request_status>] = <stat_value>"
- ///
+ /// Specify streamID to be -1 to print every stream.
+
std::vector<unsigned> total_access;
- total_access.resize(NUM_MEM_ACCESS_TYPE, 0);
std::string m_cache_name = cache_name;
- for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
- for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
- fprintf(fout, "\t%s[%s][%s] = %llu\n", m_cache_name.c_str(),
- mem_access_type_str((enum mem_access_type)type),
- cache_request_status_str((enum cache_request_status)status),
- m_stats[type][status]);
+ for (auto iter = m_stats.begin(); iter != m_stats.end(); ++iter) {
+ unsigned long long streamid = iter->first;
+ // when streamID is specified, skip stats for all other streams, otherwise,
+ // print stats from all streams
+ if ((streamID != -1) && (streamid != streamID)) continue;
+ total_access.clear();
+ total_access.resize(NUM_MEM_ACCESS_TYPE, 0);
+ for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
+ for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
+ fprintf(fout, "\t%s[%s][%s] = %llu\n", m_cache_name.c_str(),
+ mem_access_type_str((enum mem_access_type)type),
+ cache_request_status_str((enum cache_request_status)status),
+ m_stats.at(streamid)[type][status]);
- if (status != RESERVATION_FAIL && status != MSHR_HIT)
- // MSHR_HIT is a special type of SECTOR_MISS
- // so its already included in the SECTOR_MISS
- total_access[type] += m_stats[type][status];
+ if (status != RESERVATION_FAIL && status != MSHR_HIT)
+ // MSHR_HIT is a special type of SECTOR_MISS
+ // so its already included in the SECTOR_MISS
+ total_access[type] += m_stats.at(streamid)[type][status];
+ }
+ }
+ for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
+ if (total_access[type] > 0)
+ fprintf(fout, "\t%s[%s][%s] = %u\n", m_cache_name.c_str(),
+ mem_access_type_str((enum mem_access_type)type), "TOTAL_ACCESS",
+ total_access[type]);
}
- }
- for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
- if (total_access[type] > 0)
- fprintf(fout, "\t%s[%s][%s] = %u\n", m_cache_name.c_str(),
- mem_access_type_str((enum mem_access_type)type), "TOTAL_ACCESS",
- total_access[type]);
}
}
-void cache_stats::print_fail_stats(FILE *fout, const char *cache_name) const {
+void cache_stats::print_fail_stats(FILE *fout, unsigned long long streamID,
+ const char *cache_name) const {
std::string m_cache_name = cache_name;
- for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
- for (unsigned fail = 0; fail < NUM_CACHE_RESERVATION_FAIL_STATUS; ++fail) {
- if (m_fail_stats[type][fail] > 0) {
- fprintf(fout, "\t%s[%s][%s] = %llu\n", m_cache_name.c_str(),
- mem_access_type_str((enum mem_access_type)type),
- cache_fail_status_str((enum cache_reservation_fail_reason)fail),
- m_fail_stats[type][fail]);
+ for (auto iter = m_fail_stats.begin(); iter != m_fail_stats.end(); ++iter) {
+ unsigned long long streamid = iter->first;
+ // when streamID is specified, skip stats for all other streams, otherwise,
+ // print stats from all streams
+ if ((streamID != -1) && (streamid != streamID)) continue;
+ for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
+ for (unsigned fail = 0; fail < NUM_CACHE_RESERVATION_FAIL_STATUS;
+ ++fail) {
+ if (m_fail_stats.at(streamid)[type][fail] > 0) {
+ fprintf(
+ fout, "\t%s[%s][%s] = %llu\n", m_cache_name.c_str(),
+ mem_access_type_str((enum mem_access_type)type),
+ cache_fail_status_str((enum cache_reservation_fail_reason)fail),
+ m_fail_stats.at(streamid)[type][fail]);
+ }
}
}
}
@@ -866,11 +1005,14 @@ unsigned long long cache_stats::get_stats(
/// cache_request_statuses.
///
unsigned long long total = 0;
- for (unsigned type = 0; type < num_access_type; ++type) {
- for (unsigned status = 0; status < num_access_status; ++status) {
- if (!check_valid((int)access_type[type], (int)access_status[status]))
- assert(0 && "Unknown cache access type or access outcome");
- total += m_stats[access_type[type]][access_status[status]];
+ for (auto iter = m_stats.begin(); iter != m_stats.end(); ++iter) {
+ unsigned long long streamID = iter->first;
+ for (unsigned type = 0; type < num_access_type; ++type) {
+ for (unsigned status = 0; status < num_access_status; ++status) {
+ if (!check_valid((int)access_type[type], (int)access_status[status]))
+ assert(0 && "Unknown cache access type or access outcome");
+ total += m_stats.at(streamID)[access_type[type]][access_status[status]];
+ }
}
}
return total;
@@ -883,18 +1025,23 @@ void cache_stats::get_sub_stats(struct cache_sub_stats &css) const {
struct cache_sub_stats t_css;
t_css.clear();
- for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
- for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
- if (status == HIT || status == MISS || status == SECTOR_MISS ||
- status == HIT_RESERVED)
- t_css.accesses += m_stats[type][status];
+ for (auto iter = m_stats.begin(); iter != m_stats.end(); ++iter) {
+ unsigned long long streamID = iter->first;
+ for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
+ for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
+ if (status == HIT || status == MISS || status == SECTOR_MISS ||
+ status == HIT_RESERVED)
+ t_css.accesses += m_stats.at(streamID)[type][status];
- if (status == MISS || status == SECTOR_MISS)
- t_css.misses += m_stats[type][status];
+ if (status == MISS || status == SECTOR_MISS)
+ t_css.misses += m_stats.at(streamID)[type][status];
- if (status == HIT_RESERVED) t_css.pending_hits += m_stats[type][status];
+ if (status == HIT_RESERVED)
+ t_css.pending_hits += m_stats.at(streamID)[type][status];
- if (status == RESERVATION_FAIL) t_css.res_fails += m_stats[type][status];
+ if (status == RESERVATION_FAIL)
+ t_css.res_fails += m_stats.at(streamID)[type][status];
+ }
}
}
@@ -912,41 +1059,48 @@ void cache_stats::get_sub_stats_pw(struct cache_sub_stats_pw &css) const {
struct cache_sub_stats_pw t_css;
t_css.clear();
- for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
- for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
- if (status == HIT || status == MISS || status == SECTOR_MISS ||
- status == HIT_RESERVED)
- t_css.accesses += m_stats_pw[type][status];
+ for (auto iter = m_stats_pw.begin(); iter != m_stats_pw.end(); ++iter) {
+ unsigned long long streamID = iter->first;
+ for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) {
+ for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) {
+ if (status == HIT || status == MISS || status == SECTOR_MISS ||
+ status == HIT_RESERVED)
+ t_css.accesses += m_stats_pw.at(streamID)[type][status];
- if (status == HIT) {
- if (type == GLOBAL_ACC_R || type == CONST_ACC_R || type == INST_ACC_R) {
- t_css.read_hits += m_stats_pw[type][status];
- } else if (type == GLOBAL_ACC_W) {
- t_css.write_hits += m_stats_pw[type][status];
+ if (status == HIT) {
+ if (type == GLOBAL_ACC_R || type == CONST_ACC_R ||
+ type == INST_ACC_R) {
+ t_css.read_hits += m_stats_pw.at(streamID)[type][status];
+ } else if (type == GLOBAL_ACC_W) {
+ t_css.write_hits += m_stats_pw.at(streamID)[type][status];
+ }
}
- }
- if (status == MISS || status == SECTOR_MISS) {
- if (type == GLOBAL_ACC_R || type == CONST_ACC_R || type == INST_ACC_R) {
- t_css.read_misses += m_stats_pw[type][status];
- } else if (type == GLOBAL_ACC_W) {
- t_css.write_misses += m_stats_pw[type][status];
+ if (status == MISS || status == SECTOR_MISS) {
+ if (type == GLOBAL_ACC_R || type == CONST_ACC_R ||
+ type == INST_ACC_R) {
+ t_css.read_misses += m_stats_pw.at(streamID)[type][status];
+ } else if (type == GLOBAL_ACC_W) {
+ t_css.write_misses += m_stats_pw.at(streamID)[type][status];
+ }
}
- }
- if (status == HIT_RESERVED) {
- if (type == GLOBAL_ACC_R || type == CONST_ACC_R || type == INST_ACC_R) {
- t_css.read_pending_hits += m_stats_pw[type][status];
- } else if (type == GLOBAL_ACC_W) {
- t_css.write_pending_hits += m_stats_pw[type][status];
+ if (status == HIT_RESERVED) {
+ if (type == GLOBAL_ACC_R || type == CONST_ACC_R ||
+ type == INST_ACC_R) {
+ t_css.read_pending_hits += m_stats_pw.at(streamID)[type][status];
+ } else if (type == GLOBAL_ACC_W) {
+ t_css.write_pending_hits += m_stats_pw.at(streamID)[type][status];
+ }
}
- }
- if (status == RESERVATION_FAIL) {
- if (type == GLOBAL_ACC_R || type == CONST_ACC_R || type == INST_ACC_R) {
- t_css.read_res_fails += m_stats_pw[type][status];
- } else if (type == GLOBAL_ACC_W) {
- t_css.write_res_fails += m_stats_pw[type][status];
+ if (status == RESERVATION_FAIL) {
+ if (type == GLOBAL_ACC_R || type == CONST_ACC_R ||
+ type == INST_ACC_R) {
+ t_css.read_res_fails += m_stats_pw.at(streamID)[type][status];
+ } else if (type == GLOBAL_ACC_W) {
+ t_css.write_res_fails += m_stats_pw.at(streamID)[type][status];
+ }
}
}
}
@@ -1139,6 +1293,50 @@ void baseline_cache::display_state(FILE *fp) const {
fprintf(fp, "\n");
}
+void baseline_cache::inc_aggregated_stats(cache_request_status status,
+ cache_request_status cache_status,
+ mem_fetch *mf,
+ enum cache_gpu_level level) {
+ if (level == L1_GPU_CACHE) {
+ m_gpu->aggregated_l1_stats.inc_stats(
+ mf->get_streamID(), mf->get_access_type(),
+ m_gpu->aggregated_l1_stats.select_stats_status(status, cache_status));
+ } else if (level == L2_GPU_CACHE) {
+ m_gpu->aggregated_l2_stats.inc_stats(
+ mf->get_streamID(), mf->get_access_type(),
+ m_gpu->aggregated_l2_stats.select_stats_status(status, cache_status));
+ }
+}
+
+void baseline_cache::inc_aggregated_fail_stats(
+ cache_request_status status, cache_request_status cache_status,
+ mem_fetch *mf, enum cache_gpu_level level) {
+ if (level == L1_GPU_CACHE) {
+ m_gpu->aggregated_l1_stats.inc_fail_stats(
+ mf->get_streamID(), mf->get_access_type(),
+ m_gpu->aggregated_l1_stats.select_stats_status(status, cache_status));
+ } else if (level == L2_GPU_CACHE) {
+ m_gpu->aggregated_l2_stats.inc_fail_stats(
+ mf->get_streamID(), mf->get_access_type(),
+ m_gpu->aggregated_l2_stats.select_stats_status(status, cache_status));
+ }
+}
+
+void baseline_cache::inc_aggregated_stats_pw(cache_request_status status,
+ cache_request_status cache_status,
+ mem_fetch *mf,
+ enum cache_gpu_level level) {
+ if (level == L1_GPU_CACHE) {
+ m_gpu->aggregated_l1_stats.inc_stats_pw(
+ mf->get_streamID(), mf->get_access_type(),
+ m_gpu->aggregated_l1_stats.select_stats_status(status, cache_status));
+ } else if (level == L2_GPU_CACHE) {
+ m_gpu->aggregated_l2_stats.inc_stats_pw(
+ mf->get_streamID(), mf->get_access_type(),
+ m_gpu->aggregated_l2_stats.select_stats_status(status, cache_status));
+ }
+}
+
/// Read miss handler without writeback
void baseline_cache::send_read_request(new_addr_type addr,
new_addr_type block_addr,
@@ -1170,7 +1368,7 @@ void baseline_cache::send_read_request(new_addr_type addr,
m_tag_array->access(block_addr, time, cache_index, wb, evicted, mf);
m_mshrs.add(mshr_addr, mf);
- m_stats.inc_stats(mf->get_access_type(), MSHR_HIT);
+ m_stats.inc_stats(mf->get_access_type(), MSHR_HIT, mf->get_streamID());
do_miss = true;
} else if (!mshr_hit && mshr_avail &&
@@ -1191,9 +1389,11 @@ void baseline_cache::send_read_request(new_addr_type addr,
do_miss = true;
} else if (mshr_hit && !mshr_avail)
- m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL,
+ mf->get_streamID());
else if (!mshr_hit && !mshr_avail)
- m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL,
+ mf->get_streamID());
else
assert(0);
}
@@ -1253,7 +1453,8 @@ cache_request_status data_cache::wr_hit_wt(new_addr_type addr,
std::list<cache_event> &events,
enum cache_request_status status) {
if (miss_queue_full(0)) {
- m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL,
+ mf->get_streamID());
return RESERVATION_FAIL; // cannot handle request this cycle
}
@@ -1281,7 +1482,8 @@ cache_request_status data_cache::wr_hit_we(new_addr_type addr,
std::list<cache_event> &events,
enum cache_request_status status) {
if (miss_queue_full(0)) {
- m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL,
+ mf->get_streamID());
return RESERVATION_FAIL; // cannot handle request this cycle
}
@@ -1330,11 +1532,14 @@ enum cache_request_status data_cache::wr_miss_wa_naive(
(m_miss_queue.size() < m_config.m_miss_queue_size)))) {
// check what is the exactly the failure reason
if (miss_queue_full(2))
- m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL,
+ mf->get_streamID());
else if (mshr_hit && !mshr_avail)
- m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL,
+ mf->get_streamID());
else if (!mshr_hit && !mshr_avail)
- m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL,
+ mf->get_streamID());
else
assert(0);
@@ -1353,10 +1558,10 @@ enum cache_request_status data_cache::wr_miss_wa_naive(
mf->get_access_warp_mask(), mf->get_access_byte_mask(),
mf->get_access_sector_mask(), m_gpu->gpgpu_ctx);
- mem_fetch *n_mf =
- new mem_fetch(*ma, NULL, mf->get_ctrl_size(), mf->get_wid(),
- mf->get_sid(), mf->get_tpc(), mf->get_mem_config(),
- m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle);
+ mem_fetch *n_mf = new mem_fetch(
+ *ma, NULL, mf->get_streamID(), mf->get_ctrl_size(), mf->get_wid(),
+ mf->get_sid(), mf->get_tpc(), mf->get_mem_config(),
+ m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle);
bool do_miss = false;
bool wb = false;
@@ -1378,7 +1583,7 @@ enum cache_request_status data_cache::wr_miss_wa_naive(
evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(),
evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size,
true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1,
- NULL);
+ NULL, mf->get_streamID());
// the evicted block may have wrong chip id when advanced L2 hashing is
// used, so set the right chip address from the original mf
wb->set_chip(mf->get_tlx_addr().chip);
@@ -1404,7 +1609,8 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write(
// reserve mshr
if (miss_queue_full(0)) {
- m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL,
+ mf->get_streamID());
return RESERVATION_FAIL; // cannot handle request this cycle
}
@@ -1431,7 +1637,7 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write(
evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(),
evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size,
true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1,
- NULL);
+ NULL, mf->get_streamID());
// the evicted block may have wrong chip id when advanced L2 hashing is
// used, so set the right chip address from the original mf
wb->set_chip(mf->get_tlx_addr().chip);
@@ -1451,11 +1657,14 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write(
(m_miss_queue.size() < m_config.m_miss_queue_size)))) {
// check what is the exactly the failure reason
if (miss_queue_full(1))
- m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL,
+ mf->get_streamID());
else if (mshr_hit && !mshr_avail)
- m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL,
+ mf->get_streamID());
else if (!mshr_hit && !mshr_avail)
- m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL,
+ mf->get_streamID());
else
assert(0);
@@ -1468,7 +1677,8 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write(
if (m_mshrs.probe(mshr_addr) &&
m_mshrs.is_read_after_write_pending(mshr_addr) && mf->is_write()) {
// assert(0);
- m_stats.inc_fail_stats(mf->get_access_type(), MSHR_RW_PENDING);
+ m_stats.inc_fail_stats(mf->get_access_type(), MSHR_RW_PENDING,
+ mf->get_streamID());
return RESERVATION_FAIL;
}
@@ -1479,8 +1689,8 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write(
mf->get_access_sector_mask(), m_gpu->gpgpu_ctx);
mem_fetch *n_mf = new mem_fetch(
- *ma, NULL, mf->get_ctrl_size(), mf->get_wid(), mf->get_sid(),
- mf->get_tpc(), mf->get_mem_config(),
+ *ma, NULL, mf->get_streamID(), mf->get_ctrl_size(), mf->get_wid(),
+ mf->get_sid(), mf->get_tpc(), mf->get_mem_config(),
m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, NULL, mf);
new_addr_type block_addr = m_config.block_addr(addr);
@@ -1504,7 +1714,7 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write(
evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(),
evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size,
true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1,
- NULL);
+ NULL, mf->get_streamID());
// the evicted block may have wrong chip id when advanced L2 hashing is
// used, so set the right chip address from the original mf
wb->set_chip(mf->get_tlx_addr().chip);
@@ -1528,7 +1738,8 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read(
// mshr
if (miss_queue_full(0)) {
- m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL,
+ mf->get_streamID());
return RESERVATION_FAIL; // cannot handle request this cycle
}
@@ -1571,7 +1782,7 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read(
evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(),
evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size,
true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1,
- NULL);
+ NULL, mf->get_streamID());
// the evicted block may have wrong chip id when advanced L2 hashing is
// used, so set the right chip address from the original mf
wb->set_chip(mf->get_tlx_addr().chip);
@@ -1589,7 +1800,8 @@ enum cache_request_status data_cache::wr_miss_no_wa(
new_addr_type addr, unsigned cache_index, mem_fetch *mf, unsigned time,
std::list<cache_event> &events, enum cache_request_status status) {
if (miss_queue_full(0)) {
- m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL,
+ mf->get_streamID());
return RESERVATION_FAIL; // cannot handle request this cycle
}
@@ -1634,7 +1846,8 @@ enum cache_request_status data_cache::rd_miss_base(
if (miss_queue_full(1)) {
// cannot handle request this cycle
// (might need to generate two requests)
- m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL,
+ mf->get_streamID());
return RESERVATION_FAIL;
}
@@ -1653,7 +1866,7 @@ enum cache_request_status data_cache::rd_miss_base(
evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(),
evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size,
true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1,
- NULL);
+ NULL, mf->get_streamID());
// the evicted block may have wrong chip id when advanced L2 hashing is
// used, so set the right chip address from the original mf
wb->set_chip(mf->get_tlx_addr().chip);
@@ -1693,16 +1906,20 @@ enum cache_request_status read_only_cache::access(
cache_status = RESERVATION_FAIL;
} else {
cache_status = RESERVATION_FAIL;
- m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL);
+ m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL,
+ mf->get_streamID());
}
} else {
- m_stats.inc_fail_stats(mf->get_access_type(), LINE_ALLOC_FAIL);
+ m_stats.inc_fail_stats(mf->get_access_type(), LINE_ALLOC_FAIL,
+ mf->get_streamID());
}
m_stats.inc_stats(mf->get_access_type(),
- m_stats.select_stats_status(status, cache_status));
+ m_stats.select_stats_status(status, cache_status),
+ mf->get_streamID());
m_stats.inc_stats_pw(mf->get_access_type(),
- m_stats.select_stats_status(status, cache_status));
+ m_stats.select_stats_status(status, cache_status),
+ mf->get_streamID());
return cache_status;
}
@@ -1730,7 +1947,8 @@ enum cache_request_status data_cache::process_tag_probe(
} else {
// the only reason for reservation fail here is LINE_ALLOC_FAIL (i.e all
// lines are reserved)
- m_stats.inc_fail_stats(mf->get_access_type(), LINE_ALLOC_FAIL);
+ m_stats.inc_fail_stats(mf->get_access_type(), LINE_ALLOC_FAIL,
+ mf->get_streamID());
}
} else { // Read
if (probe_status == HIT) {
@@ -1742,7 +1960,8 @@ enum cache_request_status data_cache::process_tag_probe(
} else {
// the only reason for reservation fail here is LINE_ALLOC_FAIL (i.e all
// lines are reserved)
- m_stats.inc_fail_stats(mf->get_access_type(), LINE_ALLOC_FAIL);
+ m_stats.inc_fail_stats(mf->get_access_type(), LINE_ALLOC_FAIL,
+ mf->get_streamID());
}
}
@@ -1767,9 +1986,11 @@ enum cache_request_status data_cache::access(new_addr_type addr, mem_fetch *mf,
enum cache_request_status access_status =
process_tag_probe(wr, probe_status, addr, cache_index, mf, time, events);
m_stats.inc_stats(mf->get_access_type(),
- m_stats.select_stats_status(probe_status, access_status));
- m_stats.inc_stats_pw(mf->get_access_type(), m_stats.select_stats_status(
- probe_status, access_status));
+ m_stats.select_stats_status(probe_status, access_status),
+ mf->get_streamID());
+ m_stats.inc_stats_pw(mf->get_access_type(),
+ m_stats.select_stats_status(probe_status, access_status),
+ mf->get_streamID());
return access_status;
}
@@ -1831,9 +2052,11 @@ enum cache_request_status tex_cache::access(new_addr_type addr, mem_fetch *mf,
cache_status = HIT_RESERVED;
}
m_stats.inc_stats(mf->get_access_type(),
- m_stats.select_stats_status(status, cache_status));
+ m_stats.select_stats_status(status, cache_status),
+ mf->get_streamID());
m_stats.inc_stats_pw(mf->get_access_type(),
- m_stats.select_stats_status(status, cache_status));
+ m_stats.select_stats_status(status, cache_status),
+ mf->get_streamID());
return cache_status;
}
diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h
index 5fd40a9..c07695f 100644
--- a/src/gpgpu-sim/gpu-cache.h
+++ b/src/gpgpu-sim/gpu-cache.h
@@ -72,6 +72,13 @@ enum cache_event_type {
WRITE_ALLOCATE_SENT
};
+enum cache_gpu_level {
+ L1_GPU_CACHE = 0,
+ L2_GPU_CACHE,
+ OTHER_GPU_CACHE,
+ NUM_CACHE_GPU_LEVELS
+};
+
struct evicted_block_info {
new_addr_type m_block_addr;
unsigned m_modified_size;
@@ -1200,20 +1207,26 @@ class cache_stats {
void clear();
// Clear AerialVision cache stats after each window
void clear_pw();
- void inc_stats(int access_type, int access_outcome);
+ void inc_stats(int access_type, int access_outcome,
+ unsigned long long streamID);
// Increment AerialVision cache stats
- void inc_stats_pw(int access_type, int access_outcome);
- void inc_fail_stats(int access_type, int fail_outcome);
+ void inc_stats_pw(int access_type, int access_outcome,
+ unsigned long long streamID);
+ void inc_fail_stats(int access_type, int fail_outcome,
+ unsigned long long streamID);
enum cache_request_status select_stats_status(
enum cache_request_status probe, enum cache_request_status access) const;
unsigned long long &operator()(int access_type, int access_outcome,
- bool fail_outcome);
+ bool fail_outcome,
+ unsigned long long streamID);
unsigned long long operator()(int access_type, int access_outcome,
- bool fail_outcome) const;
+ bool fail_outcome,
+ unsigned long long streamID) const;
cache_stats operator+(const cache_stats &cs);
cache_stats &operator+=(const cache_stats &cs);
- void print_stats(FILE *fout, const char *cache_name = "Cache_stats") const;
- void print_fail_stats(FILE *fout,
+ void print_stats(FILE *fout, unsigned long long streamID,
+ const char *cache_name = "Cache_stats") const;
+ void print_fail_stats(FILE *fout, unsigned long long streamID,
const char *cache_name = "Cache_fail_stats") const;
unsigned long long get_stats(enum mem_access_type *access_type,
@@ -1231,10 +1244,14 @@ class cache_stats {
bool check_valid(int type, int status) const;
bool check_fail_valid(int type, int fail) const;
- std::vector<std::vector<unsigned long long> > m_stats;
+ // CUDA streamID -> cache stats[NUM_MEM_ACCESS_TYPE]
+ std::map<unsigned long long, std::vector<std::vector<unsigned long long>>>
+ m_stats;
// AerialVision cache stats (per-window)
- std::vector<std::vector<unsigned long long> > m_stats_pw;
- std::vector<std::vector<unsigned long long> > m_fail_stats;
+ std::map<unsigned long long, std::vector<std::vector<unsigned long long>>>
+ m_stats_pw;
+ std::map<unsigned long long, std::vector<std::vector<unsigned long long>>>
+ m_fail_stats;
unsigned long long m_cache_port_available_cycles;
unsigned long long m_cache_data_port_busy_cycles;
@@ -1264,11 +1281,14 @@ class baseline_cache : public cache_t {
public:
baseline_cache(const char *name, cache_config &config, int core_id,
int type_id, mem_fetch_interface *memport,
- enum mem_fetch_status status)
+ enum mem_fetch_status status, enum cache_gpu_level level,
+ gpgpu_sim *gpu)
: m_config(config),
m_tag_array(new tag_array(config, core_id, type_id)),
m_mshrs(config.m_mshr_entries, config.m_mshr_max_merge),
- m_bandwidth_management(config) {
+ m_bandwidth_management(config),
+ m_level(level),
+ m_gpu(gpu) {
init(name, config, memport, status);
}
@@ -1336,6 +1356,15 @@ class baseline_cache : public cache_t {
bool fill_port_free() const {
return m_bandwidth_management.fill_port_free();
}
+ void inc_aggregated_stats(cache_request_status status,
+ cache_request_status cache_status, mem_fetch *mf,
+ enum cache_gpu_level level);
+ void inc_aggregated_fail_stats(cache_request_status status,
+ cache_request_status cache_status,
+ mem_fetch *mf, enum cache_gpu_level level);
+ void inc_aggregated_stats_pw(cache_request_status status,
+ cache_request_status cache_status, mem_fetch *mf,
+ enum cache_gpu_level level);
// This is a gapping hole we are poking in the system to quickly handle
// filling the cache on cudamemcopies. We don't care about anything other than
@@ -1367,6 +1396,8 @@ class baseline_cache : public cache_t {
std::list<mem_fetch *> m_miss_queue;
enum mem_fetch_status m_miss_queue_status;
mem_fetch_interface *m_memport;
+ cache_gpu_level m_level;
+ gpgpu_sim *m_gpu;
struct extra_mf_fields {
extra_mf_fields() { m_valid = false; }
@@ -1453,8 +1484,10 @@ class read_only_cache : public baseline_cache {
public:
read_only_cache(const char *name, cache_config &config, int core_id,
int type_id, mem_fetch_interface *memport,
- enum mem_fetch_status status)
- : baseline_cache(name, config, core_id, type_id, memport, status) {}
+ enum mem_fetch_status status, enum cache_gpu_level level,
+ gpgpu_sim *gpu)
+ : baseline_cache(name, config, core_id, type_id, memport, status, level,
+ gpu) {}
/// Access cache for read_only_cache: returns RESERVATION_FAIL if request
/// could not be accepted (for any reason)
@@ -1478,8 +1511,10 @@ class data_cache : public baseline_cache {
data_cache(const char *name, cache_config &config, int core_id, int type_id,
mem_fetch_interface *memport, mem_fetch_allocator *mfcreator,
enum mem_fetch_status status, mem_access_type wr_alloc_type,
- mem_access_type wrbk_type, class gpgpu_sim *gpu)
- : baseline_cache(name, config, core_id, type_id, memport, status) {
+ mem_access_type wrbk_type, class gpgpu_sim *gpu,
+ enum cache_gpu_level level)
+ : baseline_cache(name, config, core_id, type_id, memport, status, level,
+ gpu) {
init(mfcreator);
m_wr_alloc_type = wr_alloc_type;
m_wrbk_type = wrbk_type;
@@ -1668,9 +1703,10 @@ class l1_cache : public data_cache {
public:
l1_cache(const char *name, cache_config &config, int core_id, int type_id,
mem_fetch_interface *memport, mem_fetch_allocator *mfcreator,
- enum mem_fetch_status status, class gpgpu_sim *gpu)
+ enum mem_fetch_status status, class gpgpu_sim *gpu,
+ enum cache_gpu_level level)
: data_cache(name, config, core_id, type_id, memport, mfcreator, status,
- L1_WR_ALLOC_R, L1_WRBK_ACC, gpu) {}
+ L1_WR_ALLOC_R, L1_WRBK_ACC, gpu, level) {}
virtual ~l1_cache() {}
@@ -1693,9 +1729,10 @@ class l2_cache : public data_cache {
public:
l2_cache(const char *name, cache_config &config, int core_id, int type_id,
mem_fetch_interface *memport, mem_fetch_allocator *mfcreator,
- enum mem_fetch_status status, class gpgpu_sim *gpu)
+ enum mem_fetch_status status, class gpgpu_sim *gpu,
+ enum cache_gpu_level level)
: data_cache(name, config, core_id, type_id, memport, mfcreator, status,
- L2_WR_ALLOC_R, L2_WRBK_ACC, gpu) {}
+ L2_WR_ALLOC_R, L2_WRBK_ACC, gpu, level) {}
virtual ~l2_cache() {}
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index 1cb8a25..0c922bd 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -788,6 +788,22 @@ void increment_x_then_y_then_z(dim3 &i, const dim3 &bound) {
}
void gpgpu_sim::launch(kernel_info_t *kinfo) {
+ unsigned kernelID = kinfo->get_uid();
+ unsigned long long streamID = kinfo->get_streamID();
+
+ kernel_time_t kernel_time = {gpu_tot_sim_cycle + gpu_sim_cycle, 0};
+ if (gpu_kernel_time.find(streamID) == gpu_kernel_time.end()) {
+ std::map<unsigned, kernel_time_t> new_val;
+ new_val.insert(std::pair<unsigned, kernel_time_t>(kernelID, kernel_time));
+ gpu_kernel_time.insert(
+ std::pair<unsigned long long, std::map<unsigned, kernel_time_t>>(
+ streamID, new_val));
+ } else {
+ gpu_kernel_time.at(streamID).insert(
+ std::pair<unsigned, kernel_time_t>(kernelID, kernel_time));
+ ////////// assume same kernel ID do not appear more than once
+ }
+
unsigned cta_size = kinfo->threads_per_cta();
if (cta_size > m_shader_config->n_thread_per_shader) {
printf(
@@ -893,7 +909,10 @@ kernel_info_t *gpgpu_sim::select_kernel() {
}
unsigned gpgpu_sim::finished_kernel() {
- if (m_finished_kernel.empty()) return 0;
+ if (m_finished_kernel.empty()) {
+ last_streamID = -1;
+ return 0;
+ }
unsigned result = m_finished_kernel.front();
m_finished_kernel.pop_front();
return result;
@@ -901,6 +920,11 @@ unsigned gpgpu_sim::finished_kernel() {
void gpgpu_sim::set_kernel_done(kernel_info_t *kernel) {
unsigned uid = kernel->get_uid();
+ last_uid = uid;
+ unsigned long long streamID = kernel->get_streamID();
+ last_streamID = streamID;
+ gpu_kernel_time.at(streamID).at(uid).end_cycle =
+ gpu_tot_sim_cycle + gpu_sim_cycle;
m_finished_kernel.push_back(uid);
std::vector<kernel_info_t *>::iterator k;
for (k = m_running_kernels.begin(); k != m_running_kernels.end(); k++) {
@@ -971,6 +995,9 @@ gpgpu_sim::gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx)
gpu_tot_sim_cycle_parition_util = 0;
partiton_replys_in_parallel = 0;
partiton_replys_in_parallel_total = 0;
+ last_streamID = -1;
+
+ gpu_kernel_time.clear();
m_memory_partition_unit =
new memory_partition_unit *[m_memory_config->m_n_mem];
@@ -1178,9 +1205,9 @@ PowerscalingCoefficients *gpgpu_sim::get_scaling_coeffs() {
return m_gpgpusim_wrapper->get_scaling_coeffs();
}
-void gpgpu_sim::print_stats() {
+void gpgpu_sim::print_stats(unsigned long long streamID) {
gpgpu_ctx->stats->ptx_file_line_stats_write_file();
- gpu_print_stat();
+ gpu_print_stat(streamID);
if (g_network_mode) {
printf(
@@ -1363,12 +1390,15 @@ void gpgpu_sim::clear_executed_kernel_info() {
m_executed_kernel_names.clear();
m_executed_kernel_uids.clear();
}
-void gpgpu_sim::gpu_print_stat() {
+
+void gpgpu_sim::gpu_print_stat(unsigned long long streamID) {
FILE *statfout = stdout;
std::string kernel_info_str = executed_kernel_info_string();
fprintf(statfout, "%s", kernel_info_str.c_str());
+ printf("kernel_stream_id = %llu\n", streamID);
+
printf("gpu_sim_cycle = %lld\n", gpu_sim_cycle);
printf("gpu_sim_insn = %lld\n", gpu_sim_insn);
printf("gpu_ipc = %12.4f\n", (float)gpu_sim_insn / gpu_sim_cycle);
@@ -1440,9 +1470,10 @@ void gpgpu_sim::gpu_print_stat() {
m_cluster[i]->get_cache_stats(core_cache_stats);
}
printf("\nTotal_core_cache_stats:\n");
- core_cache_stats.print_stats(stdout, "Total_core_cache_stats_breakdown");
+ core_cache_stats.print_stats(stdout, streamID,
+ "Total_core_cache_stats_breakdown");
printf("\nTotal_core_cache_fail_stats:\n");
- core_cache_stats.print_fail_stats(stdout,
+ core_cache_stats.print_fail_stats(stdout, streamID,
"Total_core_cache_fail_stats_breakdown");
shader_print_scheduler_stat(stdout, false);
@@ -1510,9 +1541,10 @@ void gpgpu_sim::gpu_print_stat() {
printf("L2_total_cache_reservation_fails = %llu\n",
total_l2_css.res_fails);
printf("L2_total_cache_breakdown:\n");
- l2_stats.print_stats(stdout, "L2_cache_stats_breakdown");
+ l2_stats.print_stats(stdout, streamID, "L2_cache_stats_breakdown");
printf("L2_total_cache_reservation_fail_breakdown:\n");
- l2_stats.print_fail_stats(stdout, "L2_cache_stats_fail_breakdown");
+ l2_stats.print_fail_stats(stdout, streamID,
+ "L2_cache_stats_fail_breakdown");
total_l2_css.print_port_stats(stdout, "L2_cache");
}
}
@@ -1955,8 +1987,10 @@ void gpgpu_sim::cycle() {
if (mf) partiton_reqs_in_parallel_per_cycle++;
}
m_memory_sub_partition[i]->cache_cycle(gpu_sim_cycle + gpu_tot_sim_cycle);
- m_memory_sub_partition[i]->accumulate_L2cache_stats(
- m_power_stats->pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX]);
+ if (m_config.g_power_simulation_enabled) {
+ m_memory_sub_partition[i]->accumulate_L2cache_stats(
+ m_power_stats->pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX]);
+ }
}
}
partiton_reqs_in_parallel += partiton_reqs_in_parallel_per_cycle;
@@ -1978,14 +2012,16 @@ void gpgpu_sim::cycle() {
*active_sms += m_cluster[i]->get_n_active_sms();
}
// Update core icnt/cache stats for AccelWattch
- m_cluster[i]->get_icnt_stats(
- m_power_stats->pwr_mem_stat->n_simt_to_mem[CURRENT_STAT_IDX][i],
- m_power_stats->pwr_mem_stat->n_mem_to_simt[CURRENT_STAT_IDX][i]);
- m_cluster[i]->get_cache_stats(
- m_power_stats->pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX]);
- m_cluster[i]->get_current_occupancy(
- gpu_occupancy.aggregate_warp_slot_filled,
- gpu_occupancy.aggregate_theoretical_warp_slots);
+ if (m_config.g_power_simulation_enabled) {
+ m_cluster[i]->get_icnt_stats(
+ m_power_stats->pwr_mem_stat->n_simt_to_mem[CURRENT_STAT_IDX][i],
+ m_power_stats->pwr_mem_stat->n_mem_to_simt[CURRENT_STAT_IDX][i]);
+ m_cluster[i]->get_cache_stats(
+ m_power_stats->pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX]);
+ m_cluster[i]->get_current_occupancy(
+ gpu_occupancy.aggregate_warp_slot_filled,
+ gpu_occupancy.aggregate_theoretical_warp_slots);
+ }
}
float temp = 0;
for (unsigned i = 0; i < m_shader_config->num_shader(); i++) {
diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h
index d43b399..8e81451 100644
--- a/src/gpgpu-sim/gpu-sim.h
+++ b/src/gpgpu-sim/gpu-sim.h
@@ -539,7 +539,7 @@ class gpgpu_sim : public gpgpu_t {
(m_config.gpu_max_completed_cta_opt &&
(gpu_completed_cta >= m_config.gpu_max_completed_cta_opt));
}
- void print_stats();
+ void print_stats(unsigned long long streamID);
void update_stats();
void deadlock_check();
void inc_completed_cta() { gpu_completed_cta++; }
@@ -568,7 +568,7 @@ class gpgpu_sim : public gpgpu_t {
void decrement_kernel_latency();
const gpgpu_sim_config &get_config() const { return m_config; }
- void gpu_print_stat();
+ void gpu_print_stat(unsigned long long streamID);
void dump_pipeline(int mask, int s, int m) const;
void perf_memcpy_to_gpu(size_t dst_start_addr, size_t count);
@@ -685,6 +685,17 @@ class gpgpu_sim : public gpgpu_t {
occupancy_stats gpu_occupancy;
occupancy_stats gpu_tot_occupancy;
+ typedef struct {
+ unsigned long long start_cycle;
+ unsigned long long end_cycle;
+ } kernel_time_t;
+ std::map<unsigned long long, std::map<unsigned, kernel_time_t>>
+ gpu_kernel_time;
+ unsigned long long last_streamID;
+ unsigned long long last_uid;
+ cache_stats aggregated_l1_stats;
+ cache_stats aggregated_l2_stats;
+
// performance counter for stalls due to congestion.
unsigned int gpu_stall_dramfull;
unsigned int gpu_stall_icnt2sh;
@@ -712,6 +723,9 @@ class gpgpu_sim : public gpgpu_t {
public:
bool is_functional_sim() { return m_functional_sim; }
kernel_info_t *get_functional_kernel() { return m_functional_sim_kernel; }
+ std::vector<kernel_info_t *> get_running_kernels() {
+ return m_running_kernels;
+ }
void functional_launch(kernel_info_t *k) {
m_functional_sim = true;
m_functional_sim_kernel = k;
diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc
index 8469453..52eed0e 100644
--- a/src/gpgpu-sim/l2cache.cc
+++ b/src/gpgpu-sim/l2cache.cc
@@ -51,12 +51,12 @@
mem_fetch *partition_mf_allocator::alloc(new_addr_type addr,
mem_access_type type, unsigned size,
- bool wr,
- unsigned long long cycle) const {
+ bool wr, unsigned long long cycle,
+ unsigned long long streamID) const {
assert(wr);
mem_access_t access(type, addr, size, wr, m_memory_config->gpgpu_ctx);
- mem_fetch *mf = new mem_fetch(access, NULL, WRITE_PACKET_SIZE, -1, -1, -1,
- m_memory_config, cycle);
+ mem_fetch *mf = new mem_fetch(access, NULL, streamID, WRITE_PACKET_SIZE, -1,
+ -1, -1, m_memory_config, cycle);
return mf;
}
@@ -65,12 +65,12 @@ mem_fetch *partition_mf_allocator::alloc(
const mem_access_byte_mask_t &byte_mask,
const mem_access_sector_mask_t &sector_mask, unsigned size, bool wr,
unsigned long long cycle, unsigned wid, unsigned sid, unsigned tpc,
- mem_fetch *original_mf) const {
+ mem_fetch *original_mf, unsigned long long streamID) const {
mem_access_t access(type, addr, size, wr, active_mask, byte_mask, sector_mask,
m_memory_config->gpgpu_ctx);
- mem_fetch *mf =
- new mem_fetch(access, NULL, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE,
- wid, sid, tpc, m_memory_config, cycle, original_mf);
+ mem_fetch *mf = new mem_fetch(access, NULL, streamID,
+ wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, wid,
+ sid, tpc, m_memory_config, cycle, original_mf);
return mf;
}
memory_partition_unit::memory_partition_unit(unsigned partition_id,
@@ -436,9 +436,9 @@ memory_sub_partition::memory_sub_partition(unsigned sub_partition_id,
m_mf_allocator = new partition_mf_allocator(config);
if (!m_config->m_L2_config.disabled())
- m_L2cache =
- new l2_cache(L2c_name, m_config->m_L2_config, -1, -1, m_L2interface,
- m_mf_allocator, IN_PARTITION_L2_MISS_QUEUE, gpu);
+ m_L2cache = new l2_cache(L2c_name, m_config->m_L2_config, -1, -1,
+ m_L2interface, m_mf_allocator,
+ IN_PARTITION_L2_MISS_QUEUE, gpu, L2_GPU_CACHE);
unsigned int icnt_L2;
unsigned int L2_dram;
@@ -733,7 +733,7 @@ memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch *mf) {
mf->get_access_warp_mask(), mf->get_access_byte_mask() & mask,
std::bitset<SECTOR_CHUNCK_SIZE>().set(i), SECTOR_SIZE, mf->is_write(),
m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, mf->get_wid(),
- mf->get_sid(), mf->get_tpc(), mf);
+ mf->get_sid(), mf->get_tpc(), mf, mf->get_streamID());
result.push_back(n_mf);
}
@@ -756,7 +756,7 @@ memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch *mf) {
mf->get_access_byte_mask() & mask,
std::bitset<SECTOR_CHUNCK_SIZE>().set(i), SECTOR_SIZE, mf->is_write(),
m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, mf->get_wid(),
- mf->get_sid(), mf->get_tpc(), mf);
+ mf->get_sid(), mf->get_tpc(), mf, mf->get_streamID());
result.push_back(n_mf);
}
@@ -772,7 +772,8 @@ memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch *mf) {
mf->get_access_warp_mask(), mf->get_access_byte_mask() & mask,
std::bitset<SECTOR_CHUNCK_SIZE>().set(i), SECTOR_SIZE,
mf->is_write(), m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle,
- mf->get_wid(), mf->get_sid(), mf->get_tpc(), mf);
+ mf->get_wid(), mf->get_sid(), mf->get_tpc(), mf,
+ mf->get_streamID());
result.push_back(n_mf);
}
diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h
index ccf9b70..65c9c38 100644
--- a/src/gpgpu-sim/l2cache.h
+++ b/src/gpgpu-sim/l2cache.h
@@ -52,15 +52,16 @@ class partition_mf_allocator : public mem_fetch_allocator {
return NULL;
}
virtual mem_fetch *alloc(new_addr_type addr, mem_access_type type,
- unsigned size, bool wr,
- unsigned long long cycle) const;
+ unsigned size, bool wr, unsigned long long cycle,
+ unsigned long long streamID) const;
virtual mem_fetch *alloc(new_addr_type addr, mem_access_type type,
const active_mask_t &active_mask,
const mem_access_byte_mask_t &byte_mask,
const mem_access_sector_mask_t &sector_mask,
unsigned size, bool wr, unsigned long long cycle,
unsigned wid, unsigned sid, unsigned tpc,
- mem_fetch *original_mf) const;
+ mem_fetch *original_mf,
+ unsigned long long streamID) const;
private:
const memory_config *m_memory_config;
diff --git a/src/gpgpu-sim/mem_fetch.cc b/src/gpgpu-sim/mem_fetch.cc
index 0d86046..7211a7d 100644
--- a/src/gpgpu-sim/mem_fetch.cc
+++ b/src/gpgpu-sim/mem_fetch.cc
@@ -35,10 +35,10 @@
unsigned mem_fetch::sm_next_mf_request_uid = 1;
mem_fetch::mem_fetch(const mem_access_t &access, const warp_inst_t *inst,
- unsigned ctrl_size, unsigned wid, unsigned sid,
- unsigned tpc, const memory_config *config,
- unsigned long long cycle, mem_fetch *m_original_mf,
- mem_fetch *m_original_wr_mf)
+ unsigned long long streamID, unsigned ctrl_size,
+ unsigned wid, unsigned sid, unsigned tpc,
+ const memory_config *config, unsigned long long cycle,
+ mem_fetch *m_original_mf, mem_fetch *m_original_wr_mf)
: m_access(access)
{
@@ -48,6 +48,7 @@ mem_fetch::mem_fetch(const mem_access_t &access, const warp_inst_t *inst,
m_inst = *inst;
assert(wid == m_inst.warp_id());
}
+ m_streamID = streamID;
m_data_size = access.get_size();
m_ctrl_size = ctrl_size;
m_sid = sid;
diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h
index 283fe80..7704218 100644
--- a/src/gpgpu-sim/mem_fetch.h
+++ b/src/gpgpu-sim/mem_fetch.h
@@ -54,9 +54,10 @@ class memory_config;
class mem_fetch {
public:
mem_fetch(const mem_access_t &access, const warp_inst_t *inst,
- unsigned ctrl_size, unsigned wid, unsigned sid, unsigned tpc,
- const memory_config *config, unsigned long long cycle,
- mem_fetch *original_mf = NULL, mem_fetch *original_wr_mf = NULL);
+ unsigned long long streamID, unsigned ctrl_size, unsigned wid,
+ unsigned sid, unsigned tpc, const memory_config *config,
+ unsigned long long cycle, mem_fetch *original_mf = NULL,
+ mem_fetch *original_wr_mf = NULL);
~mem_fetch();
void set_status(enum mem_fetch_status status, unsigned long long cycle);
@@ -105,6 +106,7 @@ class mem_fetch {
unsigned get_timestamp() const { return m_timestamp; }
unsigned get_return_timestamp() const { return m_timestamp2; }
unsigned get_icnt_receive_time() const { return m_icnt_receive_time; }
+ unsigned long long get_streamID() const { return m_streamID; }
enum mem_access_type get_access_type() const { return m_access.get_type(); }
const active_mask_t &get_access_warp_mask() const {
@@ -163,6 +165,8 @@ class mem_fetch {
// requesting instruction (put last so mem_fetch prints nicer in gdb)
warp_inst_t m_inst;
+ unsigned long long m_streamID;
+
static unsigned sm_next_mf_request_uid;
const memory_config *m_mem_config;
diff --git a/src/gpgpu-sim/power_stat.cc b/src/gpgpu-sim/power_stat.cc
index dead4a0..764652b 100644
--- a/src/gpgpu-sim/power_stat.cc
+++ b/src/gpgpu-sim/power_stat.cc
@@ -181,11 +181,11 @@ void power_mem_stat_t::print(FILE *fout) const {
total_mem_reads + total_mem_writes);
fprintf(fout, "Total memory controller reads: %u\n", total_mem_reads);
fprintf(fout, "Total memory controller writes: %u\n", total_mem_writes);
-
+ // TODO: print_stats(require stream ID input)
fprintf(fout, "Core cache stats:\n");
- core_cache_stats->print_stats(fout);
+ core_cache_stats->print_stats(fout, -1);
fprintf(fout, "L2 cache stats:\n");
- l2_cache_stats->print_stats(fout);
+ l2_cache_stats->print_stats(fout, -1);
}
power_core_stat_t::power_core_stat_t(const shader_core_config *shader_config,
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 9fe4c09..4d4f112 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -57,11 +57,11 @@
mem_fetch *shader_core_mem_fetch_allocator::alloc(
new_addr_type addr, mem_access_type type, unsigned size, bool wr,
- unsigned long long cycle) const {
+ unsigned long long cycle, unsigned long long streamID) const {
mem_access_t access(type, addr, size, wr, m_memory_config->gpgpu_ctx);
- mem_fetch *mf =
- new mem_fetch(access, NULL, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, -1,
- m_core_id, m_cluster_id, m_memory_config, cycle);
+ mem_fetch *mf = new mem_fetch(
+ access, NULL, streamID, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, -1,
+ m_core_id, m_cluster_id, m_memory_config, cycle);
return mf;
}
@@ -70,12 +70,12 @@ mem_fetch *shader_core_mem_fetch_allocator::alloc(
const mem_access_byte_mask_t &byte_mask,
const mem_access_sector_mask_t &sector_mask, unsigned size, bool wr,
unsigned long long cycle, unsigned wid, unsigned sid, unsigned tpc,
- mem_fetch *original_mf) const {
+ mem_fetch *original_mf, unsigned long long streamID) const {
mem_access_t access(type, addr, size, wr, active_mask, byte_mask, sector_mask,
m_memory_config->gpgpu_ctx);
mem_fetch *mf = new mem_fetch(
- access, NULL, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, wid, m_core_id,
- m_cluster_id, m_memory_config, cycle, original_mf);
+ access, NULL, streamID, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, wid,
+ m_core_id, m_cluster_id, m_memory_config, cycle, original_mf);
return mf;
}
/////////////////////////////////////////////////////////////////////////////
@@ -178,7 +178,7 @@ void shader_core_ctx::create_front_pipeline() {
snprintf(name, STRSIZE, "L1I_%03d", m_sid);
m_L1I = new read_only_cache(name, m_config->m_L1I_config, m_sid,
get_shader_instruction_cache_id(), m_icnt,
- IN_L1I_MISS_QUEUE);
+ IN_L1I_MISS_QUEUE, OTHER_GPU_CACHE, m_gpu);
}
void shader_core_ctx::create_schedulers() {
@@ -447,7 +447,7 @@ void shader_core_ctx::create_exec_pipeline() {
m_ldst_unit = new ldst_unit(m_icnt, m_mem_fetch_allocator, this,
&m_operand_collector, m_scoreboard, m_config,
- m_memory_config, m_stats, m_sid, m_tpc);
+ m_memory_config, m_stats, m_sid, m_tpc, m_gpu);
m_fu.push_back(m_ldst_unit);
m_dispatch_port.push_back(ID_OC_MEM);
m_issue_port.push_back(OC_EX_MEM);
@@ -567,7 +567,8 @@ void shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread,
start_pc = pc;
}
- m_warp[i]->init(start_pc, cta_id, i, active_threads, m_dynamic_warp_id);
+ m_warp[i]->init(start_pc, cta_id, i, active_threads, m_dynamic_warp_id,
+ kernel.get_streamID());
++m_dynamic_warp_id;
m_not_completed += n_active;
++m_active_warps;
@@ -985,8 +986,8 @@ void shader_core_ctx::fetch() {
// mem_fetch *mf = m_mem_fetch_allocator->alloc()
mem_access_t acc(INST_ACC_R, ppc, nbytes, false, m_gpu->gpgpu_ctx);
mem_fetch *mf = new mem_fetch(
- acc, NULL /*we don't have an instruction yet*/, READ_PACKET_SIZE,
- warp_id, m_sid, m_tpc, m_memory_config,
+ acc, NULL, m_warp[warp_id]->get_kernel_info()->get_streamID(),
+ READ_PACKET_SIZE, warp_id, m_sid, m_tpc, m_memory_config,
m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle);
std::list<cache_event> events;
enum cache_request_status status;
@@ -1040,10 +1041,10 @@ void shader_core_ctx::issue_warp(register_set &pipe_reg_set,
m_warp[warp_id]->ibuffer_free();
assert(next_inst->valid());
**pipe_reg = *next_inst; // static instruction information
- (*pipe_reg)->issue(active_mask, warp_id,
- m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle,
- m_warp[warp_id]->get_dynamic_warp_id(),
- sch_id); // dynamic instruction information
+ (*pipe_reg)->issue(
+ active_mask, warp_id, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle,
+ m_warp[warp_id]->get_dynamic_warp_id(), sch_id,
+ m_warp[warp_id]->get_streamID()); // dynamic instruction information
m_stats->shader_cycle_distro[2 + (*pipe_reg)->active_count()]++;
func_exec_inst(**pipe_reg);
@@ -2597,7 +2598,7 @@ void ldst_unit::init(mem_fetch_interface *icnt,
IN_SHADER_L1T_ROB);
m_L1C = new read_only_cache(L1C_name, m_config->m_L1C_config, m_sid,
get_shader_constant_cache_id(), icnt,
- IN_L1C_MISS_QUEUE);
+ IN_L1C_MISS_QUEUE, OTHER_GPU_CACHE, m_gpu);
m_L1D = NULL;
m_mem_rc = NO_RC_FAIL;
m_num_writeback_clients =
@@ -2613,9 +2614,10 @@ ldst_unit::ldst_unit(mem_fetch_interface *icnt,
shader_core_ctx *core, opndcoll_rfu_t *operand_collector,
Scoreboard *scoreboard, const shader_core_config *config,
const memory_config *mem_config, shader_core_stats *stats,
- unsigned sid, unsigned tpc)
+ unsigned sid, unsigned tpc, gpgpu_sim *gpu)
: pipelined_simd_unit(NULL, config, config->smem_latency, core, 0),
- m_next_wb(config) {
+ m_next_wb(config),
+ m_gpu(gpu) {
assert(config->smem_latency > 1);
init(icnt, mf_allocator, core, operand_collector, scoreboard, config,
mem_config, stats, sid, tpc);
@@ -2624,7 +2626,7 @@ ldst_unit::ldst_unit(mem_fetch_interface *icnt,
snprintf(L1D_name, STRSIZE, "L1D_%03d", m_sid);
m_L1D = new l1_cache(L1D_name, m_config->m_L1D_config, m_sid,
get_shader_normal_cache_id(), m_icnt, m_mf_allocator,
- IN_L1D_MISS_QUEUE, core->get_gpu());
+ IN_L1D_MISS_QUEUE, core->get_gpu(), L1_GPU_CACHE);
l1_latency_queue.resize(m_config->m_L1D_config.l1_banks);
assert(m_config->m_L1D_config.l1_latency > 0);
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index 92691d3..e658a14 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -120,6 +120,7 @@ class shd_warp_t {
m_done_exit = true;
m_last_fetch = 0;
m_next = 0;
+ m_streamID = (unsigned long long)-1;
// Jin: cdp support
m_cdp_latency = 0;
@@ -140,8 +141,9 @@ class shd_warp_t {
m_ldgdepbar_buf.clear();
}
void init(address_type start_pc, unsigned cta_id, unsigned wid,
- const std::bitset<MAX_WARP_SIZE> &active,
- unsigned dynamic_warp_id) {
+ const std::bitset<MAX_WARP_SIZE> &active, unsigned dynamic_warp_id,
+ unsigned long long streamID) {
+ m_streamID = streamID;
m_cta_id = cta_id;
m_warp_id = wid;
m_dynamic_warp_id = dynamic_warp_id;
@@ -265,6 +267,7 @@ class shd_warp_t {
m_inst_in_pipeline--;
}
+ unsigned long long get_streamID() const { return m_streamID; }
unsigned get_cta_id() const { return m_cta_id; }
unsigned get_dynamic_warp_id() const { return m_dynamic_warp_id; }
@@ -277,6 +280,7 @@ class shd_warp_t {
private:
static const unsigned IBUFFER_SIZE = 2;
class shader_core_ctx *m_shader;
+ unsigned long long m_streamID;
unsigned m_cta_id;
unsigned m_warp_id;
unsigned m_warp_size;
@@ -1345,7 +1349,7 @@ class ldst_unit : public pipelined_simd_unit {
shader_core_ctx *core, opndcoll_rfu_t *operand_collector,
Scoreboard *scoreboard, const shader_core_config *config,
const memory_config *mem_config, class shader_core_stats *stats,
- unsigned sid, unsigned tpc);
+ unsigned sid, unsigned tpc, gpgpu_sim *gpu);
// Add a structure to record the LDGSTS instructions,
// similar to m_pending_writes, but since LDGSTS does not have a output
@@ -1435,6 +1439,7 @@ class ldst_unit : public pipelined_simd_unit {
warp_inst_t &inst);
mem_stage_stall_type process_memory_access_queue_l1cache(l1_cache *cache,
warp_inst_t &inst);
+ gpgpu_sim *m_gpu;
const memory_config *m_memory_config;
class mem_fetch_interface *m_icnt;
@@ -2025,18 +2030,20 @@ class shader_core_mem_fetch_allocator : public mem_fetch_allocator {
m_memory_config = config;
}
mem_fetch *alloc(new_addr_type addr, mem_access_type type, unsigned size,
- bool wr, unsigned long long cycle) const;
+ bool wr, unsigned long long cycle,
+ unsigned long long streamID) const;
mem_fetch *alloc(new_addr_type addr, mem_access_type type,
const active_mask_t &active_mask,
const mem_access_byte_mask_t &byte_mask,
const mem_access_sector_mask_t &sector_mask, unsigned size,
bool wr, unsigned long long cycle, unsigned wid,
- unsigned sid, unsigned tpc, mem_fetch *original_mf) const;
+ unsigned sid, unsigned tpc, mem_fetch *original_mf,
+ unsigned long long streamID) const;
mem_fetch *alloc(const warp_inst_t &inst, const mem_access_t &access,
unsigned long long cycle) const {
warp_inst_t inst_copy = inst;
mem_fetch *mf = new mem_fetch(
- access, &inst_copy,
+ access, &inst_copy, inst.get_streamID(),
access.is_write() ? WRITE_PACKET_SIZE : READ_PACKET_SIZE,
inst.warp_id(), m_core_id, m_cluster_id, m_memory_config, cycle);
return mf;
diff --git a/src/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc
index f4287d8..42c6981 100644
--- a/src/gpgpusim_entrypoint.cc
+++ b/src/gpgpusim_entrypoint.cc
@@ -57,7 +57,8 @@ void *gpgpu_sim_thread_sequential(void *ctx_ptr) {
ctx->the_gpgpusim->g_the_gpu->cycle();
ctx->the_gpgpusim->g_the_gpu->deadlock_check();
}
- ctx->the_gpgpusim->g_the_gpu->print_stats();
+ ctx->the_gpgpusim->g_the_gpu->print_stats(
+ ctx->the_gpgpusim->g_the_gpu->last_streamID);
ctx->the_gpgpusim->g_the_gpu->update_stats();
ctx->print_simulation_time();
}
@@ -144,7 +145,8 @@ void *gpgpu_sim_thread_concurrent(void *ctx_ptr) {
fflush(stdout);
}
if (sim_cycles) {
- ctx->the_gpgpusim->g_the_gpu->print_stats();
+ ctx->the_gpgpusim->g_the_gpu->print_stats(
+ ctx->the_gpgpusim->g_the_gpu->last_streamID);
ctx->the_gpgpusim->g_the_gpu->update_stats();
ctx->print_simulation_time();
}
diff --git a/src/stream_manager.cc b/src/stream_manager.cc
index 0ce3c6a..72f8bb0 100644
--- a/src/stream_manager.cc
+++ b/src/stream_manager.cc
@@ -302,6 +302,14 @@ bool stream_manager::register_finished_kernel(unsigned grid_uid) {
void stream_manager::stop_all_running_kernels() {
pthread_mutex_lock(&m_lock);
+ std::vector<unsigned long long> finished_streams;
+ std::vector<kernel_info_t *> running_kernels = m_gpu->get_running_kernels();
+ for (kernel_info_t *k : running_kernels) {
+ if (k != NULL) {
+ finished_streams.push_back(k->get_streamID());
+ }
+ }
+
// Signal m_gpu to stop all running kernels
m_gpu->stop_all_running_kernels();
@@ -312,7 +320,9 @@ void stream_manager::stop_all_running_kernels() {
}
// If any kernels completed, print out the current stats
- if (count > 0) m_gpu->print_stats();
+ for (unsigned long long streamID : finished_streams) {
+ m_gpu->print_stats(streamID);
+ }
pthread_mutex_unlock(&m_lock);
}