summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/gpu-cache.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim/gpu-cache.cc')
-rw-r--r--src/gpgpu-sim/gpu-cache.cc581
1 files changed, 407 insertions, 174 deletions
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc
index a2aeec5..0ea9ff6 100644
--- a/src/gpgpu-sim/gpu-cache.cc
+++ b/src/gpgpu-sim/gpu-cache.cc
@@ -1,16 +1,19 @@
-// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington,
+// Vijay Kandiah, Nikos Hardavellas, Mahmoud Khairy, Junrui Pan,
+// Timothy G. Rogers
+// The University of British Columbia, Northwestern University, Purdue
+// University All rights reserved.
//
// 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
+// 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 names of The University of British Columbia, Northwestern
+// 3. Neither the names of The University of British Columbia, Northwestern
// University nor the names of their contributors may be used to
// endorse or promote products derived from this software without specific
// prior written permission.
@@ -285,10 +288,11 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx,
// number of dirty lines / total lines in the cache
float dirty_line_percentage =
((float)m_dirty / (m_config.m_nset * m_config.m_assoc)) * 100;
- // If the cacheline is from a load op (not modified),
+ // If the cacheline is from a load op (not modified),
// or the total dirty cacheline is above a specific value,
- // Then this cacheline is eligible to be considered for replacement candidate
- // i.e. Only evict clean cachelines until total dirty cachelines reach the limit.
+ // Then this cacheline is eligible to be considered for replacement
+ // candidate i.e. Only evict clean cachelines until total dirty cachelines
+ // reach the limit.
if (!line->is_modified_line() ||
dirty_line_percentage >= m_config.m_wr_percent) {
all_reserved = false;
@@ -407,6 +411,11 @@ void tag_array::fill(new_addr_type addr, unsigned time,
// assert( m_config.m_alloc_policy == ON_FILL );
unsigned idx;
enum cache_request_status status = probe(addr, idx, mask, is_write);
+
+ if (status == RESERVATION_FAIL) {
+ return;
+ }
+
bool before = m_lines[idx]->is_modified_line();
// assert(status==MISS||status==SECTOR_MISS); // MSHR should have prevented
// redundant memory request
@@ -430,7 +439,8 @@ void tag_array::fill(new_addr_type addr, unsigned time,
void tag_array::fill(unsigned index, unsigned time, mem_fetch *mf) {
assert(m_config.m_alloc_policy == ON_MISS);
bool before = m_lines[index]->is_modified_line();
- m_lines[index]->fill(time, mf->get_access_sector_mask(), mf->get_access_byte_mask());
+ m_lines[index]->fill(time, mf->get_access_sector_mask(),
+ mf->get_access_byte_mask());
if (m_lines[index]->is_modified_line() && !before) {
m_dirty++;
}
@@ -624,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;
@@ -641,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;
@@ -655,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(
@@ -702,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
@@ -712,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.
///
@@ -730,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];
}
}
@@ -744,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 =
@@ -768,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;
@@ -786,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]);
+ }
}
}
}
@@ -856,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;
@@ -873,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];
+ }
}
}
@@ -902,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];
+ }
}
}
}
@@ -1129,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,
@@ -1160,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 &&
@@ -1181,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);
}
@@ -1203,15 +1413,14 @@ void data_cache::update_m_readable(mem_fetch *mf, unsigned cache_index) {
if (mf->get_access_sector_mask().test(i)) {
bool all_set = true;
for (unsigned k = i * SECTOR_SIZE; k < (i + 1) * SECTOR_SIZE; k++) {
- // If any bit in the byte mask (within the sector) is not set,
+ // If any bit in the byte mask (within the sector) is not set,
// the sector is unreadble
if (!block->get_dirty_byte_mask().test(k)) {
all_set = false;
break;
}
}
- if (all_set)
- block->set_m_readable(true, mf->get_access_sector_mask());
+ if (all_set) block->set_m_readable(true, mf->get_access_sector_mask());
}
}
}
@@ -1232,7 +1441,7 @@ cache_request_status data_cache::wr_hit_wb(new_addr_type addr,
}
block->set_status(MODIFIED, mf->get_access_sector_mask());
block->set_byte_mask(mf);
- update_m_readable(mf,cache_index);
+ update_m_readable(mf, cache_index);
return HIT;
}
@@ -1244,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
}
@@ -1256,7 +1466,7 @@ cache_request_status data_cache::wr_hit_wt(new_addr_type addr,
}
block->set_status(MODIFIED, mf->get_access_sector_mask());
block->set_byte_mask(mf);
- update_m_readable(mf,cache_index);
+ update_m_readable(mf, cache_index);
// generate a write-through
send_write_request(mf, cache_event(WRITE_REQUEST_SENT), time, events);
@@ -1272,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
}
@@ -1321,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);
@@ -1344,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;
@@ -1369,11 +1583,11 @@ 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);
- wb->set_parition(mf->get_tlx_addr().sub_partition);
+ wb->set_partition(mf->get_tlx_addr().sub_partition);
send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted),
time, events);
}
@@ -1395,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
}
@@ -1422,11 +1637,11 @@ 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);
- wb->set_parition(mf->get_tlx_addr().sub_partition);
+ wb->set_partition(mf->get_tlx_addr().sub_partition);
send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted),
time, events);
}
@@ -1442,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);
@@ -1459,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;
}
@@ -1470,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);
@@ -1495,11 +1714,11 @@ 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);
- wb->set_parition(mf->get_tlx_addr().sub_partition);
+ wb->set_partition(mf->get_tlx_addr().sub_partition);
send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted),
time, events);
}
@@ -1519,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
}
@@ -1552,7 +1772,7 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read(
if (m_status == HIT_RESERVED)
block->set_readable_on_fill(true, mf->get_access_sector_mask());
}
- update_m_readable(mf,cache_index);
+ update_m_readable(mf, cache_index);
if (m_status != RESERVATION_FAIL) {
// If evicted block is modified and not a write-through
@@ -1562,11 +1782,11 @@ 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);
- wb->set_parition(mf->get_tlx_addr().sub_partition);
+ wb->set_partition(mf->get_tlx_addr().sub_partition);
send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted),
time, events);
}
@@ -1580,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
}
@@ -1625,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;
}
@@ -1644,11 +1866,11 @@ 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);
- wb->set_parition(mf->get_tlx_addr().sub_partition);
+ wb->set_partition(mf->get_tlx_addr().sub_partition);
send_write_request(wb, WRITE_BACK_REQUEST_SENT, time, events);
}
return MISS;
@@ -1684,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;
}
@@ -1721,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) {
@@ -1733,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());
}
}
@@ -1758,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;
}
@@ -1822,14 +2052,17 @@ 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;
}
void tex_cache::cycle() {
// send next request to lower level of memory
+ // TODO: Use different full() for sst_mem_interface?
if (!m_request_fifo.empty()) {
mem_fetch *mf = m_request_fifo.peek();
if (!m_memport->full(mf->get_ctrl_size(), false)) {