summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim')
-rw-r--r--src/gpgpu-sim/CMakeLists.txt36
-rw-r--r--src/gpgpu-sim/addrdec.cc4
-rw-r--r--src/gpgpu-sim/dram.cc100
-rw-r--r--src/gpgpu-sim/dram.h12
-rw-r--r--src/gpgpu-sim/gpu-cache.cc581
-rw-r--r--src/gpgpu-sim/gpu-cache.h99
-rw-r--r--src/gpgpu-sim/gpu-sim.cc504
-rw-r--r--src/gpgpu-sim/gpu-sim.h187
-rw-r--r--src/gpgpu-sim/l2cache.cc46
-rw-r--r--src/gpgpu-sim/l2cache.h19
-rw-r--r--src/gpgpu-sim/local_interconnect.cc18
-rw-r--r--src/gpgpu-sim/mem_fetch.cc29
-rw-r--r--src/gpgpu-sim/mem_fetch.h12
-rw-r--r--src/gpgpu-sim/mem_latency_stat.cc17
-rw-r--r--src/gpgpu-sim/power_interface.cc636
-rw-r--r--src/gpgpu-sim/power_interface.h32
-rw-r--r--src/gpgpu-sim/power_stat.cc530
-rw-r--r--src/gpgpu-sim/power_stat.h862
-rw-r--r--src/gpgpu-sim/shader.cc625
-rw-r--r--src/gpgpu-sim/shader.h657
-rw-r--r--src/gpgpu-sim/shader_trace.h2
-rw-r--r--src/gpgpu-sim/stat-tool.cc2
22 files changed, 3168 insertions, 1842 deletions
diff --git a/src/gpgpu-sim/CMakeLists.txt b/src/gpgpu-sim/CMakeLists.txt
new file mode 100644
index 0000000..04f1973
--- /dev/null
+++ b/src/gpgpu-sim/CMakeLists.txt
@@ -0,0 +1,36 @@
+# Exclude power_interface.cc if no power model
+list(APPEND gpgpusim_SRC addrdec.cc
+ dram.cc
+ dram_sched.cc
+ gpu-cache.cc
+ gpu-misc.cc
+ gpu-sim.cc
+ hashing.cc
+ histogram.cc
+ icnt_wrapper.cc
+ l2cache.cc
+ local_interconnect.cc
+ mem_fetch.cc
+ mem_latency_stat.cc
+ power_interface.cc
+ power_stat.cc
+ scoreboard.cc
+ shader.cc
+ stack.cc
+ stat-tool.cc
+ traffic_breakdown.cc
+ visualizer.cc)
+if(NOT GPGPUSIM_USE_POWER_MODEL)
+ list(REMOVE_ITEM ${gpgpusim_SRC} power_interface.cc)
+endif()
+
+# Create libgpgpusim.a
+add_library(gpgpusim STATIC ${gpgpusim_SRC})
+target_include_directories(gpgpusim PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(gpgpusim PUBLIC ${CUDAToolkit_INCLUDE_DIRS})
+
+if(GPGPUSIM_USE_POWER_MODEL)
+target_compile_definitions(gpgpusim PRIVATE GPGPUSIM_POWER_MODEL)
+target_include_directories(gpgpusim PRIVATE ${GPGPUSIM_POWER_MODEL})
+endif()
+
diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc
index 19714ec..db27c82 100644
--- a/src/gpgpu-sim/addrdec.cc
+++ b/src/gpgpu-sim/addrdec.cc
@@ -519,7 +519,7 @@ void linear_to_raw_address_translation::sweep_test() const {
h->second, raw_addr);
abort();
} else {
- assert((int)tlx.chip < m_n_channel);
+ assert(tlx.chip < m_n_channel);
// ensure that partition_address() returns the concatenated address
if ((ADDR_CHIP_S != -1 and raw_addr >= (1ULL << ADDR_CHIP_S)) or
(ADDR_CHIP_S == -1 and raw_addr >= (1ULL << addrdec_mklow[CHIP]))) {
@@ -584,7 +584,7 @@ unsigned next_powerOf2(unsigned n) {
n = n - 1;
// do till only one bit is left
- while (n & n - 1) n = n & (n - 1); // unset rightmost bit
+ while (n & (n - 1)) n = n & (n - 1); // unset rightmost bit
// n is now a power of two (less than n)
diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc
index 545c45d..80e20d7 100644
--- a/src/gpgpu-sim/dram.cc
+++ b/src/gpgpu-sim/dram.cc
@@ -1,17 +1,19 @@
// Copyright (c) 2009-2021, Tor M. Aamodt, Wilson W.L. Fung, Ali Bakhoda,
-// Ivan Sham, George L. Yuan, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// Ivan Sham, George L. Yuan, 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.
@@ -591,39 +593,40 @@ bool dram_t::issue_col_command(int j) {
bk[j]->mrq = NULL;
}
} else
- // correct row activated for a WRITE
- if (!issued && !CCDc && !bk[j]->RCDWRc && !(bkgrp[grp]->CCDLc) &&
- (bk[j]->curr_row == bk[j]->mrq->row) && (bk[j]->mrq->rw == WRITE) &&
- (RTWc == 0) && (bk[j]->state == BANK_ACTIVE) && !rwq->full()) {
- if (rw == READ) {
- rw = WRITE;
- rwq->set_min_length(m_config->WL);
- }
- rwq->push(bk[j]->mrq);
+ // correct row activated for a WRITE
+ if (!issued && !CCDc && !bk[j]->RCDWRc && !(bkgrp[grp]->CCDLc) &&
+ (bk[j]->curr_row == bk[j]->mrq->row) && (bk[j]->mrq->rw == WRITE) &&
+ (RTWc == 0) && (bk[j]->state == BANK_ACTIVE) && !rwq->full()) {
+ if (rw == READ) {
+ rw = WRITE;
+ rwq->set_min_length(m_config->WL);
+ }
+ rwq->push(bk[j]->mrq);
- bk[j]->mrq->txbytes += m_config->dram_atom_size;
- CCDc = m_config->tCCD;
- bkgrp[grp]->CCDLc = m_config->tCCDL;
- WTRc = m_config->tWTR;
- bk[j]->WTPc = m_config->tWTP;
- issued = true;
+ bk[j]->mrq->txbytes += m_config->dram_atom_size;
+ CCDc = m_config->tCCD;
+ bkgrp[grp]->CCDLc = m_config->tCCDL;
+ WTRc = m_config->tWTR;
+ bk[j]->WTPc = m_config->tWTP;
+ issued = true;
- if (bk[j]->mrq->data->get_access_type() == L2_WRBK_ACC)
- n_wr_WB++;
- else
- n_wr++;
- bwutil += m_config->BL / m_config->data_command_freq_ratio;
- bwutil_partial += m_config->BL / m_config->data_command_freq_ratio;
+ if (bk[j]->mrq->data->get_access_type() == L2_WRBK_ACC)
+ n_wr_WB++;
+ else
+ n_wr++;
+ bwutil += m_config->BL / m_config->data_command_freq_ratio;
+ bwutil_partial += m_config->BL / m_config->data_command_freq_ratio;
#ifdef DRAM_VERIFY
- PRINT_CYCLE = 1;
- printf("\tWR Bk:%d Row:%03x Col:%03x \n", j, bk[j]->curr_row,
- bk[j]->mrq->col + bk[j]->mrq->txbytes - m_config->dram_atom_size);
+ PRINT_CYCLE = 1;
+ printf(
+ "\tWR Bk:%d Row:%03x Col:%03x \n", j, bk[j]->curr_row,
+ bk[j]->mrq->col + bk[j]->mrq->txbytes - m_config->dram_atom_size);
#endif
- // transfer done
- if (!(bk[j]->mrq->txbytes < bk[j]->mrq->nbytes)) {
- bk[j]->mrq = NULL;
+ // transfer done
+ if (!(bk[j]->mrq->txbytes < bk[j]->mrq->nbytes)) {
+ bk[j]->mrq = NULL;
+ }
}
- }
}
return issued;
@@ -659,23 +662,23 @@ bool dram_t::issue_row_command(int j) {
}
else
- // different row activated
- if ((!issued) && (bk[j]->curr_row != bk[j]->mrq->row) &&
- (bk[j]->state == BANK_ACTIVE) &&
- (!bk[j]->RASc && !bk[j]->WTPc && !bk[j]->RTPc &&
- !bkgrp[grp]->RTPLc)) {
- // make the bank idle again
- bk[j]->state = BANK_IDLE;
- bk[j]->RPc = m_config->tRP;
- prio = (j + 1) % m_config->nbk;
- issued = true;
- n_pre++;
- n_pre_partial++;
+ // different row activated
+ if ((!issued) && (bk[j]->curr_row != bk[j]->mrq->row) &&
+ (bk[j]->state == BANK_ACTIVE) &&
+ (!bk[j]->RASc && !bk[j]->WTPc && !bk[j]->RTPc &&
+ !bkgrp[grp]->RTPLc)) {
+ // make the bank idle again
+ bk[j]->state = BANK_IDLE;
+ bk[j]->RPc = m_config->tRP;
+ prio = (j + 1) % m_config->nbk;
+ issued = true;
+ n_pre++;
+ n_pre_partial++;
#ifdef DRAM_VERIFY
- PRINT_CYCLE = 1;
- printf("\tPRE BK:%d Row:%03x \n", j, bk[j]->curr_row);
+ PRINT_CYCLE = 1;
+ printf("\tPRE BK:%d Row:%03x \n", j, bk[j]->curr_row);
#endif
- }
+ }
}
return issued;
}
@@ -879,4 +882,5 @@ unsigned dram_t::get_bankgrp_number(unsigned i) {
} else {
assert(1);
}
+ return 0; // we should never get here
}
diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h
index 88e46ed..9e9517b 100644
--- a/src/gpgpu-sim/dram.h
+++ b/src/gpgpu-sim/dram.h
@@ -1,17 +1,19 @@
// Copyright (c) 2009-2021, Tor M. Aamodt, Ivan Sham, Ali Bakhoda,
-// George L. Yuan, Wilson W.L. Fung, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// George L. Yuan, Wilson W.L. Fung, 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.
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)) {
diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h
index 498dfeb..c07695f 100644
--- a/src/gpgpu-sim/gpu-cache.h
+++ b/src/gpgpu-sim/gpu-cache.h
@@ -1,16 +1,18 @@
-// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
+// 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.
@@ -70,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;
@@ -498,6 +507,7 @@ struct sector_cache_block : public cache_block_t {
for (unsigned i = 0; i < SECTOR_CHUNCK_SIZE; ++i) {
if (sector_mask.to_ulong() & (1 << i)) return i;
}
+ return SECTOR_CHUNCK_SIZE; // error
}
};
@@ -720,9 +730,16 @@ class cache_config {
"Invalid cache configuration: FETCH_ON_WRITE and LAZY_FETCH_ON_READ "
"cannot work properly with ON_FILL policy. Cache must be ON_MISS. ");
}
+
if (m_cache_type == SECTOR) {
- assert(m_line_sz / SECTOR_SIZE == SECTOR_CHUNCK_SIZE &&
- m_line_sz % SECTOR_SIZE == 0);
+ bool cond = m_line_sz / SECTOR_SIZE == SECTOR_CHUNCK_SIZE &&
+ m_line_sz % SECTOR_SIZE == 0;
+ if (!cond) {
+ std::cerr << "error: For sector cache, the simulator uses hard-coded "
+ "SECTOR_SIZE and SECTOR_CHUNCK_SIZE. The line size "
+ "must be product of both values.\n";
+ assert(0);
+ }
}
// default: port to data array width and granularity = line size
@@ -1190,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,
@@ -1221,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;
@@ -1254,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);
}
@@ -1326,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
@@ -1357,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; }
@@ -1443,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)
@@ -1468,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;
@@ -1658,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() {}
@@ -1683,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 e44551e..55d70d1 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -1,17 +1,19 @@
// Copyright (c) 2009-2021, Tor M. Aamodt, Wilson W.L. Fung, George L. Yuan,
-// Ali Bakhoda, Andrew Turner, Ivan Sham, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// Ali Bakhoda, Andrew Turner, Ivan Sham, 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.
@@ -79,7 +81,7 @@ class gpgpu_sim_wrapper {};
#include <sstream>
#include <string>
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+// #define MAX(a, b) (((a) > (b)) ? (a) : (b)) //redefined
bool g_interactive_debugger_enabled = false;
@@ -96,7 +98,6 @@ tr1_hash_map<new_addr_type, unsigned> address_random_interleaving;
#include "mem_latency_stat.h"
-
void power_config::reg_options(class OptionParser *opp) {
option_parser_register(opp, "-accelwattch_xml_file", OPT_CSTR,
&g_power_config_name, "AccelWattch XML file",
@@ -110,91 +111,106 @@ void power_config::reg_options(class OptionParser *opp) {
&g_power_per_cycle_dump,
"Dump detailed power output each cycle", "0");
-
-
-
option_parser_register(opp, "-hw_perf_file_name", OPT_CSTR,
- &g_hw_perf_file_name, "Hardware Performance Statistics file",
- "hw_perf.csv");
+ &g_hw_perf_file_name,
+ "Hardware Performance Statistics file", "hw_perf.csv");
- option_parser_register(opp, "-hw_perf_bench_name", OPT_CSTR,
- &g_hw_perf_bench_name, "Kernel Name in Hardware Performance Statistics file",
- "");
+ option_parser_register(
+ opp, "-hw_perf_bench_name", OPT_CSTR, &g_hw_perf_bench_name,
+ "Kernel Name in Hardware Performance Statistics file", "");
option_parser_register(opp, "-power_simulation_mode", OPT_INT32,
&g_power_simulation_mode,
- "Switch performance counter input for power simulation (0=Sim, 1=HW, 2=HW-Sim Hybrid)", "0");
+ "Switch performance counter input for power "
+ "simulation (0=Sim, 1=HW, 2=HW-Sim Hybrid)",
+ "0");
- option_parser_register(opp, "-dvfs_enabled", OPT_BOOL,
- &g_dvfs_enabled,
+ option_parser_register(opp, "-dvfs_enabled", OPT_BOOL, &g_dvfs_enabled,
"Turn on DVFS for power model", "0");
option_parser_register(opp, "-aggregate_power_stats", OPT_BOOL,
&g_aggregate_power_stats,
"Accumulate power across all kernels", "0");
- //Accelwattch Hyrbid Configuration
+ // Accelwattch Hyrbid Configuration
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_L1_RH", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_L1_RH],
- "Get L1 Read Hits for Accelwattch-Hybrid from Accel-Sim", "0");
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_L1_RM", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_L1_RM],
- "Get L1 Read Misses for Accelwattch-Hybrid from Accel-Sim", "0");
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_L1_WH", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_L1_WH],
- "Get L1 Write Hits for Accelwattch-Hybrid from Accel-Sim", "0");
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_L1_WM", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_L1_WM],
- "Get L1 Write Misses for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_L1_RH", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_L1_RH],
+ "Get L1 Read Hits for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_L1_RM", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_L1_RM],
+ "Get L1 Read Misses for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_L1_WH", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_L1_WH],
+ "Get L1 Write Hits for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_L1_WM", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_L1_WM],
+ "Get L1 Write Misses for Accelwattch-Hybrid from Accel-Sim", "0");
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_L2_RH", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_L2_RH],
- "Get L2 Read Hits for Accelwattch-Hybrid from Accel-Sim", "0");
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_L2_RM", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_L2_RM],
- "Get L2 Read Misses for Accelwattch-Hybrid from Accel-Sim", "0");
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_L2_WH", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_L2_WH],
- "Get L2 Write Hits for Accelwattch-Hybrid from Accel-Sim", "0");
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_L2_WM", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_L2_WM],
- "Get L2 Write Misses for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_L2_RH", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_L2_RH],
+ "Get L2 Read Hits for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_L2_RM", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_L2_RM],
+ "Get L2 Read Misses for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_L2_WH", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_L2_WH],
+ "Get L2 Write Hits for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_L2_WM", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_L2_WM],
+ "Get L2 Write Misses for Accelwattch-Hybrid from Accel-Sim", "0");
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_CC_ACC", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_CC_ACC],
- "Get Constant Cache Acesses for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_CC_ACC", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_CC_ACC],
+ "Get Constant Cache Acesses for Accelwattch-Hybrid from Accel-Sim", "0");
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_SHARED_ACC", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_SHRD_ACC],
- "Get Shared Memory Acesses for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_SHARED_ACC", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_SHRD_ACC],
+ "Get Shared Memory Acesses for Accelwattch-Hybrid from Accel-Sim", "0");
option_parser_register(opp, "-accelwattch_hybrid_perfsim_DRAM_RD", OPT_BOOL,
&accelwattch_hybrid_configuration[HW_DRAM_RD],
- "Get DRAM Reads for Accelwattch-Hybrid from Accel-Sim", "0");
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_DRAM_WR", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_DRAM_WR],
- "Get DRAM Writes for Accelwattch-Hybrid from Accel-Sim", "0");
-
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_NOC", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_NOC],
- "Get Interconnect Acesses for Accelwattch-Hybrid from Accel-Sim", "0");
+ "Get DRAM Reads for Accelwattch-Hybrid from Accel-Sim",
+ "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_DRAM_WR", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_DRAM_WR],
+ "Get DRAM Writes for Accelwattch-Hybrid from Accel-Sim", "0");
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_PIPE_DUTY", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_PIPE_DUTY],
- "Get Pipeline Duty Cycle Acesses for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_NOC", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_NOC],
+ "Get Interconnect Acesses for Accelwattch-Hybrid from Accel-Sim", "0");
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_NUM_SM_IDLE", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_NUM_SM_IDLE],
- "Get Number of Idle SMs for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_PIPE_DUTY", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_PIPE_DUTY],
+ "Get Pipeline Duty Cycle Acesses for Accelwattch-Hybrid from Accel-Sim",
+ "0");
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_CYCLES", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_CYCLES],
- "Get Executed Cycles for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_NUM_SM_IDLE", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_NUM_SM_IDLE],
+ "Get Number of Idle SMs for Accelwattch-Hybrid from Accel-Sim", "0");
- option_parser_register(opp, "-accelwattch_hybrid_perfsim_VOLTAGE", OPT_BOOL,
- &accelwattch_hybrid_configuration[HW_VOLTAGE],
- "Get Chip Voltage for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_CYCLES", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_CYCLES],
+ "Get Executed Cycles for Accelwattch-Hybrid from Accel-Sim", "0");
+ option_parser_register(
+ opp, "-accelwattch_hybrid_perfsim_VOLTAGE", OPT_BOOL,
+ &accelwattch_hybrid_configuration[HW_VOLTAGE],
+ "Get Chip Voltage for Accelwattch-Hybrid from Accel-Sim", "0");
// Output Data Formats
option_parser_register(
@@ -303,6 +319,9 @@ void memory_config::reg_options(class OptionParser *opp) {
"elimnate_rw_turnaround i.e set tWTR and tRTW = 0", "0");
option_parser_register(opp, "-icnt_flit_size", OPT_UINT32, &icnt_flit_size,
"icnt_flit_size", "32");
+ // SST mode activate
+ option_parser_register(opp, "-SST_mode", OPT_BOOL, &SST_mode, "SST mode",
+ "0");
m_address_mapping.addrdec_setoption(opp);
}
@@ -394,7 +413,7 @@ void shader_core_config::reg_options(class OptionParser *opp) {
"gpgpu_ignore_resources_limitation (default 0)", "0");
option_parser_register(
opp, "-gpgpu_shader_cta", OPT_UINT32, &max_cta_per_core,
- "Maximum number of concurrent CTAs in shader (default 8)", "8");
+ "Maximum number of concurrent CTAs in shader (default 32)", "32");
option_parser_register(
opp, "-gpgpu_num_cta_barriers", OPT_UINT32, &max_barriers_per_cta,
"Maximum number of named barriers per CTA (default 16)", "16");
@@ -585,26 +604,26 @@ void shader_core_config::reg_options(class OptionParser *opp) {
"ID_OC_SP,ID_OC_DP,ID_OC_INT,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_"
"INT,OC_EX_SFU,OC_EX_MEM,EX_WB,ID_OC_TENSOR_CORE,OC_EX_TENSOR_CORE",
"1,1,1,1,1,1,1,1,1,1,1,1,1");
- option_parser_register(opp, "-gpgpu_tensor_core_avail", OPT_INT32,
+ option_parser_register(opp, "-gpgpu_tensor_core_avail", OPT_UINT32,
&gpgpu_tensor_core_avail,
"Tensor Core Available (default=0)", "0");
- option_parser_register(opp, "-gpgpu_num_sp_units", OPT_INT32,
+ option_parser_register(opp, "-gpgpu_num_sp_units", OPT_UINT32,
&gpgpu_num_sp_units, "Number of SP units (default=1)",
"1");
- option_parser_register(opp, "-gpgpu_num_dp_units", OPT_INT32,
+ option_parser_register(opp, "-gpgpu_num_dp_units", OPT_UINT32,
&gpgpu_num_dp_units, "Number of DP units (default=0)",
"0");
- option_parser_register(opp, "-gpgpu_num_int_units", OPT_INT32,
+ option_parser_register(opp, "-gpgpu_num_int_units", OPT_UINT32,
&gpgpu_num_int_units,
"Number of INT units (default=0)", "0");
- option_parser_register(opp, "-gpgpu_num_sfu_units", OPT_INT32,
+ option_parser_register(opp, "-gpgpu_num_sfu_units", OPT_UINT32,
&gpgpu_num_sfu_units, "Number of SF units (default=1)",
"1");
- option_parser_register(opp, "-gpgpu_num_tensor_core_units", OPT_INT32,
+ option_parser_register(opp, "-gpgpu_num_tensor_core_units", OPT_UINT32,
&gpgpu_num_tensor_core_units,
"Number of tensor_core units (default=1)", "0");
option_parser_register(
- opp, "-gpgpu_num_mem_units", OPT_INT32, &gpgpu_num_mem_units,
+ opp, "-gpgpu_num_mem_units", OPT_UINT32, &gpgpu_num_mem_units,
"Number if ldst units (default=1) WARNING: not hooked up to anything",
"1");
option_parser_register(
@@ -700,7 +719,9 @@ void gpgpu_sim_config::reg_options(option_parser_t opp) {
"500.0:2000.0:2000.0:2000.0");
option_parser_register(
opp, "-gpgpu_max_concurrent_kernel", OPT_INT32, &max_concurrent_kernel,
- "maximum kernels that can run concurrently on GPU", "8");
+ "maximum kernels that can run concurrently on GPU, set this value "
+ "according to max resident grids for your compute capability",
+ "32");
option_parser_register(
opp, "-gpgpu_cflog_interval", OPT_INT32, &gpgpu_cflog_interval,
"Interval between each snapshot in control flow logger", "0");
@@ -770,6 +791,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(
@@ -875,7 +912,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;
@@ -883,6 +923,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++) {
@@ -913,6 +958,16 @@ void exec_gpgpu_sim::createSIMTCluster() {
m_shader_stats, m_memory_stats);
}
+// SST get its own simt_cluster
+void sst_gpgpu_sim::createSIMTCluster() {
+ m_cluster = new simt_core_cluster *[m_shader_config->n_simt_clusters];
+ for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++)
+ m_cluster[i] =
+ new sst_simt_core_cluster(this, i, m_shader_config, m_memory_config,
+ m_shader_stats, m_memory_stats);
+ SST_gpgpu_reply_buffer.resize(m_shader_config->n_simt_clusters);
+}
+
gpgpu_sim::gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx)
: gpgpu_t(config, ctx), m_config(config) {
gpgpu_ctx = ctx;
@@ -922,8 +977,9 @@ gpgpu_sim::gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx)
ptx_file_line_stats_create_exposed_latency_tracker(m_config.num_shader());
#ifdef GPGPUSIM_POWER_MODEL
- m_gpgpusim_wrapper = new gpgpu_sim_wrapper(config.g_power_simulation_enabled,
- config.g_power_config_name, config.g_power_simulation_mode, config.g_dvfs_enabled);
+ m_gpgpusim_wrapper = new gpgpu_sim_wrapper(
+ config.g_power_simulation_enabled, config.g_power_config_name,
+ config.g_power_simulation_mode, config.g_dvfs_enabled);
#endif
m_shader_stats = new shader_core_stats(m_shader_config);
@@ -952,27 +1008,33 @@ 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;
- m_memory_partition_unit =
- new memory_partition_unit *[m_memory_config->m_n_mem];
- m_memory_sub_partition =
- new memory_sub_partition *[m_memory_config->m_n_mem_sub_partition];
- for (unsigned i = 0; i < m_memory_config->m_n_mem; i++) {
- m_memory_partition_unit[i] =
- new memory_partition_unit(i, m_memory_config, m_memory_stats, this);
- for (unsigned p = 0;
- p < m_memory_config->m_n_sub_partition_per_memory_channel; p++) {
- unsigned submpid =
- i * m_memory_config->m_n_sub_partition_per_memory_channel + p;
- m_memory_sub_partition[submpid] =
- m_memory_partition_unit[i]->get_sub_partition(p);
- }
- }
+ gpu_kernel_time.clear();
- icnt_wrapper_init();
- icnt_create(m_shader_config->n_simt_clusters,
- m_memory_config->m_n_mem_sub_partition);
+ // TODO: somehow move this logic to the sst_gpgpu_sim constructor?
+ if (!m_config.is_SST_mode()) {
+ // Init memory if not in SST mode
+ m_memory_partition_unit =
+ new memory_partition_unit *[m_memory_config->m_n_mem];
+ m_memory_sub_partition =
+ new memory_sub_partition *[m_memory_config->m_n_mem_sub_partition];
+ for (unsigned i = 0; i < m_memory_config->m_n_mem; i++) {
+ m_memory_partition_unit[i] =
+ new memory_partition_unit(i, m_memory_config, m_memory_stats, this);
+ for (unsigned p = 0;
+ p < m_memory_config->m_n_sub_partition_per_memory_channel; p++) {
+ unsigned submpid =
+ i * m_memory_config->m_n_sub_partition_per_memory_channel + p;
+ m_memory_sub_partition[submpid] =
+ m_memory_partition_unit[i]->get_sub_partition(p);
+ }
+ }
+ icnt_wrapper_init();
+ icnt_create(m_shader_config->n_simt_clusters,
+ m_memory_config->m_n_mem_sub_partition);
+ }
time_vector_create(NUM_MEM_REQ_STAT);
fprintf(stdout,
"GPGPU-Sim uArch: performance model initialization complete.\n");
@@ -991,6 +1053,22 @@ gpgpu_sim::gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx)
m_functional_sim_kernel = NULL;
}
+void sst_gpgpu_sim::SST_receive_mem_reply(unsigned core_id, void *mem_req) {
+ assert(core_id < m_shader_config->n_simt_clusters);
+ mem_fetch *mf = (mem_fetch *)mem_req;
+
+ (SST_gpgpu_reply_buffer[core_id]).push_back(mf);
+}
+
+mem_fetch *sst_gpgpu_sim::SST_pop_mem_reply(unsigned core_id) {
+ if (SST_gpgpu_reply_buffer[core_id].size() > 0) {
+ mem_fetch *temp = SST_gpgpu_reply_buffer[core_id].front();
+ SST_gpgpu_reply_buffer[core_id].pop_front();
+ return temp;
+ } else
+ return NULL;
+}
+
int gpgpu_sim::shared_mem_size() const {
return m_shader_config->gpgpu_shmem_size;
}
@@ -1086,6 +1164,26 @@ bool gpgpu_sim::active() {
return false;
}
+bool sst_gpgpu_sim::active() {
+ if (m_config.gpu_max_cycle_opt &&
+ (gpu_tot_sim_cycle + gpu_sim_cycle) >= m_config.gpu_max_cycle_opt)
+ return false;
+ if (m_config.gpu_max_insn_opt &&
+ (gpu_tot_sim_insn + gpu_sim_insn) >= m_config.gpu_max_insn_opt)
+ return false;
+ if (m_config.gpu_max_cta_opt &&
+ (gpu_tot_issued_cta >= m_config.gpu_max_cta_opt))
+ return false;
+ if (m_config.gpu_max_completed_cta_opt &&
+ (gpu_completed_cta >= m_config.gpu_max_completed_cta_opt))
+ return false;
+ if (m_config.gpu_deadlock_detect && gpu_deadlock) return false;
+ for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++)
+ if (m_cluster[i]->get_not_completed() > 0) return true;
+ if (get_more_cta_left()) return true;
+ return false;
+}
+
void gpgpu_sim::init() {
// run a CUDA grid on the GPU microarchitecture simulator
gpu_sim_cycle = 0;
@@ -1155,14 +1253,13 @@ void gpgpu_sim::update_stats() {
gpu_occupancy = occupancy_stats();
}
-PowerscalingCoefficients *gpgpu_sim::get_scaling_coeffs()
-{
+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(
@@ -1241,10 +1338,10 @@ std::string gpgpu_sim::executed_kernel_info_string() {
}
std::string gpgpu_sim::executed_kernel_name() {
- std::stringstream statout;
- if( m_executed_kernel_names.size() == 1)
- statout << m_executed_kernel_names[0];
- else{
+ std::stringstream statout;
+ if (m_executed_kernel_names.size() == 1)
+ statout << m_executed_kernel_names[0];
+ else {
for (unsigned int k = 0; k < m_executed_kernel_names.size(); k++) {
statout << m_executed_kernel_names[k] << " ";
}
@@ -1345,12 +1442,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);
@@ -1397,13 +1497,13 @@ void gpgpu_sim::gpu_print_stat() {
// %lld\n", partiton_replys_in_parallel_total );
printf("L2_BW = %12.4f GB/Sec\n",
((float)(partiton_replys_in_parallel * 32) /
- (gpu_sim_cycle * m_config.icnt_period)) /
+ (gpu_sim_cycle * m_config.core_period)) /
1000000000);
printf("L2_BW_total = %12.4f GB/Sec\n",
((float)((partiton_replys_in_parallel +
partiton_replys_in_parallel_total) *
32) /
- ((gpu_tot_sim_cycle + gpu_sim_cycle) * m_config.icnt_period)) /
+ ((gpu_tot_sim_cycle + gpu_sim_cycle) * m_config.core_period)) /
1000000000);
time_t curr_time;
@@ -1422,29 +1522,33 @@ 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);
m_shader_stats->print(stdout);
#ifdef GPGPUSIM_POWER_MODEL
if (m_config.g_power_simulation_enabled) {
- if(m_config.g_power_simulation_mode > 0){
- //if(!m_config.g_aggregate_power_stats)
- mcpat_reset_perf_count(m_gpgpusim_wrapper);
- calculate_hw_mcpat(m_config, getShaderCoreConfig(), m_gpgpusim_wrapper,
- m_power_stats, m_config.gpu_stat_sample_freq,
- gpu_tot_sim_cycle, gpu_sim_cycle, gpu_tot_sim_insn,
- gpu_sim_insn, m_config.g_power_simulation_mode, m_config.g_dvfs_enabled,
- m_config.g_hw_perf_file_name, m_config.g_hw_perf_bench_name, executed_kernel_name(), m_config.accelwattch_hybrid_configuration, m_config.g_aggregate_power_stats);
+ if (m_config.g_power_simulation_mode > 0) {
+ // if(!m_config.g_aggregate_power_stats)
+ mcpat_reset_perf_count(m_gpgpusim_wrapper);
+ calculate_hw_mcpat(m_config, getShaderCoreConfig(), m_gpgpusim_wrapper,
+ m_power_stats, m_config.gpu_stat_sample_freq,
+ gpu_tot_sim_cycle, gpu_sim_cycle, gpu_tot_sim_insn,
+ gpu_sim_insn, m_config.g_power_simulation_mode,
+ m_config.g_dvfs_enabled, m_config.g_hw_perf_file_name,
+ m_config.g_hw_perf_bench_name, executed_kernel_name(),
+ m_config.accelwattch_hybrid_configuration,
+ m_config.g_aggregate_power_stats);
}
m_gpgpusim_wrapper->print_power_kernel_stats(
gpu_sim_cycle, gpu_tot_sim_cycle, gpu_tot_sim_insn + gpu_sim_insn,
kernel_info_str, true);
- //if(!m_config.g_aggregate_power_stats)
- mcpat_reset_perf_count(m_gpgpusim_wrapper);
+ // if(!m_config.g_aggregate_power_stats)
+ mcpat_reset_perf_count(m_gpgpusim_wrapper);
}
#endif
@@ -1489,9 +1593,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");
}
}
@@ -1638,9 +1743,9 @@ bool shader_core_ctx::occupy_shader_resource_1block(kernel_info_t &k,
SHADER_DPRINTF(LIVENESS,
"GPGPU-Sim uArch: Occupied %u threads, %u shared mem, %u "
- "registers, %u ctas\n",
+ "registers, %u ctas, on shader %d\n",
m_occupied_n_threads, m_occupied_shmem, m_occupied_regs,
- m_occupied_ctas);
+ m_occupied_ctas, m_sid);
}
return true;
@@ -1806,9 +1911,10 @@ void shader_core_ctx::issue_block2core(kernel_info_t &kernel) {
shader_CTA_count_log(m_sid, 1);
SHADER_DPRINTF(LIVENESS,
"GPGPU-Sim uArch: cta:%2u, start_tid:%4u, end_tid:%4u, "
- "initialized @(%lld,%lld)\n",
+ "initialized @(%lld,%lld), kernel_uid:%u, kernel_name:%s\n",
free_cta_hw_id, start_thread, end_thread, m_gpu->gpu_sim_cycle,
- m_gpu->gpu_tot_sim_cycle);
+ m_gpu->gpu_tot_sim_cycle, kernel.get_uid(),
+ kernel.get_name().c_str());
}
///////////////////////////////////////////////////////////////////////////////////////////
@@ -1933,8 +2039,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;
@@ -1956,11 +2064,13 @@ 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]);
+ 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);
@@ -1985,11 +2095,11 @@ void gpgpu_sim::cycle() {
// McPAT main cycle (interface with McPAT)
#ifdef GPGPUSIM_POWER_MODEL
if (m_config.g_power_simulation_enabled) {
- if(m_config.g_power_simulation_mode == 0){
- mcpat_cycle(m_config, getShaderCoreConfig(), m_gpgpusim_wrapper,
- m_power_stats, m_config.gpu_stat_sample_freq,
- gpu_tot_sim_cycle, gpu_sim_cycle, gpu_tot_sim_insn,
- gpu_sim_insn, m_config.g_dvfs_enabled);
+ if (m_config.g_power_simulation_mode == 0) {
+ mcpat_cycle(m_config, getShaderCoreConfig(), m_gpgpusim_wrapper,
+ m_power_stats, m_config.gpu_stat_sample_freq,
+ gpu_tot_sim_cycle, gpu_sim_cycle, gpu_tot_sim_insn,
+ gpu_sim_insn, m_config.g_dvfs_enabled);
}
}
#endif
@@ -2051,7 +2161,7 @@ void gpgpu_sim::cycle() {
m_cluster[i]->get_current_occupancy(active, total);
}
DPRINTFG(LIVENESS,
- "uArch: inst.: %lld (ipc=%4.1f, occ=%0.4f\% [%llu / %llu]) "
+ "uArch: inst.: %lld (ipc=%4.1f, occ=%0.4f%% [%llu / %llu]) "
"sim_rate=%u (inst/sec) elapsed = %u:%u:%02u:%02u / %s",
gpu_tot_sim_insn + gpu_sim_insn,
(double)gpu_sim_insn / (double)gpu_sim_cycle,
@@ -2099,6 +2209,11 @@ void gpgpu_sim::cycle() {
}
}
+void sst_gpgpu_sim::cycle() {
+ SST_cycle();
+ return;
+}
+
void shader_core_ctx::dump_warp_state(FILE *fout) const {
fprintf(fout, "\n");
fprintf(fout, "per warp functional simulation status:\n");
@@ -2178,3 +2293,110 @@ const shader_core_config *gpgpu_sim::getShaderCoreConfig() {
const memory_config *gpgpu_sim::getMemoryConfig() { return m_memory_config; }
simt_core_cluster *gpgpu_sim::getSIMTCluster() { return *m_cluster; }
+
+void sst_gpgpu_sim::SST_gpgpusim_numcores_equal_check(unsigned sst_numcores) {
+ if (m_shader_config->n_simt_clusters != sst_numcores) {
+ assert(
+ "\nSST core is not equal the GPGPU-sim cores. Open gpgpu-sim.config "
+ "file and ensure n_simt_clusters"
+ "is the same as SST gpu cores.\n" &&
+ 0);
+ } else {
+ printf("\nSST GPU core is equal the GPGPU-sim cores = %d\n", sst_numcores);
+ }
+}
+
+void sst_gpgpu_sim::SST_cycle() {
+ // shader core loading (pop from ICNT into core) follows CORE clock
+ for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++)
+ static_cast<sst_simt_core_cluster *>(m_cluster[i])->icnt_cycle_SST();
+
+ // L1 cache + shader core pipeline stages
+ m_power_stats->pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].clear();
+ for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++) {
+ if (m_cluster[i]->get_not_completed() || get_more_cta_left()) {
+ m_cluster[i]->core_cycle();
+ *active_sms += m_cluster[i]->get_n_active_sms();
+ }
+ // Update core icnt/cache stats for GPUWattch
+ 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]);
+ }
+ float temp = 0;
+ for (unsigned i = 0; i < m_shader_config->num_shader(); i++) {
+ temp += m_shader_stats->m_pipeline_duty_cycle[i];
+ }
+ temp = temp / m_shader_config->num_shader();
+ *average_pipeline_duty_cycle = ((*average_pipeline_duty_cycle) + temp);
+ // cout<<"Average pipeline duty cycle: "<<*average_pipeline_duty_cycle<<endl;
+
+ if (g_single_step && ((gpu_sim_cycle + gpu_tot_sim_cycle) >= g_single_step)) {
+ asm("int $03");
+ }
+ gpu_sim_cycle++;
+ if (g_interactive_debugger_enabled) gpgpu_debug();
+
+ // McPAT main cycle (interface with McPAT)
+#ifdef GPGPUSIM_POWER_MODEL
+ if (m_config.g_power_simulation_enabled) {
+ mcpat_cycle(m_config, getShaderCoreConfig(), m_gpgpusim_wrapper,
+ m_power_stats, m_config.gpu_stat_sample_freq, gpu_tot_sim_cycle,
+ gpu_sim_cycle, gpu_tot_sim_insn, gpu_sim_insn,
+ m_config.g_dvfs_enabled);
+ }
+#endif
+
+ issue_block2core();
+
+ if (!(gpu_sim_cycle % m_config.gpu_stat_sample_freq)) {
+ time_t days, hrs, minutes, sec;
+ time_t curr_time;
+ time(&curr_time);
+ unsigned long long elapsed_time =
+ MAX(curr_time - gpgpu_ctx->the_gpgpusim->g_simulation_starttime, 1);
+ if ((elapsed_time - last_liveness_message_time) >=
+ m_config.liveness_message_freq) {
+ days = elapsed_time / (3600 * 24);
+ hrs = elapsed_time / 3600 - 24 * days;
+ minutes = elapsed_time / 60 - 60 * (hrs + 24 * days);
+ sec = elapsed_time - 60 * (minutes + 60 * (hrs + 24 * days));
+
+ last_liveness_message_time = elapsed_time;
+ }
+ visualizer_printstat();
+ m_memory_stats->memlatstat_lat_pw();
+ if (m_config.gpgpu_runtime_stat && (m_config.gpu_runtime_stat_flag != 0)) {
+ if (m_config.gpu_runtime_stat_flag & GPU_RSTAT_BW_STAT) {
+ for (unsigned i = 0; i < m_memory_config->m_n_mem; i++)
+ m_memory_partition_unit[i]->print_stat(stdout);
+ printf("maxmrqlatency = %d \n", m_memory_stats->max_mrq_latency);
+ printf("maxmflatency = %d \n", m_memory_stats->max_mf_latency);
+ }
+ if (m_config.gpu_runtime_stat_flag & GPU_RSTAT_SHD_INFO)
+ shader_print_runtime_stat(stdout);
+ if (m_config.gpu_runtime_stat_flag & GPU_RSTAT_L1MISS)
+ shader_print_l1_miss_stat(stdout);
+ if (m_config.gpu_runtime_stat_flag & GPU_RSTAT_SCHED)
+ shader_print_scheduler_stat(stdout, false);
+ }
+ }
+
+ if (!(gpu_sim_cycle % 20000)) {
+ // deadlock detection
+ if (m_config.gpu_deadlock_detect && gpu_sim_insn == last_gpu_sim_insn) {
+ gpu_deadlock = true;
+ } else {
+ last_gpu_sim_insn = gpu_sim_insn;
+ }
+ }
+ try_snap_shot(gpu_sim_cycle);
+ spill_log_to_file(stdout, 0, gpu_sim_cycle);
+
+#if (CUDART_VERSION >= 5000)
+ // launch device kernel
+ gpgpu_ctx->device_runtime->launch_one_device_kernel();
+#endif
+}
diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h
index 68b3dfa..5b253ab 100644
--- a/src/gpgpu-sim/gpu-sim.h
+++ b/src/gpgpu-sim/gpu-sim.h
@@ -1,16 +1,18 @@
-// Copyright (c) 2009-2021, Tor M. Aamodt, Wilson W.L. Fung, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
+// Copyright (c) 2009-2021, Tor M. Aamodt, Wilson W.L. Fung, 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.
@@ -27,7 +29,6 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
-
#ifndef GPU_SIM_H
#define GPU_SIM_H
@@ -68,10 +69,50 @@ class gpgpu_context;
extern tr1_hash_map<new_addr_type, unsigned> address_random_interleaving;
+// SST communication functions
+/**
+ * @brief Check if SST requests buffer is full
+ *
+ * @param core_id
+ * @return true
+ * @return false
+ */
+extern bool is_SST_buffer_full(unsigned core_id);
+__attribute__((weak)) bool is_SST_buffer_full(unsigned core_id) {
+ return false;
+}
+
+/**
+ * @brief Send loads to SST memory backend
+ *
+ * @param core_id
+ * @param address
+ * @param size
+ * @param mem_req
+ */
+extern void send_read_request_SST(unsigned core_id, uint64_t address,
+ size_t size, void *mem_req);
+__attribute__((weak)) void send_read_request_SST(unsigned core_id,
+ uint64_t address, size_t size,
+ void *mem_req) {}
+/**
+ * @brief Send stores to SST memory backend
+ *
+ * @param core_id
+ * @param address
+ * @param size
+ * @param mem_req
+ */
+extern void send_write_request_SST(unsigned core_id, uint64_t address,
+ size_t size, void *mem_req);
+__attribute__((weak)) void send_write_request_SST(unsigned core_id,
+ uint64_t address, size_t size,
+ void *mem_req) {}
+
enum dram_ctrl_t { DRAM_FIFO = 0, DRAM_FRFCFS = 1 };
enum hw_perf_t {
- HW_BENCH_NAME=0,
+ HW_BENCH_NAME = 0,
HW_KERNEL_NAME,
HW_L1_RH,
HW_L1_RM,
@@ -107,7 +148,7 @@ struct power_config {
s++;
}
char buf1[1024];
- //snprintf(buf1, 1024, "accelwattch_power_report__%s.log", date);
+ // snprintf(buf1, 1024, "accelwattch_power_report__%s.log", date);
snprintf(buf1, 1024, "accelwattch_power_report.log");
g_power_filename = strdup(buf1);
char buf2[1024];
@@ -131,9 +172,9 @@ struct power_config {
// NOTE: After changing the nonlinear model to only scaling idle core,
// NOTE: The min_inc_per_active_sm is not used any more
- if (g_use_nonlinear_model)
- sscanf(gpu_nonlinear_model_config, "%lf:%lf", &gpu_idle_core_power,
- &gpu_min_inc_per_active_sm);
+ // if (g_use_nonlinear_model)
+ // sscanf(gpu_nonlinear_model_config, "%lf:%lf", &gpu_idle_core_power,
+ // &gpu_min_inc_per_active_sm);
}
void reg_options(class OptionParser *opp);
@@ -154,7 +195,6 @@ struct power_config {
double gpu_steady_power_deviation;
double gpu_steady_min_period;
-
char *g_hw_perf_file_name;
char *g_hw_perf_bench_name;
int g_power_simulation_mode;
@@ -274,6 +314,14 @@ class memory_config {
}
void reg_options(class OptionParser *opp);
+ /**
+ * @brief Check if the config script is in SST mode
+ *
+ * @return true
+ * @return false
+ */
+ bool is_SST_mode() const { return SST_mode; }
+
bool m_valid;
mutable l2_cache_config m_L2_config;
bool m_L2_texure_only;
@@ -351,7 +399,7 @@ class memory_config {
unsigned write_low_watermark;
bool m_perf_sim_memcpy;
bool simple_dram_model;
-
+ bool SST_mode;
gpgpu_context *gpgpu_ctx;
};
@@ -398,6 +446,15 @@ class gpgpu_sim_config : public power_config,
unsigned num_shader() const { return m_shader_config.num_shader(); }
unsigned num_cluster() const { return m_shader_config.n_simt_clusters; }
unsigned get_max_concurrent_kernel() const { return max_concurrent_kernel; }
+
+ /**
+ * @brief Check if we are in SST mode
+ *
+ * @return true
+ * @return false
+ */
+ bool is_SST_mode() const { return m_memory_config.SST_mode; }
+
unsigned checkpoint_option;
size_t stack_limit() const { return stack_size_limit; }
@@ -462,6 +519,7 @@ class gpgpu_sim_config : public power_config,
unsigned long long liveness_message_freq;
friend class gpgpu_sim;
+ friend class sst_gpgpu_sim;
};
struct occupancy_stats {
@@ -539,7 +597,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 +626,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);
@@ -600,10 +658,18 @@ class gpgpu_sim : public gpgpu_t {
void hit_watchpoint(unsigned watchpoint_num, ptx_thread_info *thd,
const ptx_instruction *pI);
+ /**
+ * @brief Check if we are in SST mode
+ *
+ * @return true
+ * @return false
+ */
+ bool is_SST_mode() { return m_config.is_SST_mode(); }
+
// backward pointer
class gpgpu_context *gpgpu_ctx;
- private:
+ protected:
// clocks
void reinit_clock_domains(void);
int next_clock_domain(void);
@@ -685,6 +751,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;
@@ -704,7 +781,7 @@ class gpgpu_sim : public gpgpu_t {
void set_cache_config(std::string kernel_name);
// Jin: functional simulation for CDP
- private:
+ protected:
// set by stream operation every time a functoinal simulation is done
bool m_functional_sim;
kernel_info_t *m_functional_sim_kernel;
@@ -712,6 +789,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;
@@ -734,4 +814,79 @@ class exec_gpgpu_sim : public gpgpu_sim {
virtual void createSIMTCluster();
};
+/**
+ * @brief A GPGPUSim class customized to SST Balar interfacing
+ *
+ */
+class sst_gpgpu_sim : public gpgpu_sim {
+ public:
+ sst_gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx)
+ : gpgpu_sim(config, ctx) {
+ createSIMTCluster();
+ }
+
+ // SST memory handling
+ std::vector<std::deque<mem_fetch *>>
+ SST_gpgpu_reply_buffer; /** SST mem response queue */
+
+ /**
+ * @brief Receive mem request's response from SST and put
+ * it in a buffer (SST_gpgpu_reply_buffer)
+ *
+ * @param core_id
+ * @param mem_req
+ */
+ void SST_receive_mem_reply(unsigned core_id, void *mem_req);
+
+ /**
+ * @brief Pop the head of the buffer queue to get the
+ * memory response
+ *
+ * @param core_id
+ * @return mem_fetch*
+ */
+ mem_fetch *SST_pop_mem_reply(unsigned core_id);
+
+ virtual void createSIMTCluster();
+
+ // SST Balar interfacing
+ /**
+ * @brief Advance core and collect stats
+ *
+ */
+ void SST_cycle();
+
+ /**
+ * @brief Wrapper of SST_cycle()
+ *
+ */
+ void cycle();
+
+ /**
+ * @brief Whether the GPU is active, removed test for
+ * memory system since that is handled in SST
+ *
+ * @return true
+ * @return false
+ */
+ bool active();
+
+ /**
+ * @brief SST mode use SST memory system instead, so the memcpy
+ * is empty here
+ *
+ * @param dst_start_addr
+ * @param count
+ */
+ void perf_memcpy_to_gpu(size_t dst_start_addr, size_t count){};
+
+ /**
+ * @brief Check if the SST config matches up with the
+ * gpgpusim.config in core number
+ *
+ * @param sst_numcores SST core count
+ */
+ void SST_gpgpusim_numcores_equal_check(unsigned sst_numcores);
+};
+
#endif
diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc
index 511c15e..52eed0e 100644
--- a/src/gpgpu-sim/l2cache.cc
+++ b/src/gpgpu-sim/l2cache.cc
@@ -1,16 +1,18 @@
-// Copyright (c) 2009-2021, Tor M. Aamodt, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// Copyright (c) 2009-2021, Tor M. Aamodt, 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.
@@ -49,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;
}
@@ -63,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,
@@ -389,7 +391,8 @@ void memory_partition_unit::set_done(mem_fetch *mf) {
void memory_partition_unit::set_dram_power_stats(
unsigned &n_cmd, unsigned &n_activity, unsigned &n_nop, unsigned &n_act,
- unsigned &n_pre, unsigned &n_rd, unsigned &n_wr, unsigned &n_wr_WB, unsigned &n_req) const {
+ unsigned &n_pre, unsigned &n_rd, unsigned &n_wr, unsigned &n_wr_WB,
+ unsigned &n_req) const {
m_dram->set_dram_power_stats(n_cmd, n_activity, n_nop, n_act, n_pre, n_rd,
n_wr, n_wr_WB, n_req);
}
@@ -433,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;
@@ -558,7 +561,7 @@ void memory_sub_partition::cache_cycle(unsigned cycle) {
if (mf->get_access_type() == L1_WRBK_ACC) {
m_request_tracker.erase(mf);
delete mf;
- } else {
+ } else if (m_config->m_L2_config.get_write_policy() == WRITE_BACK) {
mf->set_reply();
mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,
m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
@@ -730,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);
}
@@ -753,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);
}
@@ -769,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 902a4b7..65c9c38 100644
--- a/src/gpgpu-sim/l2cache.h
+++ b/src/gpgpu-sim/l2cache.h
@@ -1,16 +1,18 @@
-// Copyright (c) 2009-2021, Tor M. Aamodt, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// Copyright (c) 2009-2021, Tor M. Aamodt, 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.
@@ -50,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/local_interconnect.cc b/src/gpgpu-sim/local_interconnect.cc
index 0e20462..7e1ab5b 100644
--- a/src/gpgpu-sim/local_interconnect.cc
+++ b/src/gpgpu-sim/local_interconnect.cc
@@ -148,8 +148,8 @@ void xbar_router::RR_Advance() {
}
}
}
-
- next_node_id = (++next_node_id % total_nodes);
+ next_node_id = next_node_id + 1;
+ next_node_id = (next_node_id % total_nodes);
conflicts += conflict_sub;
if (active) {
@@ -159,8 +159,8 @@ void xbar_router::RR_Advance() {
}
if (verbose) {
- printf("%d : cycle %d : conflicts = %d\n", m_id, cycles, conflict_sub);
- printf("%d : cycle %d : passing reqs = %d\n", m_id, cycles, reqs);
+ printf("%d : cycle %llu : conflicts = %d\n", m_id, cycles, conflict_sub);
+ printf("%d : cycle %llu : passing reqs = %d\n", m_id, cycles, reqs);
}
// collect some stats about buffer util
@@ -217,7 +217,7 @@ void xbar_router::iSLIP_Advance() {
out_buffers[_packet.output_deviceID].push(_packet);
in_buffers[node_id].pop();
if (verbose)
- printf("%d : cycle %d : send req from %d to %d\n", m_id, cycles,
+ printf("%d : cycle %llu : send req from %d to %d\n", m_id, cycles,
node_id, i - _n_shader);
if (grant_cycles_count == 1)
next_node[i] = (++node_id % total_nodes);
@@ -228,7 +228,7 @@ void xbar_router::iSLIP_Advance() {
Packet _packet2 = in_buffers[node_id2].front();
if (_packet2.output_deviceID == i)
- printf("%d : cycle %d : cannot send req from %d to %d\n",
+ printf("%d : cycle %llu : cannot send req from %d to %d\n",
m_id, cycles, node_id2, i - _n_shader);
}
}
@@ -248,7 +248,7 @@ void xbar_router::iSLIP_Advance() {
}
if (verbose)
- printf("%d : cycle %d : grant_cycles = %d\n", m_id, cycles, grant_cycles);
+ printf("%d : cycle %llu : grant_cycles = %d\n", m_id, cycles, grant_cycles);
if (active && grant_cycles_count == 1)
grant_cycles_count = grant_cycles;
@@ -256,8 +256,8 @@ void xbar_router::iSLIP_Advance() {
grant_cycles_count--;
if (verbose) {
- printf("%d : cycle %d : conflicts = %d\n", m_id, cycles, conflict_sub);
- printf("%d : cycle %d : passing reqs = %d\n", m_id, cycles, reqs);
+ printf("%d : cycle %llu : conflicts = %d\n", m_id, cycles, conflict_sub);
+ printf("%d : cycle %llu : passing reqs = %d\n", m_id, cycles, reqs);
}
// collect some stats about buffer util
diff --git a/src/gpgpu-sim/mem_fetch.cc b/src/gpgpu-sim/mem_fetch.cc
index 456d891..809c920 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,14 +48,21 @@ 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;
m_tpc = tpc;
m_wid = wid;
- config->m_address_mapping.addrdec_tlx(access.get_addr(), &m_raw_addr);
- m_partition_addr =
- config->m_address_mapping.partition_address(access.get_addr());
+
+ if (!config->is_SST_mode()) {
+ // In SST memory model, the SST memory hierarchy is
+ // responsible to generate the correct address mapping
+ config->m_address_mapping.addrdec_tlx(access.get_addr(), &m_raw_addr);
+ m_partition_addr =
+ config->m_address_mapping.partition_address(access.get_addr());
+ }
+
m_type = m_access.is_write() ? WRITE_REQUEST : READ_REQUEST;
m_timestamp = cycle;
m_timestamp2 = 0;
@@ -84,10 +91,10 @@ mem_fetch::~mem_fetch() { m_status = MEM_FETCH_DELETED; }
#undef MF_TUP_END
void mem_fetch::print(FILE *fp, bool print_inst) const {
- if (this == NULL) {
- fprintf(fp, " <NULL mem_fetch pointer>\n");
- return;
- }
+ // if (this == NULL) { // doenst make sense!
+ // fprintf(fp, " <NULL mem_fetch pointer>\n");
+ // return;
+ // }
fprintf(fp, " mf: uid=%6u, sid%02u:w%02u, part=%u, ", m_request_uid, m_sid,
m_wid, m_raw_addr.chip);
m_access.print(fp);
diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h
index e039846..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);
@@ -77,7 +78,7 @@ class mem_fetch {
const addrdec_t &get_tlx_addr() const { return m_raw_addr; }
void set_chip(unsigned chip_id) { m_raw_addr.chip = chip_id; }
- void set_parition(unsigned sub_partition_id) {
+ void set_partition(unsigned sub_partition_id) {
m_raw_addr.sub_partition = sub_partition_id;
}
unsigned get_data_size() const { return m_data_size; }
@@ -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/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc
index 63d7ee8..c77a686 100644
--- a/src/gpgpu-sim/mem_latency_stat.cc
+++ b/src/gpgpu-sim/mem_latency_stat.cc
@@ -203,7 +203,15 @@ unsigned memory_stats_t::memlatstat_done(mem_fetch *mf) {
}
void memory_stats_t::memlatstat_read_done(mem_fetch *mf) {
- if (m_memory_config->gpgpu_memlatency_stat) {
+ if (m_memory_config->SST_mode) {
+ // in SST mode, we just calculate mem latency
+ unsigned mf_latency;
+ mf_latency =
+ (m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle) - mf->get_timestamp();
+ num_mfs++;
+ mf_total_lat += mf_latency;
+ if (mf_latency > max_mf_latency) max_mf_latency = mf_latency;
+ } else if (m_memory_config->gpgpu_memlatency_stat) {
unsigned mf_latency = memlatstat_done(mf);
if (mf_latency >
mf_max_lat_table[mf->get_tlx_addr().chip][mf->get_tlx_addr().bk])
@@ -273,7 +281,12 @@ void memory_stats_t::memlatstat_print(unsigned n_mem, unsigned gpu_mem_n_bk) {
unsigned max_bank_accesses, min_bank_accesses, max_chip_accesses,
min_chip_accesses;
- if (m_memory_config->gpgpu_memlatency_stat) {
+ if (m_memory_config->SST_mode) {
+ // in SST mode, we just calculate mem latency
+ printf("max_mem_SST_latency = %d \n", max_mf_latency);
+ if (num_mfs)
+ printf("average_mf_SST_latency = %lld \n", mf_total_lat / num_mfs);
+ } else if (m_memory_config->gpgpu_memlatency_stat) {
printf("maxmflatency = %d \n", max_mf_latency);
printf("max_icnt2mem_latency = %d \n", max_icnt2mem_latency);
printf("maxmrqlatency = %d \n", max_mrq_latency);
diff --git a/src/gpgpu-sim/power_interface.cc b/src/gpgpu-sim/power_interface.cc
index 63b9852..cddb6e9 100644
--- a/src/gpgpu-sim/power_interface.cc
+++ b/src/gpgpu-sim/power_interface.cc
@@ -1,16 +1,18 @@
-// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, Tayler Hetherington, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, 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.
@@ -27,10 +29,8 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
-
#include "power_interface.h"
-
void init_mcpat(const gpgpu_sim_config &config,
class gpgpu_sim_wrapper *wrapper, unsigned stat_sample_freq,
unsigned tot_inst, unsigned inst) {
@@ -41,11 +41,9 @@ void init_mcpat(const gpgpu_sim_config &config,
config.g_power_simulation_enabled, config.g_power_trace_enabled,
config.g_steady_power_levels_enabled, config.g_power_per_cycle_dump,
config.gpu_steady_power_deviation, config.gpu_steady_min_period,
- config.g_power_trace_zlevel, tot_inst + inst, stat_sample_freq,
- config.g_power_simulation_mode,
- config.g_dvfs_enabled,
- config.get_core_freq()/1000000,
- config.num_shader());
+ config.g_power_trace_zlevel, tot_inst + inst, stat_sample_freq,
+ config.g_power_simulation_mode, config.g_dvfs_enabled,
+ config.get_core_freq() / 1000000, config.num_shader());
}
void mcpat_cycle(const gpgpu_sim_config &config,
@@ -62,8 +60,9 @@ void mcpat_cycle(const gpgpu_sim_config &config,
}
if ((tot_cycle + cycle) % stat_sample_freq == 0) {
- if(dvfs_enabled){
- wrapper->set_model_voltage(1); //performance model needs to support this.
+ if (dvfs_enabled) {
+ wrapper->set_model_voltage(1); // performance model needs to support
+ // this.
}
wrapper->set_inst_power(
@@ -84,14 +83,17 @@ void mcpat_cycle(const gpgpu_sim_config &config,
power_stats->get_inst_c_misses(0));
// Constant Cache, shared memory, texture cache
- wrapper->set_ccache_power(power_stats->get_const_accessess(0), 0); //assuming all HITS in constant cache for now
+ wrapper->set_ccache_power(
+ power_stats->get_const_accessess(0),
+ 0); // assuming all HITS in constant cache for now
wrapper->set_tcache_power(power_stats->get_texture_c_hits(),
power_stats->get_texture_c_misses());
wrapper->set_shrd_mem_power(power_stats->get_shmem_access(0));
- wrapper->set_l1cache_power(
- power_stats->get_l1d_read_hits(0), power_stats->get_l1d_read_misses(0),
- power_stats->get_l1d_write_hits(0), power_stats->get_l1d_write_misses(0));
+ wrapper->set_l1cache_power(power_stats->get_l1d_read_hits(0),
+ power_stats->get_l1d_read_misses(0),
+ power_stats->get_l1d_write_hits(0),
+ power_stats->get_l1d_write_misses(0));
wrapper->set_l2cache_power(
power_stats->get_l2_read_hits(0), power_stats->get_l2_read_misses(0),
@@ -119,24 +121,23 @@ void mcpat_cycle(const gpgpu_sim_config &config,
// Execution pipeline accesses
// FPU (SP) accesses, Integer ALU (not present in Tesla), Sfu accesses
- wrapper->set_int_accesses(power_stats->get_ialu_accessess(0),
- power_stats->get_intmul24_accessess(0),
- power_stats->get_intmul32_accessess(0),
- power_stats->get_intmul_accessess(0),
+ wrapper->set_int_accesses(power_stats->get_ialu_accessess(0),
+ power_stats->get_intmul24_accessess(0),
+ power_stats->get_intmul32_accessess(0),
+ power_stats->get_intmul_accessess(0),
power_stats->get_intdiv_accessess(0));
- wrapper->set_dp_accesses(power_stats->get_dp_accessess(0),
- power_stats->get_dpmul_accessess(0),
- power_stats->get_dpdiv_accessess(0));
+ wrapper->set_dp_accesses(power_stats->get_dp_accessess(0),
+ power_stats->get_dpmul_accessess(0),
+ power_stats->get_dpdiv_accessess(0));
- wrapper->set_fp_accesses(power_stats->get_fp_accessess(0),
- power_stats->get_fpmul_accessess(0),
- power_stats->get_fpdiv_accessess(0));
+ wrapper->set_fp_accesses(power_stats->get_fp_accessess(0),
+ power_stats->get_fpmul_accessess(0),
+ power_stats->get_fpdiv_accessess(0));
- wrapper->set_trans_accesses(power_stats->get_sqrt_accessess(0),
- power_stats->get_log_accessess(0),
- power_stats->get_sin_accessess(0),
- power_stats->get_exp_accessess(0));
+ wrapper->set_trans_accesses(
+ power_stats->get_sqrt_accessess(0), power_stats->get_log_accessess(0),
+ power_stats->get_sin_accessess(0), power_stats->get_exp_accessess(0));
wrapper->set_tensor_accesses(power_stats->get_tensor_accessess(0));
@@ -153,23 +154,21 @@ void mcpat_cycle(const gpgpu_sim_config &config,
(power_stats->get_sp_active_lanes()) / stat_sample_freq;
float avg_sfu_active_lanes =
(power_stats->get_sfu_active_lanes()) / stat_sample_freq;
- if(avg_sp_active_lanes >32.0 )
- avg_sp_active_lanes = 32.0;
- if(avg_sfu_active_lanes >32.0 )
- avg_sfu_active_lanes = 32.0;
+ if (avg_sp_active_lanes > 32.0) avg_sp_active_lanes = 32.0;
+ if (avg_sfu_active_lanes > 32.0) avg_sfu_active_lanes = 32.0;
assert(avg_sp_active_lanes <= 32);
assert(avg_sfu_active_lanes <= 32);
wrapper->set_active_lanes_power(avg_sp_active_lanes, avg_sfu_active_lanes);
- double n_icnt_simt_to_mem =
- (double)
- power_stats->get_icnt_simt_to_mem(0); // # flits from SIMT clusters
- // to memory partitions
- double n_icnt_mem_to_simt =
- (double)
- power_stats->get_icnt_mem_to_simt(0); // # flits from memory
- // partitions to SIMT clusters
- wrapper->set_NoC_power(n_icnt_mem_to_simt + n_icnt_simt_to_mem); // Number of flits traversing the interconnect
+ double n_icnt_simt_to_mem = (double)power_stats->get_icnt_simt_to_mem(
+ 0); // # flits from SIMT clusters
+ // to memory partitions
+ double n_icnt_mem_to_simt = (double)power_stats->get_icnt_mem_to_simt(
+ 0); // # flits from memory
+ // partitions to SIMT clusters
+ wrapper->set_NoC_power(
+ n_icnt_mem_to_simt +
+ n_icnt_simt_to_mem); // Number of flits traversing the interconnect
wrapper->compute();
@@ -190,68 +189,77 @@ void mcpat_reset_perf_count(class gpgpu_sim_wrapper *wrapper) {
wrapper->reset_counters();
}
-bool parse_hw_file(char* hwpowerfile, bool find_target_kernel, vector<string> &hw_data, char* benchname, std::string executed_kernelname){
+bool parse_hw_file(char *hwpowerfile, bool find_target_kernel,
+ vector<string> &hw_data, char *benchname,
+ std::string executed_kernelname) {
fstream hw_file;
hw_file.open(hwpowerfile, ios::in);
string line, word, temp;
- while(!hw_file.eof()){
+ while (!hw_file.eof()) {
hw_data.clear();
getline(hw_file, line);
stringstream s(line);
- while (getline(s,word,',')){
+ while (getline(s, word, ',')) {
hw_data.push_back(word);
}
- if(hw_data[HW_BENCH_NAME] == std::string(benchname)){
- if(find_target_kernel){
- if(hw_data[HW_KERNEL_NAME] == ""){
+ if (hw_data[HW_BENCH_NAME] == std::string(benchname)) {
+ if (find_target_kernel) {
+ if (hw_data[HW_KERNEL_NAME] == "") {
hw_file.close();
return true;
- }
- else{
- if(hw_data[HW_KERNEL_NAME] == executed_kernelname){
+ } else {
+ if (hw_data[HW_KERNEL_NAME] == executed_kernelname) {
hw_file.close();
return true;
}
}
- }
- else{
+ } else {
hw_file.close();
return true;
}
- }
+ }
}
hw_file.close();
return false;
}
-
-void calculate_hw_mcpat(const gpgpu_sim_config &config,
- const shader_core_config *shdr_config,
- class gpgpu_sim_wrapper *wrapper,
- class power_stat_t *power_stats, unsigned stat_sample_freq,
- unsigned tot_cycle, unsigned cycle, unsigned tot_inst,
- unsigned inst, int power_simulation_mode, bool dvfs_enabled, char* hwpowerfile,
- char* benchname, std::string executed_kernelname,
- const bool *accelwattch_hybrid_configuration, bool aggregate_power_stats){
-
+void calculate_hw_mcpat(
+ const gpgpu_sim_config &config, const shader_core_config *shdr_config,
+ class gpgpu_sim_wrapper *wrapper, class power_stat_t *power_stats,
+ unsigned stat_sample_freq, unsigned tot_cycle, unsigned cycle,
+ unsigned tot_inst, unsigned inst, int power_simulation_mode,
+ bool dvfs_enabled, char *hwpowerfile, char *benchname,
+ std::string executed_kernelname,
+ const bool *accelwattch_hybrid_configuration, bool aggregate_power_stats) {
/* Reading HW data from CSV file */
vector<string> hw_data;
bool kernel_found = false;
- kernel_found = parse_hw_file(hwpowerfile, true, hw_data, benchname, executed_kernelname); //Searching for matching executed_kernelname.
- if(!kernel_found)
- kernel_found = parse_hw_file(hwpowerfile, false, hw_data, benchname, executed_kernelname); //Searching for any kernel with same benchname.
- assert("Could not find perf stats for the target benchmark in hwpowerfile.\n" && (kernel_found));
- unsigned perf_cycles = static_cast<unsigned int>(std::stod(hw_data[HW_CYCLES]) + 0.5);
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_CYCLES]))
+ kernel_found = parse_hw_file(
+ hwpowerfile, true, hw_data, benchname,
+ executed_kernelname); // Searching for matching executed_kernelname.
+ if (!kernel_found)
+ kernel_found = parse_hw_file(
+ hwpowerfile, false, hw_data, benchname,
+ executed_kernelname); // Searching for any kernel with same benchname.
+ assert(
+ "Could not find perf stats for the target benchmark in hwpowerfile.\n" &&
+ (kernel_found));
+ unsigned perf_cycles =
+ static_cast<unsigned int>(std::stod(hw_data[HW_CYCLES]) + 0.5);
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_CYCLES]))
perf_cycles = cycle;
- wrapper->init_mcpat_hw_mode(perf_cycles); //total PERF MODEL cycles for current kernel
+ wrapper->init_mcpat_hw_mode(
+ perf_cycles); // total PERF MODEL cycles for current kernel
- if(dvfs_enabled){
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_VOLTAGE]))
- wrapper->set_model_voltage(1); //performance model needs to support this
- else
- wrapper->set_model_voltage(std::stod(hw_data[HW_VOLTAGE])); //performance model needs to support this
+ if (dvfs_enabled) {
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_VOLTAGE]))
+ wrapper->set_model_voltage(1); // performance model needs to support this
+ else
+ wrapper->set_model_voltage(std::stod(
+ hw_data[HW_VOLTAGE])); // performance model needs to support this
}
double l1_read_hits = std::stod(hw_data[HW_L1_RH]);
@@ -259,266 +267,302 @@ void calculate_hw_mcpat(const gpgpu_sim_config &config,
double l1_write_hits = std::stod(hw_data[HW_L1_WH]);
double l1_write_misses = std::stod(hw_data[HW_L1_WM]);
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L1_RH]))
- l1_read_hits = power_stats->get_l1d_read_hits(1) - power_stats->l1r_hits_kernel;
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L1_RM]))
- l1_read_misses = power_stats->get_l1d_read_misses(1) - power_stats->l1r_misses_kernel;
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L1_WH]))
- l1_write_hits = power_stats->get_l1d_write_hits(1) - power_stats->l1w_hits_kernel;
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L1_WM]))
- l1_write_misses = power_stats->get_l1d_write_misses(1) - power_stats->l1w_misses_kernel;
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_L1_RH]))
+ l1_read_hits =
+ power_stats->get_l1d_read_hits(1) - power_stats->l1r_hits_kernel;
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_L1_RM]))
+ l1_read_misses =
+ power_stats->get_l1d_read_misses(1) - power_stats->l1r_misses_kernel;
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_L1_WH]))
+ l1_write_hits =
+ power_stats->get_l1d_write_hits(1) - power_stats->l1w_hits_kernel;
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_L1_WM]))
+ l1_write_misses =
+ power_stats->get_l1d_write_misses(1) - power_stats->l1w_misses_kernel;
- if(aggregate_power_stats){
- power_stats->tot_inst_execution += power_stats->get_total_inst(1);
- power_stats->tot_int_inst_execution += power_stats->get_total_int_inst(1);
- power_stats->tot_fp_inst_execution += power_stats->get_total_fp_inst(1);
- power_stats->commited_inst_execution += power_stats->get_committed_inst(1);
- wrapper->set_inst_power(
- shdr_config->gpgpu_clock_gated_lanes, cycle, //TODO: core.[0] cycles counts don't matter, remove this
+ if (aggregate_power_stats) {
+ power_stats->tot_inst_execution += power_stats->get_total_inst(1);
+ power_stats->tot_int_inst_execution += power_stats->get_total_int_inst(1);
+ power_stats->tot_fp_inst_execution += power_stats->get_total_fp_inst(1);
+ power_stats->commited_inst_execution += power_stats->get_committed_inst(1);
+ wrapper->set_inst_power(
+ shdr_config->gpgpu_clock_gated_lanes,
+ cycle, // TODO: core.[0] cycles counts don't matter, remove this
cycle, power_stats->tot_inst_execution,
power_stats->tot_int_inst_execution, power_stats->tot_fp_inst_execution,
- l1_read_hits + l1_read_misses,
- l1_write_hits + l1_write_misses,
+ l1_read_hits + l1_read_misses, l1_write_hits + l1_write_misses,
power_stats->commited_inst_execution);
- }
- else{
+ } else {
wrapper->set_inst_power(
- shdr_config->gpgpu_clock_gated_lanes, cycle, //TODO: core.[0] cycles counts don't matter, remove this
+ shdr_config->gpgpu_clock_gated_lanes,
+ cycle, // TODO: core.[0] cycles counts don't matter, remove this
cycle, power_stats->get_total_inst(1),
power_stats->get_total_int_inst(1), power_stats->get_total_fp_inst(1),
- l1_read_hits + l1_read_misses,
- l1_write_hits + l1_write_misses,
+ l1_read_hits + l1_read_misses, l1_write_hits + l1_write_misses,
power_stats->get_committed_inst(1));
- }
+ }
- // Single RF for both int and fp ops -- activity factor set to 0 for Accelwattch HW and Accelwattch Hybrid because no HW Perf Stats for register files
- wrapper->set_regfile_power(power_stats->get_regfile_reads(1),
- power_stats->get_regfile_writes(1),
- power_stats->get_non_regfile_operands(1));
+ // Single RF for both int and fp ops -- activity factor set to 0 for
+ // Accelwattch HW and Accelwattch Hybrid because no HW Perf Stats for register
+ // files
+ wrapper->set_regfile_power(power_stats->get_regfile_reads(1),
+ power_stats->get_regfile_writes(1),
+ power_stats->get_non_regfile_operands(1));
- // Instruction cache stats -- activity factor set to 0 for Accelwattch HW and Accelwattch Hybrid because no HW Perf Stats for instruction cache
- wrapper->set_icache_power(power_stats->get_inst_c_hits(1) - power_stats->l1i_hits_kernel,
- power_stats->get_inst_c_misses(1) - power_stats->l1i_misses_kernel);
+ // Instruction cache stats -- activity factor set to 0 for Accelwattch HW and
+ // Accelwattch Hybrid because no HW Perf Stats for instruction cache
+ wrapper->set_icache_power(
+ power_stats->get_inst_c_hits(1) - power_stats->l1i_hits_kernel,
+ power_stats->get_inst_c_misses(1) - power_stats->l1i_misses_kernel);
- // Constant Cache, shared memory, texture cache
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_CC_ACC]))
- wrapper->set_ccache_power(power_stats->get_const_accessess(1) - power_stats->cc_accesses_kernel, 0); //assuming all HITS in constant cache for now
- else
- wrapper->set_ccache_power(std::stod(hw_data[HW_CC_ACC]), 0); //assuming all HITS in constant cache for now
+ // Constant Cache, shared memory, texture cache
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_CC_ACC]))
+ wrapper->set_ccache_power(
+ power_stats->get_const_accessess(1) - power_stats->cc_accesses_kernel,
+ 0); // assuming all HITS in constant cache for now
+ else
+ wrapper->set_ccache_power(
+ std::stod(hw_data[HW_CC_ACC]),
+ 0); // assuming all HITS in constant cache for now
-
- // wrapper->set_tcache_power(power_stats->get_texture_c_hits(),
- // power_stats->get_texture_c_misses());
+ // wrapper->set_tcache_power(power_stats->get_texture_c_hits(),
+ // power_stats->get_texture_c_misses());
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_SHRD_ACC]))
- wrapper->set_shrd_mem_power(power_stats->get_shmem_access(1) - power_stats->shared_accesses_kernel);
- else
- wrapper->set_shrd_mem_power(std::stod(hw_data[HW_SHRD_ACC]));
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_SHRD_ACC]))
+ wrapper->set_shrd_mem_power(power_stats->get_shmem_access(1) -
+ power_stats->shared_accesses_kernel);
+ else
+ wrapper->set_shrd_mem_power(std::stod(hw_data[HW_SHRD_ACC]));
- wrapper->set_l1cache_power( l1_read_hits, l1_read_misses, l1_write_hits, l1_write_misses);
+ wrapper->set_l1cache_power(l1_read_hits, l1_read_misses, l1_write_hits,
+ l1_write_misses);
- double l2_read_hits = std::stod(hw_data[HW_L2_RH]);
- double l2_read_misses = std::stod(hw_data[HW_L2_RM]);
- double l2_write_hits = std::stod(hw_data[HW_L2_WH]);
- double l2_write_misses = std::stod(hw_data[HW_L2_WM]);
+ double l2_read_hits = std::stod(hw_data[HW_L2_RH]);
+ double l2_read_misses = std::stod(hw_data[HW_L2_RM]);
+ double l2_write_hits = std::stod(hw_data[HW_L2_WH]);
+ double l2_write_misses = std::stod(hw_data[HW_L2_WM]);
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L2_RH]))
- l2_read_hits = power_stats->get_l2_read_hits(1) - power_stats->l2r_hits_kernel;
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L2_RM]))
- l2_read_misses = power_stats->get_l2_read_misses(1) - power_stats->l2r_misses_kernel;
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L2_WH]))
- l2_write_hits = power_stats->get_l2_write_hits(1) - power_stats->l2w_hits_kernel;
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L2_WM]))
- l2_write_misses = power_stats->get_l2_write_misses(1) - power_stats->l2w_misses_kernel;
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_L2_RH]))
+ l2_read_hits =
+ power_stats->get_l2_read_hits(1) - power_stats->l2r_hits_kernel;
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_L2_RM]))
+ l2_read_misses =
+ power_stats->get_l2_read_misses(1) - power_stats->l2r_misses_kernel;
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_L2_WH]))
+ l2_write_hits =
+ power_stats->get_l2_write_hits(1) - power_stats->l2w_hits_kernel;
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_L2_WM]))
+ l2_write_misses =
+ power_stats->get_l2_write_misses(1) - power_stats->l2w_misses_kernel;
- wrapper->set_l2cache_power(l2_read_hits, l2_read_misses, l2_write_hits, l2_write_misses);
-
- float active_sms = (*power_stats->m_active_sms) / stat_sample_freq;
- float num_cores = shdr_config->num_shader();
- float num_idle_core = num_cores - active_sms;
- wrapper->set_num_cores(num_cores);
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_NUM_SM_IDLE]))
- wrapper->set_idle_core_power(num_idle_core);
- else
- wrapper->set_idle_core_power(std::stod(hw_data[HW_NUM_SM_IDLE]));
+ wrapper->set_l2cache_power(l2_read_hits, l2_read_misses, l2_write_hits,
+ l2_write_misses);
- float pipeline_duty_cycle =
- ((*power_stats->m_average_pipeline_duty_cycle / (stat_sample_freq)) <
- 0.8)
- ? ((*power_stats->m_average_pipeline_duty_cycle) / stat_sample_freq)
- : 0.8;
-
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_PIPE_DUTY]))
- wrapper->set_duty_cycle_power(pipeline_duty_cycle);
- else
- wrapper->set_duty_cycle_power(std::stod(hw_data[HW_PIPE_DUTY]));
+ float active_sms = (*power_stats->m_active_sms) / stat_sample_freq;
+ float num_cores = shdr_config->num_shader();
+ float num_idle_core = num_cores - active_sms;
+ wrapper->set_num_cores(num_cores);
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_NUM_SM_IDLE]))
+ wrapper->set_idle_core_power(num_idle_core);
+ else
+ wrapper->set_idle_core_power(std::stod(hw_data[HW_NUM_SM_IDLE]));
- // Memory Controller
-
- double dram_reads = std::stod(hw_data[HW_DRAM_RD]);
- double dram_writes = std::stod(hw_data[HW_DRAM_WR]);
- double dram_pre = 0;
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_DRAM_RD]))
- dram_reads = power_stats->get_dram_rd(1) - power_stats->dram_rd_kernel;
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_DRAM_WR]))
- dram_writes = power_stats->get_dram_wr(1) - power_stats->dram_wr_kernel;
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_DRAM_RD]))
- dram_pre = power_stats->get_dram_pre(1) - power_stats->dram_pre_kernel;
+ float pipeline_duty_cycle =
+ ((*power_stats->m_average_pipeline_duty_cycle / (stat_sample_freq)) < 0.8)
+ ? ((*power_stats->m_average_pipeline_duty_cycle) / stat_sample_freq)
+ : 0.8;
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_PIPE_DUTY]))
+ wrapper->set_duty_cycle_power(pipeline_duty_cycle);
+ else
+ wrapper->set_duty_cycle_power(std::stod(hw_data[HW_PIPE_DUTY]));
- wrapper->set_mem_ctrl_power(dram_reads, dram_writes, dram_pre);
+ // Memory Controller
- if(aggregate_power_stats){
- power_stats->ialu_acc_execution += power_stats->get_ialu_accessess(1);
- power_stats->imul24_acc_execution += power_stats->get_intmul24_accessess(1);
- power_stats->imul32_acc_execution += power_stats->get_intmul32_accessess(1);
- power_stats->imul_acc_execution += power_stats->get_intmul_accessess(1);
- power_stats->idiv_acc_execution += power_stats->get_intdiv_accessess(1);
- power_stats->dp_acc_execution += power_stats->get_dp_accessess(1);
- power_stats->dpmul_acc_execution += power_stats->get_dpmul_accessess(1);
- power_stats->dpdiv_acc_execution += power_stats->get_dpdiv_accessess(1);
- power_stats->fp_acc_execution += power_stats->get_fp_accessess(1);
- power_stats->fpmul_acc_execution += power_stats->get_fpmul_accessess(1);
- power_stats->fpdiv_acc_execution += power_stats->get_fpdiv_accessess(1);
- power_stats->sqrt_acc_execution += power_stats->get_sqrt_accessess(1);
- power_stats->log_acc_execution += power_stats->get_log_accessess(1);
- power_stats->sin_acc_execution += power_stats->get_sin_accessess(1);
- power_stats->exp_acc_execution += power_stats->get_exp_accessess(1);
- power_stats->tensor_acc_execution += power_stats->get_tensor_accessess(1);
- power_stats->tex_acc_execution += power_stats->get_tex_accessess(1);
- power_stats->tot_fpu_acc_execution += power_stats->get_tot_fpu_accessess(1);
- power_stats->tot_sfu_acc_execution += power_stats->get_tot_sfu_accessess(1);
- power_stats->tot_threads_acc_execution += power_stats->get_tot_threads_kernel(1);
- power_stats->tot_warps_acc_execution += power_stats->get_tot_warps_kernel(1);
-
- power_stats->sp_active_lanes_execution += (power_stats->get_sp_active_lanes() * shdr_config->num_shader() * shdr_config->gpgpu_num_sp_units);
- power_stats->sfu_active_lanes_execution += (power_stats->get_sfu_active_lanes() * shdr_config->num_shader() * shdr_config->gpgpu_num_sp_units);
+ double dram_reads = std::stod(hw_data[HW_DRAM_RD]);
+ double dram_writes = std::stod(hw_data[HW_DRAM_WR]);
+ double dram_pre = 0;
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_DRAM_RD]))
+ dram_reads = power_stats->get_dram_rd(1) - power_stats->dram_rd_kernel;
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_DRAM_WR]))
+ dram_writes = power_stats->get_dram_wr(1) - power_stats->dram_wr_kernel;
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_DRAM_RD]))
+ dram_pre = power_stats->get_dram_pre(1) - power_stats->dram_pre_kernel;
- wrapper->set_int_accesses(power_stats->ialu_acc_execution,
- power_stats->imul24_acc_execution,
- power_stats->imul32_acc_execution,
- power_stats->imul_acc_execution,
- power_stats->idiv_acc_execution);
+ wrapper->set_mem_ctrl_power(dram_reads, dram_writes, dram_pre);
- wrapper->set_dp_accesses(power_stats->dp_acc_execution,
- power_stats->dpmul_acc_execution,
- power_stats->dpdiv_acc_execution);
+ if (aggregate_power_stats) {
+ power_stats->ialu_acc_execution += power_stats->get_ialu_accessess(1);
+ power_stats->imul24_acc_execution += power_stats->get_intmul24_accessess(1);
+ power_stats->imul32_acc_execution += power_stats->get_intmul32_accessess(1);
+ power_stats->imul_acc_execution += power_stats->get_intmul_accessess(1);
+ power_stats->idiv_acc_execution += power_stats->get_intdiv_accessess(1);
+ power_stats->dp_acc_execution += power_stats->get_dp_accessess(1);
+ power_stats->dpmul_acc_execution += power_stats->get_dpmul_accessess(1);
+ power_stats->dpdiv_acc_execution += power_stats->get_dpdiv_accessess(1);
+ power_stats->fp_acc_execution += power_stats->get_fp_accessess(1);
+ power_stats->fpmul_acc_execution += power_stats->get_fpmul_accessess(1);
+ power_stats->fpdiv_acc_execution += power_stats->get_fpdiv_accessess(1);
+ power_stats->sqrt_acc_execution += power_stats->get_sqrt_accessess(1);
+ power_stats->log_acc_execution += power_stats->get_log_accessess(1);
+ power_stats->sin_acc_execution += power_stats->get_sin_accessess(1);
+ power_stats->exp_acc_execution += power_stats->get_exp_accessess(1);
+ power_stats->tensor_acc_execution += power_stats->get_tensor_accessess(1);
+ power_stats->tex_acc_execution += power_stats->get_tex_accessess(1);
+ power_stats->tot_fpu_acc_execution += power_stats->get_tot_fpu_accessess(1);
+ power_stats->tot_sfu_acc_execution += power_stats->get_tot_sfu_accessess(1);
+ power_stats->tot_threads_acc_execution +=
+ power_stats->get_tot_threads_kernel(1);
+ power_stats->tot_warps_acc_execution +=
+ power_stats->get_tot_warps_kernel(1);
- wrapper->set_fp_accesses(power_stats->fp_acc_execution,
- power_stats->fpmul_acc_execution,
- power_stats->fpdiv_acc_execution);
+ power_stats->sp_active_lanes_execution +=
+ (power_stats->get_sp_active_lanes() * shdr_config->num_shader() *
+ shdr_config->gpgpu_num_sp_units);
+ power_stats->sfu_active_lanes_execution +=
+ (power_stats->get_sfu_active_lanes() * shdr_config->num_shader() *
+ shdr_config->gpgpu_num_sp_units);
- wrapper->set_trans_accesses(power_stats->sqrt_acc_execution,
- power_stats->log_acc_execution,
- power_stats->sin_acc_execution,
- power_stats->exp_acc_execution);
+ wrapper->set_int_accesses(
+ power_stats->ialu_acc_execution, power_stats->imul24_acc_execution,
+ power_stats->imul32_acc_execution, power_stats->imul_acc_execution,
+ power_stats->idiv_acc_execution);
- wrapper->set_tensor_accesses(power_stats->tensor_acc_execution);
+ wrapper->set_dp_accesses(power_stats->dp_acc_execution,
+ power_stats->dpmul_acc_execution,
+ power_stats->dpdiv_acc_execution);
- wrapper->set_tex_accesses(power_stats->tex_acc_execution);
+ wrapper->set_fp_accesses(power_stats->fp_acc_execution,
+ power_stats->fpmul_acc_execution,
+ power_stats->fpdiv_acc_execution);
- wrapper->set_exec_unit_power(power_stats->ialu_acc_execution,
- power_stats->tot_fpu_acc_execution,
- power_stats->tot_sfu_acc_execution);
+ wrapper->set_trans_accesses(
+ power_stats->sqrt_acc_execution, power_stats->log_acc_execution,
+ power_stats->sin_acc_execution, power_stats->exp_acc_execution);
- wrapper->set_avg_active_threads((double)((double)power_stats->tot_threads_acc_execution / (double)power_stats->tot_warps_acc_execution));
+ wrapper->set_tensor_accesses(power_stats->tensor_acc_execution);
- // Average active lanes for sp and sfu pipelines
- float avg_sp_active_lanes =
- (power_stats->sp_active_lanes_execution) / shdr_config->num_shader() / shdr_config->gpgpu_num_sp_units / stat_sample_freq;
- float avg_sfu_active_lanes =
- (power_stats->sfu_active_lanes_execution) / shdr_config->num_shader() / shdr_config->gpgpu_num_sp_units / stat_sample_freq;
- if(avg_sp_active_lanes >32.0 )
- avg_sp_active_lanes = 32.0;
- if(avg_sfu_active_lanes >32.0 )
- avg_sfu_active_lanes = 32.0;
- assert(avg_sp_active_lanes <= 32);
- assert(avg_sfu_active_lanes <= 32);
- wrapper->set_active_lanes_power(avg_sp_active_lanes, avg_sfu_active_lanes);
- }
- else{
- wrapper->set_int_accesses(power_stats->get_ialu_accessess(1),
- power_stats->get_intmul24_accessess(1),
- power_stats->get_intmul32_accessess(1),
- power_stats->get_intmul_accessess(1),
- power_stats->get_intdiv_accessess(1));
+ wrapper->set_tex_accesses(power_stats->tex_acc_execution);
- wrapper->set_dp_accesses(power_stats->get_dp_accessess(1),
- power_stats->get_dpmul_accessess(1),
- power_stats->get_dpdiv_accessess(1));
+ wrapper->set_exec_unit_power(power_stats->ialu_acc_execution,
+ power_stats->tot_fpu_acc_execution,
+ power_stats->tot_sfu_acc_execution);
- wrapper->set_fp_accesses(power_stats->get_fp_accessess(1),
- power_stats->get_fpmul_accessess(1),
- power_stats->get_fpdiv_accessess(1));
+ wrapper->set_avg_active_threads(
+ (double)((double)power_stats->tot_threads_acc_execution /
+ (double)power_stats->tot_warps_acc_execution));
- wrapper->set_trans_accesses(power_stats->get_sqrt_accessess(1),
- power_stats->get_log_accessess(1),
- power_stats->get_sin_accessess(1),
- power_stats->get_exp_accessess(1));
+ // Average active lanes for sp and sfu pipelines
+ float avg_sp_active_lanes =
+ (power_stats->sp_active_lanes_execution) / shdr_config->num_shader() /
+ shdr_config->gpgpu_num_sp_units / stat_sample_freq;
+ float avg_sfu_active_lanes =
+ (power_stats->sfu_active_lanes_execution) / shdr_config->num_shader() /
+ shdr_config->gpgpu_num_sp_units / stat_sample_freq;
+ if (avg_sp_active_lanes > 32.0) avg_sp_active_lanes = 32.0;
+ if (avg_sfu_active_lanes > 32.0) avg_sfu_active_lanes = 32.0;
+ assert(avg_sp_active_lanes <= 32);
+ assert(avg_sfu_active_lanes <= 32);
+ wrapper->set_active_lanes_power(avg_sp_active_lanes, avg_sfu_active_lanes);
+ } else {
+ wrapper->set_int_accesses(power_stats->get_ialu_accessess(1),
+ power_stats->get_intmul24_accessess(1),
+ power_stats->get_intmul32_accessess(1),
+ power_stats->get_intmul_accessess(1),
+ power_stats->get_intdiv_accessess(1));
- wrapper->set_tensor_accesses(power_stats->get_tensor_accessess(1));
+ wrapper->set_dp_accesses(power_stats->get_dp_accessess(1),
+ power_stats->get_dpmul_accessess(1),
+ power_stats->get_dpdiv_accessess(1));
- wrapper->set_tex_accesses(power_stats->get_tex_accessess(1));
+ wrapper->set_fp_accesses(power_stats->get_fp_accessess(1),
+ power_stats->get_fpmul_accessess(1),
+ power_stats->get_fpdiv_accessess(1));
- wrapper->set_exec_unit_power(power_stats->get_tot_fpu_accessess(1),
- power_stats->get_ialu_accessess(1),
- power_stats->get_tot_sfu_accessess(1));
+ wrapper->set_trans_accesses(
+ power_stats->get_sqrt_accessess(1), power_stats->get_log_accessess(1),
+ power_stats->get_sin_accessess(1), power_stats->get_exp_accessess(1));
- wrapper->set_avg_active_threads(power_stats->get_active_threads(1));
+ wrapper->set_tensor_accesses(power_stats->get_tensor_accessess(1));
- // Average active lanes for sp and sfu pipelines
- float avg_sp_active_lanes =
- (power_stats->get_sp_active_lanes()) / stat_sample_freq;
- float avg_sfu_active_lanes =
- (power_stats->get_sfu_active_lanes()) / stat_sample_freq;
- if(avg_sp_active_lanes >32.0 )
- avg_sp_active_lanes = 32.0;
- if(avg_sfu_active_lanes >32.0 )
- avg_sfu_active_lanes = 32.0;
- assert(avg_sp_active_lanes <= 32);
- assert(avg_sfu_active_lanes <= 32);
- wrapper->set_active_lanes_power(avg_sp_active_lanes, avg_sfu_active_lanes);
- }
+ wrapper->set_tex_accesses(power_stats->get_tex_accessess(1));
-
- double n_icnt_simt_to_mem =
- (double)
- (power_stats->get_icnt_simt_to_mem(1) - power_stats->noc_tr_kernel); // # flits from SIMT clusters
- // to memory partitions
- double n_icnt_mem_to_simt =
- (double)
- (power_stats->get_icnt_mem_to_simt(1)- power_stats->noc_rc_kernel); // # flits from memory
- // partitions to SIMT clusters
- if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_NOC]))
- wrapper->set_NoC_power(n_icnt_mem_to_simt + n_icnt_simt_to_mem); // Number of flits traversing the interconnect from Accel-Sim
- else
- wrapper->set_NoC_power(std::stod(hw_data[HW_NOC])); // Number of flits traversing the interconnect from HW
-
- wrapper->compute();
+ wrapper->set_exec_unit_power(power_stats->get_tot_fpu_accessess(1),
+ power_stats->get_ialu_accessess(1),
+ power_stats->get_tot_sfu_accessess(1));
- wrapper->update_components_power();
+ wrapper->set_avg_active_threads(power_stats->get_active_threads(1));
- wrapper->power_metrics_calculations();
+ // Average active lanes for sp and sfu pipelines
+ float avg_sp_active_lanes =
+ (power_stats->get_sp_active_lanes()) / stat_sample_freq;
+ float avg_sfu_active_lanes =
+ (power_stats->get_sfu_active_lanes()) / stat_sample_freq;
+ if (avg_sp_active_lanes > 32.0) avg_sp_active_lanes = 32.0;
+ if (avg_sfu_active_lanes > 32.0) avg_sfu_active_lanes = 32.0;
+ assert(avg_sp_active_lanes <= 32);
+ assert(avg_sfu_active_lanes <= 32);
+ wrapper->set_active_lanes_power(avg_sp_active_lanes, avg_sfu_active_lanes);
+ }
- wrapper->dump();
- power_stats->l1r_hits_kernel = power_stats->get_l1d_read_hits(1);
- power_stats->l1r_misses_kernel = power_stats->get_l1d_read_misses(1);
- power_stats->l1w_hits_kernel = power_stats->get_l1d_write_hits(1);
- power_stats->l1w_misses_kernel = power_stats->get_l1d_write_misses(1);
- power_stats->shared_accesses_kernel = power_stats->get_const_accessess(1);
- power_stats->cc_accesses_kernel = power_stats->get_shmem_access(1);
- power_stats->dram_rd_kernel = power_stats->get_dram_rd(1);
- power_stats->dram_wr_kernel = power_stats->get_dram_wr(1);
- power_stats->dram_pre_kernel = power_stats->get_dram_pre(1);
- power_stats->l1i_hits_kernel = power_stats->get_inst_c_hits(1);
- power_stats->l1i_misses_kernel = power_stats->get_inst_c_misses(1);
- power_stats->l2r_hits_kernel = power_stats->get_l2_read_hits(1);
- power_stats->l2r_misses_kernel = power_stats->get_l2_read_misses(1);
- power_stats->l2w_hits_kernel = power_stats->get_l2_write_hits(1);
- power_stats->l2w_misses_kernel = power_stats->get_l2_write_misses(1);
- power_stats->noc_tr_kernel = power_stats->get_icnt_simt_to_mem(1);
- power_stats->noc_rc_kernel = power_stats->get_icnt_mem_to_simt(1);
+ double n_icnt_simt_to_mem =
+ (double)(power_stats->get_icnt_simt_to_mem(1) -
+ power_stats->noc_tr_kernel); // # flits from SIMT clusters
+ // to memory partitions
+ double n_icnt_mem_to_simt =
+ (double)(power_stats->get_icnt_mem_to_simt(1) -
+ power_stats->noc_rc_kernel); // # flits from memory
+ // partitions to SIMT clusters
+ if ((power_simulation_mode == 2) &&
+ (accelwattch_hybrid_configuration[HW_NOC]))
+ wrapper->set_NoC_power(
+ n_icnt_mem_to_simt +
+ n_icnt_simt_to_mem); // Number of flits traversing the interconnect
+ // from Accel-Sim
+ else
+ wrapper->set_NoC_power(
+ std::stod(hw_data[HW_NOC])); // Number of flits traversing the
+ // interconnect from HW
+
+ wrapper->compute();
+
+ wrapper->update_components_power();
+
+ wrapper->power_metrics_calculations();
+ wrapper->dump();
+ power_stats->l1r_hits_kernel = power_stats->get_l1d_read_hits(1);
+ power_stats->l1r_misses_kernel = power_stats->get_l1d_read_misses(1);
+ power_stats->l1w_hits_kernel = power_stats->get_l1d_write_hits(1);
+ power_stats->l1w_misses_kernel = power_stats->get_l1d_write_misses(1);
+ power_stats->shared_accesses_kernel = power_stats->get_const_accessess(1);
+ power_stats->cc_accesses_kernel = power_stats->get_shmem_access(1);
+ power_stats->dram_rd_kernel = power_stats->get_dram_rd(1);
+ power_stats->dram_wr_kernel = power_stats->get_dram_wr(1);
+ power_stats->dram_pre_kernel = power_stats->get_dram_pre(1);
+ power_stats->l1i_hits_kernel = power_stats->get_inst_c_hits(1);
+ power_stats->l1i_misses_kernel = power_stats->get_inst_c_misses(1);
+ power_stats->l2r_hits_kernel = power_stats->get_l2_read_hits(1);
+ power_stats->l2r_misses_kernel = power_stats->get_l2_read_misses(1);
+ power_stats->l2w_hits_kernel = power_stats->get_l2_write_hits(1);
+ power_stats->l2w_misses_kernel = power_stats->get_l2_write_misses(1);
+ power_stats->noc_tr_kernel = power_stats->get_icnt_simt_to_mem(1);
+ power_stats->noc_rc_kernel = power_stats->get_icnt_mem_to_simt(1);
- power_stats->clear();
+ power_stats->clear();
} \ No newline at end of file
diff --git a/src/gpgpu-sim/power_interface.h b/src/gpgpu-sim/power_interface.h
index 1a48894..3c043e6 100644
--- a/src/gpgpu-sim/power_interface.h
+++ b/src/gpgpu-sim/power_interface.h
@@ -1,16 +1,18 @@
-// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, Tayler Hetherington, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, 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.
@@ -46,16 +48,18 @@ void mcpat_cycle(const gpgpu_sim_config &config,
unsigned tot_cycle, unsigned cycle, unsigned tot_inst,
unsigned inst, bool dvfs_enabled);
-void calculate_hw_mcpat(const gpgpu_sim_config &config,
- const shader_core_config *shdr_config,
- class gpgpu_sim_wrapper *wrapper,
- class power_stat_t *power_stats, unsigned stat_sample_freq,
- unsigned tot_cycle, unsigned cycle, unsigned tot_inst,
- unsigned inst, int power_simulation_mode, bool dvfs_enabled,
- char* hwpowerfile, char* benchname, std::string executed_kernelname,
- const bool *accelwattch_hybrid_configuration, bool aggregate_power_stats);
+void calculate_hw_mcpat(
+ const gpgpu_sim_config &config, const shader_core_config *shdr_config,
+ class gpgpu_sim_wrapper *wrapper, class power_stat_t *power_stats,
+ unsigned stat_sample_freq, unsigned tot_cycle, unsigned cycle,
+ unsigned tot_inst, unsigned inst, int power_simulation_mode,
+ bool dvfs_enabled, char *hwpowerfile, char *benchname,
+ std::string executed_kernelname,
+ const bool *accelwattch_hybrid_configuration, bool aggregate_power_stats);
-bool parse_hw_file(char* hwpowerfile, bool find_target_kernel, vector<string> &hw_data, char* benchname, std::string executed_kernelname);
+bool parse_hw_file(char *hwpowerfile, bool find_target_kernel,
+ vector<string> &hw_data, char *benchname,
+ std::string executed_kernelname);
void mcpat_reset_perf_count(class gpgpu_sim_wrapper *wrapper);
diff --git a/src/gpgpu-sim/power_stat.cc b/src/gpgpu-sim/power_stat.cc
index fd7a775..764652b 100644
--- a/src/gpgpu-sim/power_stat.cc
+++ b/src/gpgpu-sim/power_stat.cc
@@ -1,16 +1,18 @@
-// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, Tayler Hetherington, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, 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.
@@ -55,60 +57,58 @@ power_mem_stat_t::power_mem_stat_t(const memory_config *mem_config,
init();
}
-void power_stat_t::clear(){
- for(unsigned i=0; i< NUM_STAT_IDX; ++i){
+void power_stat_t::clear() {
+ for (unsigned i = 0; i < NUM_STAT_IDX; ++i) {
pwr_mem_stat->core_cache_stats[i].clear();
pwr_mem_stat->l2_cache_stats[i].clear();
- for(unsigned j=0; j<m_config->num_shader(); ++j){
- pwr_core_stat->m_pipeline_duty_cycle[i][j]=0;
- pwr_core_stat->m_num_decoded_insn[i][j]=0;
- pwr_core_stat->m_num_FPdecoded_insn[i][j]=0;
- pwr_core_stat->m_num_INTdecoded_insn[i][j]=0;
- pwr_core_stat->m_num_storequeued_insn[i][j]=0;
- pwr_core_stat->m_num_loadqueued_insn[i][j]=0;
- pwr_core_stat->m_num_tex_inst[i][j]=0;
- pwr_core_stat->m_num_ialu_acesses[i][j]=0;
- pwr_core_stat->m_num_fp_acesses[i][j]=0;
- pwr_core_stat->m_num_imul_acesses[i][j]=0;
- pwr_core_stat->m_num_imul24_acesses[i][j]=0;
- pwr_core_stat->m_num_imul32_acesses[i][j]=0;
- pwr_core_stat->m_num_fpmul_acesses[i][j]=0;
- pwr_core_stat->m_num_idiv_acesses[i][j]=0;
- pwr_core_stat->m_num_fpdiv_acesses[i][j]=0;
- pwr_core_stat->m_num_dp_acesses[i][j]=0;
- pwr_core_stat->m_num_dpmul_acesses[i][j]=0;
- pwr_core_stat->m_num_dpdiv_acesses[i][j]=0;
- pwr_core_stat->m_num_tensor_core_acesses[i][j]=0;
- pwr_core_stat->m_num_const_acesses[i][j]=0;
- pwr_core_stat->m_num_tex_acesses[i][j]=0;
- pwr_core_stat->m_num_sp_acesses[i][j]=0;
- pwr_core_stat->m_num_sfu_acesses[i][j]=0;
- pwr_core_stat->m_num_sqrt_acesses[i][j]=0;
- pwr_core_stat->m_num_log_acesses[i][j]=0;
- pwr_core_stat->m_num_sin_acesses[i][j]=0;
- pwr_core_stat->m_num_exp_acesses[i][j]=0;
- pwr_core_stat->m_num_mem_acesses[i][j]=0;
- pwr_core_stat->m_num_sp_committed[i][j]=0;
- pwr_core_stat->m_num_sfu_committed[i][j]=0;
- pwr_core_stat->m_num_mem_committed[i][j]=0;
- pwr_core_stat->m_read_regfile_acesses[i][j]=0;
- pwr_core_stat->m_write_regfile_acesses[i][j]=0;
- pwr_core_stat->m_non_rf_operands[i][j]=0;
- pwr_core_stat->m_active_sp_lanes[i][j]=0;
- pwr_core_stat->m_active_sfu_lanes[i][j]=0;
- pwr_core_stat->m_active_exu_threads[i][j]=0;
- pwr_core_stat->m_active_exu_warps[i][j]=0;
+ for (unsigned j = 0; j < m_config->num_shader(); ++j) {
+ pwr_core_stat->m_pipeline_duty_cycle[i][j] = 0;
+ pwr_core_stat->m_num_decoded_insn[i][j] = 0;
+ pwr_core_stat->m_num_FPdecoded_insn[i][j] = 0;
+ pwr_core_stat->m_num_INTdecoded_insn[i][j] = 0;
+ pwr_core_stat->m_num_storequeued_insn[i][j] = 0;
+ pwr_core_stat->m_num_loadqueued_insn[i][j] = 0;
+ pwr_core_stat->m_num_tex_inst[i][j] = 0;
+ pwr_core_stat->m_num_ialu_acesses[i][j] = 0;
+ pwr_core_stat->m_num_fp_acesses[i][j] = 0;
+ pwr_core_stat->m_num_imul_acesses[i][j] = 0;
+ pwr_core_stat->m_num_imul24_acesses[i][j] = 0;
+ pwr_core_stat->m_num_imul32_acesses[i][j] = 0;
+ pwr_core_stat->m_num_fpmul_acesses[i][j] = 0;
+ pwr_core_stat->m_num_idiv_acesses[i][j] = 0;
+ pwr_core_stat->m_num_fpdiv_acesses[i][j] = 0;
+ pwr_core_stat->m_num_dp_acesses[i][j] = 0;
+ pwr_core_stat->m_num_dpmul_acesses[i][j] = 0;
+ pwr_core_stat->m_num_dpdiv_acesses[i][j] = 0;
+ pwr_core_stat->m_num_tensor_core_acesses[i][j] = 0;
+ pwr_core_stat->m_num_const_acesses[i][j] = 0;
+ pwr_core_stat->m_num_tex_acesses[i][j] = 0;
+ pwr_core_stat->m_num_sp_acesses[i][j] = 0;
+ pwr_core_stat->m_num_sfu_acesses[i][j] = 0;
+ pwr_core_stat->m_num_sqrt_acesses[i][j] = 0;
+ pwr_core_stat->m_num_log_acesses[i][j] = 0;
+ pwr_core_stat->m_num_sin_acesses[i][j] = 0;
+ pwr_core_stat->m_num_exp_acesses[i][j] = 0;
+ pwr_core_stat->m_num_mem_acesses[i][j] = 0;
+ pwr_core_stat->m_num_sp_committed[i][j] = 0;
+ pwr_core_stat->m_num_sfu_committed[i][j] = 0;
+ pwr_core_stat->m_num_mem_committed[i][j] = 0;
+ pwr_core_stat->m_read_regfile_acesses[i][j] = 0;
+ pwr_core_stat->m_write_regfile_acesses[i][j] = 0;
+ pwr_core_stat->m_non_rf_operands[i][j] = 0;
+ pwr_core_stat->m_active_sp_lanes[i][j] = 0;
+ pwr_core_stat->m_active_sfu_lanes[i][j] = 0;
+ pwr_core_stat->m_active_exu_threads[i][j] = 0;
+ pwr_core_stat->m_active_exu_warps[i][j] = 0;
}
for (unsigned j = 0; j < m_mem_config->m_n_mem; ++j) {
- pwr_mem_stat->n_rd[i][j]=0;
- pwr_mem_stat->n_wr[i][j]=0;
- pwr_mem_stat->n_pre[i][j]=0;
+ pwr_mem_stat->n_rd[i][j] = 0;
+ pwr_mem_stat->n_wr[i][j] = 0;
+ pwr_mem_stat->n_pre[i][j] = 0;
}
}
}
-
-
void power_mem_stat_t::init() {
shmem_access[CURRENT_STAT_IDX] =
m_core_stats->gpgpu_n_shmem_bank_access; // Shared memory access
@@ -174,17 +174,18 @@ void power_mem_stat_t::print(FILE *fout) const {
unsigned total_mem_writes = 0;
for (unsigned i = 0; i < m_config->m_n_mem; ++i) {
total_mem_reads += n_rd[CURRENT_STAT_IDX][i];
- total_mem_writes += n_wr[CURRENT_STAT_IDX][i] + n_wr_WB[CURRENT_STAT_IDX][i];
+ total_mem_writes +=
+ n_wr[CURRENT_STAT_IDX][i] + n_wr_WB[CURRENT_STAT_IDX][i];
}
fprintf(fout, "Total memory controller accesses: %u\n",
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,
@@ -204,165 +205,272 @@ void power_core_stat_t::print(FILE *fout) {
// per core statistics
fprintf(fout, "Power Metrics: \n");
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- fprintf(fout,"core %u:\n",i);
- fprintf(fout,"\tpipeline duty cycle =%f\n",m_pipeline_duty_cycle[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal Deocded Instructions=%u\n",m_num_decoded_insn[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal FP Deocded Instructions=%u\n",m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal INT Deocded Instructions=%u\n",m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal LOAD Queued Instructions=%u\n",m_num_loadqueued_insn[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal STORE Queued Instructions=%u\n",m_num_storequeued_insn[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal IALU Acesses=%f\n",m_num_ialu_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal FP Acesses=%f\n",m_num_fp_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal DP Acesses=%f\n",m_num_dp_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal IMUL Acesses=%f\n",m_num_imul_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal IMUL24 Acesses=%f\n",m_num_imul24_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal IMUL32 Acesses=%f\n",m_num_imul32_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal IDIV Acesses=%f\n",m_num_idiv_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal FPMUL Acesses=%f\n",m_num_fpmul_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal DPMUL Acesses=%f\n",m_num_dpmul_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal SQRT Acesses=%f\n",m_num_sqrt_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal LOG Acesses=%f\n",m_num_log_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal SIN Acesses=%f\n",m_num_sin_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal EXP Acesses=%f\n",m_num_exp_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal FPDIV Acesses=%f\n",m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal DPDIV Acesses=%f\n",m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal TENSOR Acesses=%f\n",m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal CONST Acesses=%f\n",m_num_const_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal TEX Acesses=%f\n",m_num_tex_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal SFU Acesses=%f\n",m_num_sfu_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal SP Acesses=%f\n",m_num_sp_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal MEM Acesses=%f\n",m_num_mem_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal SFU Commissions=%u\n",m_num_sfu_committed[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal SP Commissions=%u\n",m_num_sp_committed[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal MEM Commissions=%u\n",m_num_mem_committed[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal REG Reads=%u\n",m_read_regfile_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal REG Writes=%u\n",m_write_regfile_acesses[CURRENT_STAT_IDX][i]);
- fprintf(fout,"\tTotal NON REG=%u\n",m_non_rf_operands[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "core %u:\n", i);
+ fprintf(fout, "\tpipeline duty cycle =%f\n",
+ m_pipeline_duty_cycle[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal Deocded Instructions=%u\n",
+ m_num_decoded_insn[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal FP Deocded Instructions=%u\n",
+ m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal INT Deocded Instructions=%u\n",
+ m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal LOAD Queued Instructions=%u\n",
+ m_num_loadqueued_insn[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal STORE Queued Instructions=%u\n",
+ m_num_storequeued_insn[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal IALU Acesses=%f\n",
+ m_num_ialu_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal FP Acesses=%f\n",
+ m_num_fp_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal DP Acesses=%f\n",
+ m_num_dp_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal IMUL Acesses=%f\n",
+ m_num_imul_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal IMUL24 Acesses=%f\n",
+ m_num_imul24_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal IMUL32 Acesses=%f\n",
+ m_num_imul32_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal IDIV Acesses=%f\n",
+ m_num_idiv_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal FPMUL Acesses=%f\n",
+ m_num_fpmul_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal DPMUL Acesses=%f\n",
+ m_num_dpmul_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal SQRT Acesses=%f\n",
+ m_num_sqrt_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal LOG Acesses=%f\n",
+ m_num_log_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal SIN Acesses=%f\n",
+ m_num_sin_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal EXP Acesses=%f\n",
+ m_num_exp_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal FPDIV Acesses=%f\n",
+ m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal DPDIV Acesses=%f\n",
+ m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal TENSOR Acesses=%f\n",
+ m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal CONST Acesses=%f\n",
+ m_num_const_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal TEX Acesses=%f\n",
+ m_num_tex_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal SFU Acesses=%f\n",
+ m_num_sfu_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal SP Acesses=%f\n",
+ m_num_sp_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal MEM Acesses=%f\n",
+ m_num_mem_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal SFU Commissions=%u\n",
+ m_num_sfu_committed[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal SP Commissions=%u\n",
+ m_num_sp_committed[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal MEM Commissions=%u\n",
+ m_num_mem_committed[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal REG Reads=%u\n",
+ m_read_regfile_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal REG Writes=%u\n",
+ m_write_regfile_acesses[CURRENT_STAT_IDX][i]);
+ fprintf(fout, "\tTotal NON REG=%u\n",
+ m_non_rf_operands[CURRENT_STAT_IDX][i]);
}
}
void power_core_stat_t::init() {
- m_pipeline_duty_cycle[CURRENT_STAT_IDX]=m_core_stats->m_pipeline_duty_cycle;
- m_num_decoded_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_decoded_insn;
- m_num_FPdecoded_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_FPdecoded_insn;
- m_num_INTdecoded_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_INTdecoded_insn;
- m_num_storequeued_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_storequeued_insn;
- m_num_loadqueued_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_loadqueued_insn;
- m_num_ialu_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_ialu_acesses;
- m_num_fp_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_fp_acesses;
- m_num_imul_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_imul_acesses;
- m_num_imul24_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_imul24_acesses;
- m_num_imul32_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_imul32_acesses;
- m_num_fpmul_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_fpmul_acesses;
- m_num_idiv_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_idiv_acesses;
- m_num_fpdiv_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_fpdiv_acesses;
- m_num_dp_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_dp_acesses;
- m_num_dpmul_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_dpmul_acesses;
- m_num_dpdiv_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_dpdiv_acesses;
- m_num_sp_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_sp_acesses;
- m_num_sfu_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_sfu_acesses;
- m_num_sqrt_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_sqrt_acesses;
- m_num_log_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_log_acesses;
- m_num_sin_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_sin_acesses;
- m_num_exp_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_exp_acesses;
- m_num_tensor_core_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_tensor_core_acesses;
- m_num_const_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_const_acesses;
- m_num_tex_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_tex_acesses;
- m_num_mem_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_mem_acesses;
- m_num_sp_committed[CURRENT_STAT_IDX]=m_core_stats->m_num_sp_committed;
- m_num_sfu_committed[CURRENT_STAT_IDX]=m_core_stats->m_num_sfu_committed;
- m_num_mem_committed[CURRENT_STAT_IDX]=m_core_stats->m_num_mem_committed;
- m_read_regfile_acesses[CURRENT_STAT_IDX]=m_core_stats->m_read_regfile_acesses;
- m_write_regfile_acesses[CURRENT_STAT_IDX]=m_core_stats->m_write_regfile_acesses;
- m_non_rf_operands[CURRENT_STAT_IDX]=m_core_stats->m_non_rf_operands;
- m_active_sp_lanes[CURRENT_STAT_IDX]=m_core_stats->m_active_sp_lanes;
- m_active_sfu_lanes[CURRENT_STAT_IDX]=m_core_stats->m_active_sfu_lanes;
- m_active_exu_threads[CURRENT_STAT_IDX]=m_core_stats->m_active_exu_threads;
- m_active_exu_warps[CURRENT_STAT_IDX]=m_core_stats->m_active_exu_warps;
- m_num_tex_inst[CURRENT_STAT_IDX]=m_core_stats->m_num_tex_inst;
-
- m_pipeline_duty_cycle[PREV_STAT_IDX]=(float*)calloc(m_config->num_shader(),sizeof(float));
- m_num_decoded_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
- m_num_FPdecoded_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
- m_num_INTdecoded_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
- m_num_storequeued_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
- m_num_loadqueued_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
- m_num_tex_inst[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
-
- m_num_ialu_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_fp_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_imul_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_imul24_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_imul32_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_fpmul_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_idiv_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_fpdiv_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_dp_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_dpmul_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_dpdiv_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_tensor_core_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_const_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_tex_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_sp_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_sfu_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_sqrt_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_log_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_sin_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_exp_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_mem_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_num_sp_committed[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
- m_num_sfu_committed[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
- m_num_mem_committed[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
- m_read_regfile_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
- m_write_regfile_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
- m_non_rf_operands[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
- m_active_sp_lanes[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
- m_active_sfu_lanes[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned));
- m_active_exu_threads[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
- m_active_exu_warps[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double));
+ m_pipeline_duty_cycle[CURRENT_STAT_IDX] = m_core_stats->m_pipeline_duty_cycle;
+ m_num_decoded_insn[CURRENT_STAT_IDX] = m_core_stats->m_num_decoded_insn;
+ m_num_FPdecoded_insn[CURRENT_STAT_IDX] = m_core_stats->m_num_FPdecoded_insn;
+ m_num_INTdecoded_insn[CURRENT_STAT_IDX] = m_core_stats->m_num_INTdecoded_insn;
+ m_num_storequeued_insn[CURRENT_STAT_IDX] =
+ m_core_stats->m_num_storequeued_insn;
+ m_num_loadqueued_insn[CURRENT_STAT_IDX] = m_core_stats->m_num_loadqueued_insn;
+ m_num_ialu_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_ialu_acesses;
+ m_num_fp_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_fp_acesses;
+ m_num_imul_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_imul_acesses;
+ m_num_imul24_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_imul24_acesses;
+ m_num_imul32_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_imul32_acesses;
+ m_num_fpmul_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_fpmul_acesses;
+ m_num_idiv_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_idiv_acesses;
+ m_num_fpdiv_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_fpdiv_acesses;
+ m_num_dp_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_dp_acesses;
+ m_num_dpmul_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_dpmul_acesses;
+ m_num_dpdiv_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_dpdiv_acesses;
+ m_num_sp_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_sp_acesses;
+ m_num_sfu_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_sfu_acesses;
+ m_num_sqrt_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_sqrt_acesses;
+ m_num_log_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_log_acesses;
+ m_num_sin_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_sin_acesses;
+ m_num_exp_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_exp_acesses;
+ m_num_tensor_core_acesses[CURRENT_STAT_IDX] =
+ m_core_stats->m_num_tensor_core_acesses;
+ m_num_const_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_const_acesses;
+ m_num_tex_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_tex_acesses;
+ m_num_mem_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_mem_acesses;
+ m_num_sp_committed[CURRENT_STAT_IDX] = m_core_stats->m_num_sp_committed;
+ m_num_sfu_committed[CURRENT_STAT_IDX] = m_core_stats->m_num_sfu_committed;
+ m_num_mem_committed[CURRENT_STAT_IDX] = m_core_stats->m_num_mem_committed;
+ m_read_regfile_acesses[CURRENT_STAT_IDX] =
+ m_core_stats->m_read_regfile_acesses;
+ m_write_regfile_acesses[CURRENT_STAT_IDX] =
+ m_core_stats->m_write_regfile_acesses;
+ m_non_rf_operands[CURRENT_STAT_IDX] = m_core_stats->m_non_rf_operands;
+ m_active_sp_lanes[CURRENT_STAT_IDX] = m_core_stats->m_active_sp_lanes;
+ m_active_sfu_lanes[CURRENT_STAT_IDX] = m_core_stats->m_active_sfu_lanes;
+ m_active_exu_threads[CURRENT_STAT_IDX] = m_core_stats->m_active_exu_threads;
+ m_active_exu_warps[CURRENT_STAT_IDX] = m_core_stats->m_active_exu_warps;
+ m_num_tex_inst[CURRENT_STAT_IDX] = m_core_stats->m_num_tex_inst;
+ m_pipeline_duty_cycle[PREV_STAT_IDX] =
+ (float *)calloc(m_config->num_shader(), sizeof(float));
+ m_num_decoded_insn[PREV_STAT_IDX] =
+ (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned));
+ m_num_FPdecoded_insn[PREV_STAT_IDX] =
+ (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned));
+ m_num_INTdecoded_insn[PREV_STAT_IDX] =
+ (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned));
+ m_num_storequeued_insn[PREV_STAT_IDX] =
+ (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned));
+ m_num_loadqueued_insn[PREV_STAT_IDX] =
+ (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned));
+ m_num_tex_inst[PREV_STAT_IDX] =
+ (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned));
+ m_num_ialu_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_fp_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_imul_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_imul24_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_imul32_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_fpmul_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_idiv_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_fpdiv_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_dp_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_dpmul_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_dpdiv_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_tensor_core_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_const_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_tex_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_sp_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_sfu_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_sqrt_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_log_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_sin_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_exp_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_mem_acesses[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_num_sp_committed[PREV_STAT_IDX] =
+ (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned));
+ m_num_sfu_committed[PREV_STAT_IDX] =
+ (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned));
+ m_num_mem_committed[PREV_STAT_IDX] =
+ (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned));
+ m_read_regfile_acesses[PREV_STAT_IDX] =
+ (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned));
+ m_write_regfile_acesses[PREV_STAT_IDX] =
+ (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned));
+ m_non_rf_operands[PREV_STAT_IDX] =
+ (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned));
+ m_active_sp_lanes[PREV_STAT_IDX] =
+ (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned));
+ m_active_sfu_lanes[PREV_STAT_IDX] =
+ (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned));
+ m_active_exu_threads[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
+ m_active_exu_warps[PREV_STAT_IDX] =
+ (double *)calloc(m_config->num_shader(), sizeof(double));
}
void power_core_stat_t::save_stats() {
for (unsigned i = 0; i < m_config->num_shader(); ++i) {
- m_pipeline_duty_cycle[PREV_STAT_IDX][i]=m_pipeline_duty_cycle[CURRENT_STAT_IDX][i];
- m_num_decoded_insn[PREV_STAT_IDX][i]= m_num_decoded_insn[CURRENT_STAT_IDX][i];
- m_num_FPdecoded_insn[PREV_STAT_IDX][i]=m_num_FPdecoded_insn[CURRENT_STAT_IDX][i];
- m_num_INTdecoded_insn[PREV_STAT_IDX][i]=m_num_INTdecoded_insn[CURRENT_STAT_IDX][i];
- m_num_storequeued_insn[PREV_STAT_IDX][i]=m_num_storequeued_insn[CURRENT_STAT_IDX][i];
- m_num_loadqueued_insn[PREV_STAT_IDX][i]=m_num_loadqueued_insn[CURRENT_STAT_IDX][i];
- m_num_ialu_acesses[PREV_STAT_IDX][i]=m_num_ialu_acesses[CURRENT_STAT_IDX][i];
- m_num_fp_acesses[PREV_STAT_IDX][i]=m_num_fp_acesses[CURRENT_STAT_IDX][i];
- m_num_tex_inst[PREV_STAT_IDX][i]=m_num_tex_inst[CURRENT_STAT_IDX][i];
- m_num_imul_acesses[PREV_STAT_IDX][i]=m_num_imul_acesses[CURRENT_STAT_IDX][i];
- m_num_imul24_acesses[PREV_STAT_IDX][i]=m_num_imul24_acesses[CURRENT_STAT_IDX][i];
- m_num_imul32_acesses[PREV_STAT_IDX][i]=m_num_imul32_acesses[CURRENT_STAT_IDX][i];
- m_num_fpmul_acesses[PREV_STAT_IDX][i]=m_num_fpmul_acesses[CURRENT_STAT_IDX][i];
- m_num_idiv_acesses[PREV_STAT_IDX][i]=m_num_idiv_acesses[CURRENT_STAT_IDX][i];
- m_num_fpdiv_acesses[PREV_STAT_IDX][i]=m_num_fpdiv_acesses[CURRENT_STAT_IDX][i];
- m_num_sp_acesses[PREV_STAT_IDX][i]=m_num_sp_acesses[CURRENT_STAT_IDX][i];
- m_num_sfu_acesses[PREV_STAT_IDX][i]=m_num_sfu_acesses[CURRENT_STAT_IDX][i];
- m_num_sqrt_acesses[PREV_STAT_IDX][i]=m_num_sqrt_acesses[CURRENT_STAT_IDX][i];
- m_num_log_acesses[PREV_STAT_IDX][i]=m_num_log_acesses[CURRENT_STAT_IDX][i];
- m_num_sin_acesses[PREV_STAT_IDX][i]=m_num_sin_acesses[CURRENT_STAT_IDX][i];
- m_num_exp_acesses[PREV_STAT_IDX][i]=m_num_exp_acesses[CURRENT_STAT_IDX][i];
- m_num_dp_acesses[PREV_STAT_IDX][i]=m_num_dp_acesses[CURRENT_STAT_IDX][i];
- m_num_dpmul_acesses[PREV_STAT_IDX][i]=m_num_dpmul_acesses[CURRENT_STAT_IDX][i];
- m_num_dpdiv_acesses[PREV_STAT_IDX][i]=m_num_dpdiv_acesses[CURRENT_STAT_IDX][i];
- m_num_tensor_core_acesses[PREV_STAT_IDX][i]=m_num_tensor_core_acesses[CURRENT_STAT_IDX][i];
- m_num_const_acesses[PREV_STAT_IDX][i]=m_num_const_acesses[CURRENT_STAT_IDX][i];
- m_num_tex_acesses[PREV_STAT_IDX][i]=m_num_tex_acesses[CURRENT_STAT_IDX][i];
- m_num_mem_acesses[PREV_STAT_IDX][i]=m_num_mem_acesses[CURRENT_STAT_IDX][i];
- m_num_sp_committed[PREV_STAT_IDX][i]=m_num_sp_committed[CURRENT_STAT_IDX][i];
- m_num_sfu_committed[PREV_STAT_IDX][i]=m_num_sfu_committed[CURRENT_STAT_IDX][i];
- m_num_mem_committed[PREV_STAT_IDX][i]=m_num_mem_committed[CURRENT_STAT_IDX][i];
- m_read_regfile_acesses[PREV_STAT_IDX][i]=m_read_regfile_acesses[CURRENT_STAT_IDX][i];
- m_write_regfile_acesses[PREV_STAT_IDX][i]=m_write_regfile_acesses[CURRENT_STAT_IDX][i];
- m_non_rf_operands[PREV_STAT_IDX][i]=m_non_rf_operands[CURRENT_STAT_IDX][i];
- m_active_sp_lanes[PREV_STAT_IDX][i]=m_active_sp_lanes[CURRENT_STAT_IDX][i];
- m_active_sfu_lanes[PREV_STAT_IDX][i]=m_active_sfu_lanes[CURRENT_STAT_IDX][i];
- m_active_exu_threads[PREV_STAT_IDX][i]=m_active_exu_threads[CURRENT_STAT_IDX][i];
- m_active_exu_warps[PREV_STAT_IDX][i]=m_active_exu_warps[CURRENT_STAT_IDX][i];
+ m_pipeline_duty_cycle[PREV_STAT_IDX][i] =
+ m_pipeline_duty_cycle[CURRENT_STAT_IDX][i];
+ m_num_decoded_insn[PREV_STAT_IDX][i] =
+ m_num_decoded_insn[CURRENT_STAT_IDX][i];
+ m_num_FPdecoded_insn[PREV_STAT_IDX][i] =
+ m_num_FPdecoded_insn[CURRENT_STAT_IDX][i];
+ m_num_INTdecoded_insn[PREV_STAT_IDX][i] =
+ m_num_INTdecoded_insn[CURRENT_STAT_IDX][i];
+ m_num_storequeued_insn[PREV_STAT_IDX][i] =
+ m_num_storequeued_insn[CURRENT_STAT_IDX][i];
+ m_num_loadqueued_insn[PREV_STAT_IDX][i] =
+ m_num_loadqueued_insn[CURRENT_STAT_IDX][i];
+ m_num_ialu_acesses[PREV_STAT_IDX][i] =
+ m_num_ialu_acesses[CURRENT_STAT_IDX][i];
+ m_num_fp_acesses[PREV_STAT_IDX][i] = m_num_fp_acesses[CURRENT_STAT_IDX][i];
+ m_num_tex_inst[PREV_STAT_IDX][i] = m_num_tex_inst[CURRENT_STAT_IDX][i];
+ m_num_imul_acesses[PREV_STAT_IDX][i] =
+ m_num_imul_acesses[CURRENT_STAT_IDX][i];
+ m_num_imul24_acesses[PREV_STAT_IDX][i] =
+ m_num_imul24_acesses[CURRENT_STAT_IDX][i];
+ m_num_imul32_acesses[PREV_STAT_IDX][i] =
+ m_num_imul32_acesses[CURRENT_STAT_IDX][i];
+ m_num_fpmul_acesses[PREV_STAT_IDX][i] =
+ m_num_fpmul_acesses[CURRENT_STAT_IDX][i];
+ m_num_idiv_acesses[PREV_STAT_IDX][i] =
+ m_num_idiv_acesses[CURRENT_STAT_IDX][i];
+ m_num_fpdiv_acesses[PREV_STAT_IDX][i] =
+ m_num_fpdiv_acesses[CURRENT_STAT_IDX][i];
+ m_num_sp_acesses[PREV_STAT_IDX][i] = m_num_sp_acesses[CURRENT_STAT_IDX][i];
+ m_num_sfu_acesses[PREV_STAT_IDX][i] =
+ m_num_sfu_acesses[CURRENT_STAT_IDX][i];
+ m_num_sqrt_acesses[PREV_STAT_IDX][i] =
+ m_num_sqrt_acesses[CURRENT_STAT_IDX][i];
+ m_num_log_acesses[PREV_STAT_IDX][i] =
+ m_num_log_acesses[CURRENT_STAT_IDX][i];
+ m_num_sin_acesses[PREV_STAT_IDX][i] =
+ m_num_sin_acesses[CURRENT_STAT_IDX][i];
+ m_num_exp_acesses[PREV_STAT_IDX][i] =
+ m_num_exp_acesses[CURRENT_STAT_IDX][i];
+ m_num_dp_acesses[PREV_STAT_IDX][i] = m_num_dp_acesses[CURRENT_STAT_IDX][i];
+ m_num_dpmul_acesses[PREV_STAT_IDX][i] =
+ m_num_dpmul_acesses[CURRENT_STAT_IDX][i];
+ m_num_dpdiv_acesses[PREV_STAT_IDX][i] =
+ m_num_dpdiv_acesses[CURRENT_STAT_IDX][i];
+ m_num_tensor_core_acesses[PREV_STAT_IDX][i] =
+ m_num_tensor_core_acesses[CURRENT_STAT_IDX][i];
+ m_num_const_acesses[PREV_STAT_IDX][i] =
+ m_num_const_acesses[CURRENT_STAT_IDX][i];
+ m_num_tex_acesses[PREV_STAT_IDX][i] =
+ m_num_tex_acesses[CURRENT_STAT_IDX][i];
+ m_num_mem_acesses[PREV_STAT_IDX][i] =
+ m_num_mem_acesses[CURRENT_STAT_IDX][i];
+ m_num_sp_committed[PREV_STAT_IDX][i] =
+ m_num_sp_committed[CURRENT_STAT_IDX][i];
+ m_num_sfu_committed[PREV_STAT_IDX][i] =
+ m_num_sfu_committed[CURRENT_STAT_IDX][i];
+ m_num_mem_committed[PREV_STAT_IDX][i] =
+ m_num_mem_committed[CURRENT_STAT_IDX][i];
+ m_read_regfile_acesses[PREV_STAT_IDX][i] =
+ m_read_regfile_acesses[CURRENT_STAT_IDX][i];
+ m_write_regfile_acesses[PREV_STAT_IDX][i] =
+ m_write_regfile_acesses[CURRENT_STAT_IDX][i];
+ m_non_rf_operands[PREV_STAT_IDX][i] =
+ m_non_rf_operands[CURRENT_STAT_IDX][i];
+ m_active_sp_lanes[PREV_STAT_IDX][i] =
+ m_active_sp_lanes[CURRENT_STAT_IDX][i];
+ m_active_sfu_lanes[PREV_STAT_IDX][i] =
+ m_active_sfu_lanes[CURRENT_STAT_IDX][i];
+ m_active_exu_threads[PREV_STAT_IDX][i] =
+ m_active_exu_threads[CURRENT_STAT_IDX][i];
+ m_active_exu_warps[PREV_STAT_IDX][i] =
+ m_active_exu_warps[CURRENT_STAT_IDX][i];
}
}
@@ -389,12 +497,12 @@ power_stat_t::power_stat_t(const shader_core_config *shader_config,
dram_rd_kernel = 0;
dram_wr_kernel = 0;
dram_pre_kernel = 0;
- l1i_hits_kernel =0;
- l1i_misses_kernel =0;
- l2r_hits_kernel =0;
- l2r_misses_kernel =0;
- l2w_hits_kernel =0;
- l2w_misses_kernel =0;
+ l1i_hits_kernel = 0;
+ l1i_misses_kernel = 0;
+ l2r_hits_kernel = 0;
+ l2r_misses_kernel = 0;
+ l2w_hits_kernel = 0;
+ l2w_misses_kernel = 0;
noc_tr_kernel = 0;
noc_rc_kernel = 0;
diff --git a/src/gpgpu-sim/power_stat.h b/src/gpgpu-sim/power_stat.h
index e2c3ed5..13f144a 100644
--- a/src/gpgpu-sim/power_stat.h
+++ b/src/gpgpu-sim/power_stat.h
@@ -1,16 +1,18 @@
-// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, Tayler Hetherington, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, 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.
@@ -52,40 +54,40 @@ struct shader_core_power_stats_pod {
unsigned
*m_num_INTdecoded_insn[NUM_STAT_IDX]; // number of instructions committed
// by this shader core
- unsigned *m_num_storequeued_insn[NUM_STAT_IDX];
- unsigned *m_num_loadqueued_insn[NUM_STAT_IDX];
- unsigned *m_num_tex_inst[NUM_STAT_IDX];
- double *m_num_ialu_acesses[NUM_STAT_IDX];
- double *m_num_fp_acesses[NUM_STAT_IDX];
- double *m_num_imul_acesses[NUM_STAT_IDX];
- double *m_num_imul32_acesses[NUM_STAT_IDX];
- double *m_num_imul24_acesses[NUM_STAT_IDX];
- double *m_num_fpmul_acesses[NUM_STAT_IDX];
- double *m_num_idiv_acesses[NUM_STAT_IDX];
- double *m_num_fpdiv_acesses[NUM_STAT_IDX];
- double *m_num_dp_acesses[NUM_STAT_IDX];
- double *m_num_dpmul_acesses[NUM_STAT_IDX];
- double *m_num_dpdiv_acesses[NUM_STAT_IDX];
- double *m_num_sp_acesses[NUM_STAT_IDX];
- double *m_num_sfu_acesses[NUM_STAT_IDX];
- double *m_num_sqrt_acesses[NUM_STAT_IDX];
- double *m_num_log_acesses[NUM_STAT_IDX];
- double *m_num_sin_acesses[NUM_STAT_IDX];
- double *m_num_exp_acesses[NUM_STAT_IDX];
- double *m_num_tensor_core_acesses[NUM_STAT_IDX];
- double *m_num_const_acesses[NUM_STAT_IDX];
- double *m_num_tex_acesses[NUM_STAT_IDX];
- double *m_num_mem_acesses[NUM_STAT_IDX];
- unsigned *m_num_sp_committed[NUM_STAT_IDX];
- unsigned *m_num_sfu_committed[NUM_STAT_IDX];
- unsigned *m_num_mem_committed[NUM_STAT_IDX];
- unsigned *m_active_sp_lanes[NUM_STAT_IDX];
- unsigned *m_active_sfu_lanes[NUM_STAT_IDX];
- double *m_active_exu_threads[NUM_STAT_IDX];
- double *m_active_exu_warps[NUM_STAT_IDX];
- unsigned *m_read_regfile_acesses[NUM_STAT_IDX];
- unsigned *m_write_regfile_acesses[NUM_STAT_IDX];
- unsigned *m_non_rf_operands[NUM_STAT_IDX];
+ unsigned *m_num_storequeued_insn[NUM_STAT_IDX];
+ unsigned *m_num_loadqueued_insn[NUM_STAT_IDX];
+ unsigned *m_num_tex_inst[NUM_STAT_IDX];
+ double *m_num_ialu_acesses[NUM_STAT_IDX];
+ double *m_num_fp_acesses[NUM_STAT_IDX];
+ double *m_num_imul_acesses[NUM_STAT_IDX];
+ double *m_num_imul32_acesses[NUM_STAT_IDX];
+ double *m_num_imul24_acesses[NUM_STAT_IDX];
+ double *m_num_fpmul_acesses[NUM_STAT_IDX];
+ double *m_num_idiv_acesses[NUM_STAT_IDX];
+ double *m_num_fpdiv_acesses[NUM_STAT_IDX];
+ double *m_num_dp_acesses[NUM_STAT_IDX];
+ double *m_num_dpmul_acesses[NUM_STAT_IDX];
+ double *m_num_dpdiv_acesses[NUM_STAT_IDX];
+ double *m_num_sp_acesses[NUM_STAT_IDX];
+ double *m_num_sfu_acesses[NUM_STAT_IDX];
+ double *m_num_sqrt_acesses[NUM_STAT_IDX];
+ double *m_num_log_acesses[NUM_STAT_IDX];
+ double *m_num_sin_acesses[NUM_STAT_IDX];
+ double *m_num_exp_acesses[NUM_STAT_IDX];
+ double *m_num_tensor_core_acesses[NUM_STAT_IDX];
+ double *m_num_const_acesses[NUM_STAT_IDX];
+ double *m_num_tex_acesses[NUM_STAT_IDX];
+ double *m_num_mem_acesses[NUM_STAT_IDX];
+ unsigned *m_num_sp_committed[NUM_STAT_IDX];
+ unsigned *m_num_sfu_committed[NUM_STAT_IDX];
+ unsigned *m_num_mem_committed[NUM_STAT_IDX];
+ unsigned *m_active_sp_lanes[NUM_STAT_IDX];
+ unsigned *m_active_sfu_lanes[NUM_STAT_IDX];
+ double *m_active_exu_threads[NUM_STAT_IDX];
+ double *m_active_exu_warps[NUM_STAT_IDX];
+ unsigned *m_read_regfile_acesses[NUM_STAT_IDX];
+ unsigned *m_write_regfile_acesses[NUM_STAT_IDX];
+ unsigned *m_non_rf_operands[NUM_STAT_IDX];
};
class power_core_stat_t : public shader_core_power_stats_pod {
@@ -96,7 +98,6 @@ class power_core_stat_t : public shader_core_power_stats_pod {
void print(FILE *fout);
void init();
void save_stats();
-
private:
shader_core_stats *m_core_stats;
@@ -205,35 +206,37 @@ class power_stat_t {
double get_total_inst(bool aggregate_stat) {
double total_inst = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat)
+ if (aggregate_stat)
total_inst += (pwr_core_stat->m_num_decoded_insn[CURRENT_STAT_IDX][i]);
else
total_inst += (pwr_core_stat->m_num_decoded_insn[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_decoded_insn[PREV_STAT_IDX][i]);
+ (pwr_core_stat->m_num_decoded_insn[PREV_STAT_IDX][i]);
}
return total_inst;
}
double get_total_int_inst(bool aggregate_stat) {
double total_inst = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat)
- total_inst +=
- (pwr_core_stat->m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]);
- else
+ if (aggregate_stat)
total_inst +=
- (pwr_core_stat->m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_INTdecoded_insn[PREV_STAT_IDX][i]);
+ (pwr_core_stat->m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]);
+ else
+ total_inst +=
+ (pwr_core_stat->m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_INTdecoded_insn[PREV_STAT_IDX][i]);
}
return total_inst;
}
double get_total_fp_inst(bool aggregate_stat) {
double total_inst = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat)
- total_inst += (pwr_core_stat->m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]);
- else
- total_inst += (pwr_core_stat->m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_FPdecoded_insn[PREV_STAT_IDX][i]);
+ if (aggregate_stat)
+ total_inst +=
+ (pwr_core_stat->m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]);
+ else
+ total_inst +=
+ (pwr_core_stat->m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_FPdecoded_insn[PREV_STAT_IDX][i]);
}
return total_inst;
}
@@ -282,43 +285,45 @@ class power_stat_t {
double get_committed_inst(bool aggregate_stat) {
double total_inst = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat)
- total_inst += (pwr_core_stat->m_num_mem_committed[CURRENT_STAT_IDX][i]) +
- (pwr_core_stat->m_num_sfu_committed[CURRENT_STAT_IDX][i]) +
- (pwr_core_stat->m_num_sp_committed[CURRENT_STAT_IDX][i]);
+ if (aggregate_stat)
+ total_inst +=
+ (pwr_core_stat->m_num_mem_committed[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_sfu_committed[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_sp_committed[CURRENT_STAT_IDX][i]);
else
- total_inst += (pwr_core_stat->m_num_mem_committed[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_mem_committed[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_sfu_committed[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_sfu_committed[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_sp_committed[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_sp_committed[PREV_STAT_IDX][i]);
+ total_inst +=
+ (pwr_core_stat->m_num_mem_committed[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_mem_committed[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_sfu_committed[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_sfu_committed[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_sp_committed[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_sp_committed[PREV_STAT_IDX][i]);
}
return total_inst;
}
double get_regfile_reads(bool aggregate_stat) {
double total_inst = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat)
- total_inst +=
- (pwr_core_stat->m_read_regfile_acesses[CURRENT_STAT_IDX][i]);
+ if (aggregate_stat)
+ total_inst +=
+ (pwr_core_stat->m_read_regfile_acesses[CURRENT_STAT_IDX][i]);
else
total_inst +=
- (pwr_core_stat->m_read_regfile_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_read_regfile_acesses[PREV_STAT_IDX][i]);
+ (pwr_core_stat->m_read_regfile_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_read_regfile_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
}
double get_regfile_writes(bool aggregate_stat) {
double total_inst = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat)
+ if (aggregate_stat)
total_inst +=
- (pwr_core_stat->m_write_regfile_acesses[CURRENT_STAT_IDX][i]);
+ (pwr_core_stat->m_write_regfile_acesses[CURRENT_STAT_IDX][i]);
else
total_inst +=
- (pwr_core_stat->m_write_regfile_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_write_regfile_acesses[PREV_STAT_IDX][i]);
+ (pwr_core_stat->m_write_regfile_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_write_regfile_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
}
@@ -336,11 +341,11 @@ class power_stat_t {
double get_non_regfile_operands(bool aggregate_stat) {
double total_inst = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat)
- total_inst += (pwr_core_stat->m_non_rf_operands[CURRENT_STAT_IDX][i]);
+ if (aggregate_stat)
+ total_inst += (pwr_core_stat->m_non_rf_operands[CURRENT_STAT_IDX][i]);
else
total_inst += (pwr_core_stat->m_non_rf_operands[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_non_rf_operands[PREV_STAT_IDX][i]);
+ (pwr_core_stat->m_non_rf_operands[PREV_STAT_IDX][i]);
}
return total_inst;
}
@@ -363,45 +368,49 @@ class power_stat_t {
return total_inst;
}
- double get_sqrt_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
- total_inst+=(pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst+=(pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_sqrt_acesses[PREV_STAT_IDX][i]);
- }
- return total_inst;
+ double get_sqrt_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
+ total_inst += (pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i]);
+ else
+ total_inst += (pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_sqrt_acesses[PREV_STAT_IDX][i]);
+ }
+ return total_inst;
}
- double get_log_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
- total_inst+=(pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst+=(pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_log_acesses[PREV_STAT_IDX][i]);
- }
- return total_inst;
+ double get_log_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
+ total_inst += (pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i]);
+ else
+ total_inst += (pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_log_acesses[PREV_STAT_IDX][i]);
+ }
+ return total_inst;
}
- double get_sin_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
- total_inst+=(pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst+=(pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_sin_acesses[PREV_STAT_IDX][i]);
- }
- return total_inst;
+ double get_sin_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
+ total_inst += (pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i]);
+ else
+ total_inst += (pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_sin_acesses[PREV_STAT_IDX][i]);
+ }
+ return total_inst;
}
- double get_exp_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
- total_inst+=(pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst+=(pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_exp_acesses[PREV_STAT_IDX][i]);
- }
- return total_inst;
+ double get_exp_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
+ total_inst += (pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i]);
+ else
+ total_inst += (pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_exp_acesses[PREV_STAT_IDX][i]);
+ }
+ return total_inst;
}
double get_mem_accessess() {
@@ -416,11 +425,11 @@ class power_stat_t {
double get_intdiv_accessess(bool aggregate_stat) {
double total_inst = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat)
+ if (aggregate_stat)
total_inst += (pwr_core_stat->m_num_idiv_acesses[CURRENT_STAT_IDX][i]);
else
total_inst += (pwr_core_stat->m_num_idiv_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_idiv_acesses[PREV_STAT_IDX][i]);
+ (pwr_core_stat->m_num_idiv_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
}
@@ -428,11 +437,12 @@ class power_stat_t {
double get_fpdiv_accessess(bool aggregate_stat) {
double total_inst = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat)
+ if (aggregate_stat)
total_inst += (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst += (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_fpdiv_acesses[PREV_STAT_IDX][i]);
+ else
+ total_inst +=
+ (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_fpdiv_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
}
@@ -440,11 +450,13 @@ class power_stat_t {
double get_intmul32_accessess(bool aggregate_stat) {
double total_inst = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat)
- total_inst += (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst += (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_imul32_acesses[PREV_STAT_IDX][i]);
+ if (aggregate_stat)
+ total_inst +=
+ (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]);
+ else
+ total_inst +=
+ (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_imul32_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
}
@@ -452,118 +464,126 @@ class power_stat_t {
double get_intmul24_accessess(bool aggregate_stat) {
double total_inst = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat)
- total_inst += (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst += (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_imul24_acesses[PREV_STAT_IDX][i]);
+ if (aggregate_stat)
+ total_inst +=
+ (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]);
+ else
+ total_inst +=
+ (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_imul24_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
}
- double get_intmul_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
- total_inst+= (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst+= (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_imul_acesses[PREV_STAT_IDX][i]);
- }
- return total_inst;
+ double get_intmul_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
+ total_inst += (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]);
+ else
+ total_inst += (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_imul_acesses[PREV_STAT_IDX][i]);
+ }
+ return total_inst;
}
- double get_fpmul_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
- total_inst += (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst += (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_fpmul_acesses[PREV_STAT_IDX][i]);
+ double get_fpmul_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
+ total_inst += (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]);
+ else
+ total_inst +=
+ (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_fpmul_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
}
- double get_fp_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
- total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i]) -
+ double get_fp_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
+ total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i]);
+ else
+ total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i]) -
(pwr_core_stat->m_num_fp_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
}
- double get_dp_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
- total_inst += (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst += (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]) -
+ double get_dp_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
+ total_inst += (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]);
+ else
+ total_inst += (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]) -
(pwr_core_stat->m_num_dp_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
}
- double get_dpmul_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
+ double get_dpmul_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
total_inst += (pwr_core_stat->m_num_dpmul_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst += (pwr_core_stat->m_num_dpmul_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_dpmul_acesses[PREV_STAT_IDX][i]);
+ else
+ total_inst +=
+ (pwr_core_stat->m_num_dpmul_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_dpmul_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
}
- double get_dpdiv_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
+ double get_dpdiv_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
total_inst += (pwr_core_stat->m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst += (pwr_core_stat->m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_dpdiv_acesses[PREV_STAT_IDX][i]);
+ else
+ total_inst +=
+ (pwr_core_stat->m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_dpdiv_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
}
- double get_tensor_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
- total_inst += (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst += (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_tensor_core_acesses[PREV_STAT_IDX][i]);
+ double get_tensor_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
+ total_inst +=
+ (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]);
+ else
+ total_inst +=
+ (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_tensor_core_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
}
- double get_const_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
- total_inst += pwr_core_stat->m_num_const_acesses[CURRENT_STAT_IDX][i];
- else
- total_inst += (pwr_core_stat->m_num_const_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_const_acesses[PREV_STAT_IDX][i]);
+ double get_const_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
+ total_inst += pwr_core_stat->m_num_const_acesses[CURRENT_STAT_IDX][i];
+ else
+ total_inst +=
+ (pwr_core_stat->m_num_const_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_const_acesses[PREV_STAT_IDX][i]);
}
return (total_inst);
}
- double get_tex_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
+ double get_tex_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
total_inst += (pwr_core_stat->m_num_tex_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst += (pwr_core_stat->m_num_tex_acesses[CURRENT_STAT_IDX][i]) -
+ else
+ total_inst += (pwr_core_stat->m_num_tex_acesses[CURRENT_STAT_IDX][i]) -
(pwr_core_stat->m_num_tex_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
@@ -589,23 +609,24 @@ class power_stat_t {
m_config->gpgpu_num_sfu_units;
}
-
float get_active_threads(bool aggregate_stat) {
unsigned total_threads = 0;
unsigned total_warps = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat){
- total_threads += (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]) ;
+ if (aggregate_stat) {
+ total_threads +=
+ (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]);
total_warps += (pwr_core_stat->m_active_exu_warps[CURRENT_STAT_IDX][i]);
+ } else {
+ total_threads +=
+ (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_active_exu_threads[PREV_STAT_IDX][i]);
+ total_warps +=
+ (pwr_core_stat->m_active_exu_warps[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_active_exu_warps[PREV_STAT_IDX][i]);
}
- else{
- total_threads += (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_active_exu_threads[PREV_STAT_IDX][i]);
- total_warps += (pwr_core_stat->m_active_exu_warps[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_active_exu_warps[PREV_STAT_IDX][i]);
- }
}
- if(total_warps != 0)
+ if (total_warps != 0)
return (float)((float)total_threads / (float)total_warps);
else
return 0;
@@ -614,98 +635,98 @@ class power_stat_t {
unsigned long long get_tot_threads_kernel(bool aggregate_stat) {
unsigned total_threads = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat){
- total_threads += (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]) ;
+ if (aggregate_stat) {
+ total_threads +=
+ (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]);
+ } else {
+ total_threads +=
+ (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_active_exu_threads[PREV_STAT_IDX][i]);
}
- else{
- total_threads += (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_active_exu_threads[PREV_STAT_IDX][i]);
- }
}
- return total_threads;
+ return total_threads;
}
unsigned long long get_tot_warps_kernel(bool aggregate_stat) {
unsigned long long total_warps = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat){
+ if (aggregate_stat) {
total_warps += (pwr_core_stat->m_active_exu_warps[CURRENT_STAT_IDX][i]);
+ } else {
+ total_warps +=
+ (pwr_core_stat->m_active_exu_warps[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_active_exu_warps[PREV_STAT_IDX][i]);
}
- else{
- total_warps += (pwr_core_stat->m_active_exu_warps[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_active_exu_warps[PREV_STAT_IDX][i]);
- }
}
- return total_warps;
+ return total_warps;
}
-
- double get_tot_fpu_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
- total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i])+
- (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]);
+ double get_tot_fpu_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
+ total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]);
else
- total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_fp_acesses[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_dp_acesses[PREV_STAT_IDX][i]);
+ total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_fp_acesses[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_dp_acesses[PREV_STAT_IDX][i]);
}
- //total_inst += get_total_load_inst()+get_total_store_inst()+get_tex_inst();
+ // total_inst +=
+ // get_total_load_inst()+get_total_store_inst()+get_tex_inst();
return total_inst;
}
-
-
- double get_tot_sfu_accessess(bool aggregate_stat){
- double total_inst=0;
- for(unsigned i=0; i<m_config->num_shader();i++){
- if(aggregate_stat)
- total_inst += (pwr_core_stat->m_num_idiv_acesses[CURRENT_STAT_IDX][i])+
- (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i])+
- (pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i])+
- (pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i])+
- (pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i])+
- (pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i])+
- (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i])+
- (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i])+
- (pwr_core_stat->m_num_dpmul_acesses[CURRENT_STAT_IDX][i])+
- (pwr_core_stat->m_num_dpdiv_acesses[CURRENT_STAT_IDX][i])+
- (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]) +
- (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i])+
- (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i])+
- (pwr_core_stat->m_num_tex_acesses[CURRENT_STAT_IDX][i]);
- else
- total_inst += (pwr_core_stat->m_num_idiv_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_idiv_acesses[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_imul32_acesses[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_sqrt_acesses[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_log_acesses[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_sin_acesses[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_exp_acesses[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_fpdiv_acesses[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_fpmul_acesses[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_dpmul_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_dpmul_acesses[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_dpdiv_acesses[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_imul24_acesses[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_imul_acesses[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_tensor_core_acesses[PREV_STAT_IDX][i]) +
- (pwr_core_stat->m_num_tex_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_tex_acesses[PREV_STAT_IDX][i]);
-
+ double get_tot_sfu_accessess(bool aggregate_stat) {
+ double total_inst = 0;
+ for (unsigned i = 0; i < m_config->num_shader(); i++) {
+ if (aggregate_stat)
+ total_inst +=
+ (pwr_core_stat->m_num_idiv_acesses[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_dpmul_acesses[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_tex_acesses[CURRENT_STAT_IDX][i]);
+ else
+ total_inst +=
+ (pwr_core_stat->m_num_idiv_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_idiv_acesses[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_imul32_acesses[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_sqrt_acesses[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_log_acesses[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_sin_acesses[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_exp_acesses[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_fpdiv_acesses[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_fpmul_acesses[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_dpmul_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_dpmul_acesses[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_dpdiv_acesses[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_imul24_acesses[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_imul_acesses[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_tensor_core_acesses[PREV_STAT_IDX][i]) +
+ (pwr_core_stat->m_num_tex_acesses[CURRENT_STAT_IDX][i]) -
+ (pwr_core_stat->m_num_tex_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
}
@@ -713,11 +734,11 @@ class power_stat_t {
double get_ialu_accessess(bool aggregate_stat) {
double total_inst = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat)
+ if (aggregate_stat)
total_inst += (pwr_core_stat->m_num_ialu_acesses[CURRENT_STAT_IDX][i]);
- else
+ else
total_inst += (pwr_core_stat->m_num_ialu_acesses[CURRENT_STAT_IDX][i]) -
- (pwr_core_stat->m_num_ialu_acesses[PREV_STAT_IDX][i]);
+ (pwr_core_stat->m_num_ialu_acesses[PREV_STAT_IDX][i]);
}
return total_inst;
}
@@ -804,17 +825,16 @@ class power_stat_t {
sizeof(access_type) / sizeof(enum mem_access_type);
unsigned num_request_status =
sizeof(request_status) / sizeof(enum cache_request_status);
- if(aggregate_stat)
+ if (aggregate_stat)
return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
+ access_type, num_access_type, request_status, num_request_status));
else
return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status)) -
- (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
+ access_type, num_access_type, request_status,
+ num_request_status)) -
+ (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status));
}
double get_inst_c_misses(bool aggregate_stat) {
enum mem_access_type access_type[] = {INST_ACC_R};
@@ -823,46 +843,45 @@ class power_stat_t {
sizeof(access_type) / sizeof(enum mem_access_type);
unsigned num_request_status =
sizeof(request_status) / sizeof(enum cache_request_status);
- if(aggregate_stat)
+ if (aggregate_stat)
return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
+ access_type, num_access_type, request_status, num_request_status));
else
return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status)) -
- (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
+ access_type, num_access_type, request_status,
+ num_request_status)) -
+ (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status));
}
double get_inst_c_hits(bool aggregate_stat) {
- return (get_inst_c_accesses(aggregate_stat) - get_inst_c_misses(aggregate_stat));
+ return (get_inst_c_accesses(aggregate_stat) -
+ get_inst_c_misses(aggregate_stat));
}
double get_l1d_read_accesses(bool aggregate_stat) {
enum mem_access_type access_type[] = {GLOBAL_ACC_R, LOCAL_ACC_R};
- enum cache_request_status request_status[] = {HIT, MISS, SECTOR_MISS};
+ enum cache_request_status request_status[] = {HIT, MISS, SECTOR_MISS};
unsigned num_access_type =
sizeof(access_type) / sizeof(enum mem_access_type);
unsigned num_request_status =
sizeof(request_status) / sizeof(enum cache_request_status);
- if(aggregate_stat){
+ if (aggregate_stat) {
return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
- }
- else{
+ access_type, num_access_type, request_status, num_request_status));
+ } else {
return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status)) -
- (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
- }
+ access_type, num_access_type, request_status,
+ num_request_status)) -
+ (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status));
+ }
}
double get_l1d_read_misses(bool aggregate_stat) {
- return (get_l1d_read_accesses(aggregate_stat) - get_l1d_read_hits(aggregate_stat));
+ return (get_l1d_read_accesses(aggregate_stat) -
+ get_l1d_read_hits(aggregate_stat));
}
double get_l1d_read_hits(bool aggregate_stat) {
enum mem_access_type access_type[] = {GLOBAL_ACC_R, LOCAL_ACC_R};
@@ -872,19 +891,17 @@ class power_stat_t {
unsigned num_request_status =
sizeof(request_status) / sizeof(enum cache_request_status);
- if(aggregate_stat){
- return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
- }
- else{
+ if (aggregate_stat) {
return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status)) -
- (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
- }
+ access_type, num_access_type, request_status, num_request_status));
+ } else {
+ return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status)) -
+ (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status));
+ }
}
double get_l1d_write_accesses(bool aggregate_stat) {
enum mem_access_type access_type[] = {GLOBAL_ACC_W, LOCAL_ACC_W};
@@ -894,22 +911,21 @@ class power_stat_t {
unsigned num_request_status =
sizeof(request_status) / sizeof(enum cache_request_status);
- if(aggregate_stat){
- return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
- }
- else{
+ if (aggregate_stat) {
return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status)) -
- (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
- }
+ access_type, num_access_type, request_status, num_request_status));
+ } else {
+ return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status)) -
+ (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status));
+ }
}
double get_l1d_write_misses(bool aggregate_stat) {
- return (get_l1d_write_accesses(aggregate_stat) - get_l1d_write_hits(aggregate_stat));
+ return (get_l1d_write_accesses(aggregate_stat) -
+ get_l1d_write_hits(aggregate_stat));
}
double get_l1d_write_hits(bool aggregate_stat) {
enum mem_access_type access_type[] = {GLOBAL_ACC_W, LOCAL_ACC_W};
@@ -919,19 +935,17 @@ class power_stat_t {
unsigned num_request_status =
sizeof(request_status) / sizeof(enum cache_request_status);
- if(aggregate_stat){
- return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
- }
- else{
+ if (aggregate_stat) {
return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status)) -
- (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
- }
+ access_type, num_access_type, request_status, num_request_status));
+ } else {
+ return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status)) -
+ (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status));
+ }
}
double get_cache_misses() {
return get_l1d_read_misses(0) + get_constant_c_misses() +
@@ -948,111 +962,107 @@ class power_stat_t {
double get_shmem_access(bool aggregate_stat) {
unsigned total_inst = 0;
for (unsigned i = 0; i < m_config->num_shader(); i++) {
- if(aggregate_stat)
+ if (aggregate_stat)
total_inst += (pwr_mem_stat->shmem_access[CURRENT_STAT_IDX][i]);
else
total_inst += (pwr_mem_stat->shmem_access[CURRENT_STAT_IDX][i]) -
- (pwr_mem_stat->shmem_access[PREV_STAT_IDX][i]);
+ (pwr_mem_stat->shmem_access[PREV_STAT_IDX][i]);
}
return total_inst;
}
- unsigned long long get_l2_read_accesses(bool aggregate_stat) {
+ unsigned long long get_l2_read_accesses(bool aggregate_stat) {
enum mem_access_type access_type[] = {
GLOBAL_ACC_R, LOCAL_ACC_R, CONST_ACC_R, TEXTURE_ACC_R, INST_ACC_R};
- enum cache_request_status request_status[] = {HIT, HIT_RESERVED, MISS, SECTOR_MISS};
+ enum cache_request_status request_status[] = {HIT, HIT_RESERVED, MISS,
+ SECTOR_MISS};
unsigned num_access_type =
sizeof(access_type) / sizeof(enum mem_access_type);
unsigned num_request_status =
sizeof(request_status) / sizeof(enum cache_request_status);
- if(aggregate_stat){
- return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
- }
- else{
+ if (aggregate_stat) {
return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status)) -
- (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
+ access_type, num_access_type, request_status, num_request_status));
+ } else {
+ return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status)) -
+ (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status));
}
}
unsigned long long get_l2_read_misses(bool aggregate_stat) {
- return (get_l2_read_accesses(aggregate_stat) - get_l2_read_hits(aggregate_stat));
+ return (get_l2_read_accesses(aggregate_stat) -
+ get_l2_read_hits(aggregate_stat));
}
unsigned long long get_l2_read_hits(bool aggregate_stat) {
- enum mem_access_type access_type[] = {
+ enum mem_access_type access_type[] = {
GLOBAL_ACC_R, LOCAL_ACC_R, CONST_ACC_R, TEXTURE_ACC_R, INST_ACC_R};
- enum cache_request_status request_status[] = {HIT, HIT_RESERVED};
+ enum cache_request_status request_status[] = {HIT, HIT_RESERVED};
unsigned num_access_type =
sizeof(access_type) / sizeof(enum mem_access_type);
unsigned num_request_status =
sizeof(request_status) / sizeof(enum cache_request_status);
- if(aggregate_stat){
- return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
- }
- else{
+ if (aggregate_stat) {
return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status)) -
- (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
+ access_type, num_access_type, request_status, num_request_status));
+ } else {
+ return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status)) -
+ (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status));
}
}
unsigned long long get_l2_write_accesses(bool aggregate_stat) {
enum mem_access_type access_type[] = {GLOBAL_ACC_W, LOCAL_ACC_W,
L1_WRBK_ACC};
- enum cache_request_status request_status[] = {HIT, HIT_RESERVED, MISS, SECTOR_MISS};
+ enum cache_request_status request_status[] = {HIT, HIT_RESERVED, MISS,
+ SECTOR_MISS};
unsigned num_access_type =
sizeof(access_type) / sizeof(enum mem_access_type);
unsigned num_request_status =
sizeof(request_status) / sizeof(enum cache_request_status);
- if(aggregate_stat){
+ if (aggregate_stat) {
return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
- }
- else{
+ access_type, num_access_type, request_status, num_request_status));
+ } else {
return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status)) -
- (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
+ access_type, num_access_type, request_status,
+ num_request_status)) -
+ (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status));
}
}
unsigned long long get_l2_write_misses(bool aggregate_stat) {
- return (get_l2_write_accesses(aggregate_stat) - get_l2_write_hits(aggregate_stat));
+ return (get_l2_write_accesses(aggregate_stat) -
+ get_l2_write_hits(aggregate_stat));
}
unsigned long long get_l2_write_hits(bool aggregate_stat) {
- enum mem_access_type access_type[] = {GLOBAL_ACC_W, LOCAL_ACC_W,
+ enum mem_access_type access_type[] = {GLOBAL_ACC_W, LOCAL_ACC_W,
L1_WRBK_ACC};
enum cache_request_status request_status[] = {HIT, HIT_RESERVED};
unsigned num_access_type =
sizeof(access_type) / sizeof(enum mem_access_type);
unsigned num_request_status =
sizeof(request_status) / sizeof(enum cache_request_status);
- if(aggregate_stat){
+ if (aggregate_stat) {
return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
- }
- else{
+ access_type, num_access_type, request_status, num_request_status));
+ } else {
return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status)) -
- (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats(
- access_type, num_access_type, request_status,
- num_request_status));
+ access_type, num_access_type, request_status,
+ num_request_status)) -
+ (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats(
+ access_type, num_access_type, request_status,
+ num_request_status));
}
}
double get_dram_cmd() {
@@ -1090,12 +1100,11 @@ class power_stat_t {
double get_dram_pre(bool aggregate_stat) {
unsigned total = 0;
for (unsigned i = 0; i < m_mem_config->m_n_mem; ++i) {
- if(aggregate_stat){
+ if (aggregate_stat) {
total += pwr_mem_stat->n_pre[CURRENT_STAT_IDX][i];
- }
- else{
+ } else {
total += (pwr_mem_stat->n_pre[CURRENT_STAT_IDX][i] -
- pwr_mem_stat->n_pre[PREV_STAT_IDX][i]);
+ pwr_mem_stat->n_pre[PREV_STAT_IDX][i]);
}
}
return total;
@@ -1103,12 +1112,11 @@ class power_stat_t {
double get_dram_rd(bool aggregate_stat) {
unsigned total = 0;
for (unsigned i = 0; i < m_mem_config->m_n_mem; ++i) {
- if(aggregate_stat){
+ if (aggregate_stat) {
total += pwr_mem_stat->n_rd[CURRENT_STAT_IDX][i];
- }
- else{
+ } else {
total += (pwr_mem_stat->n_rd[CURRENT_STAT_IDX][i] -
- pwr_mem_stat->n_rd[PREV_STAT_IDX][i]);
+ pwr_mem_stat->n_rd[PREV_STAT_IDX][i]);
}
}
return total;
@@ -1116,15 +1124,14 @@ class power_stat_t {
double get_dram_wr(bool aggregate_stat) {
unsigned total = 0;
for (unsigned i = 0; i < m_mem_config->m_n_mem; ++i) {
- if(aggregate_stat){
- total += pwr_mem_stat->n_wr[CURRENT_STAT_IDX][i] +
- pwr_mem_stat->n_wr_WB[CURRENT_STAT_IDX][i];
- }
- else{
- total += (pwr_mem_stat->n_wr[CURRENT_STAT_IDX][i] -
- pwr_mem_stat->n_wr[PREV_STAT_IDX][i]) +
- (pwr_mem_stat->n_wr_WB[CURRENT_STAT_IDX][i] -
- pwr_mem_stat->n_wr_WB[PREV_STAT_IDX][i]);
+ if (aggregate_stat) {
+ total += pwr_mem_stat->n_wr[CURRENT_STAT_IDX][i] +
+ pwr_mem_stat->n_wr_WB[CURRENT_STAT_IDX][i];
+ } else {
+ total += (pwr_mem_stat->n_wr[CURRENT_STAT_IDX][i] -
+ pwr_mem_stat->n_wr[PREV_STAT_IDX][i]) +
+ (pwr_mem_stat->n_wr_WB[CURRENT_STAT_IDX][i] -
+ pwr_mem_stat->n_wr_WB[PREV_STAT_IDX][i]);
}
}
return total;
@@ -1140,13 +1147,12 @@ class power_stat_t {
unsigned long long get_icnt_simt_to_mem(bool aggregate_stat) {
long total = 0;
- for (unsigned i = 0; i < m_config->n_simt_clusters; ++i){
- if(aggregate_stat){
+ for (unsigned i = 0; i < m_config->n_simt_clusters; ++i) {
+ if (aggregate_stat) {
total += pwr_mem_stat->n_simt_to_mem[CURRENT_STAT_IDX][i];
- }
- else{
+ } else {
total += (pwr_mem_stat->n_simt_to_mem[CURRENT_STAT_IDX][i] -
- pwr_mem_stat->n_simt_to_mem[PREV_STAT_IDX][i]);
+ pwr_mem_stat->n_simt_to_mem[PREV_STAT_IDX][i]);
}
}
return total;
@@ -1155,13 +1161,13 @@ class power_stat_t {
unsigned long long get_icnt_mem_to_simt(bool aggregate_stat) {
long total = 0;
for (unsigned i = 0; i < m_config->n_simt_clusters; ++i) {
- if(aggregate_stat){
+ if (aggregate_stat) {
total += pwr_mem_stat->n_mem_to_simt[CURRENT_STAT_IDX][i];
}
-
- else{
+
+ else {
total += (pwr_mem_stat->n_mem_to_simt[CURRENT_STAT_IDX][i] -
- pwr_mem_stat->n_mem_to_simt[PREV_STAT_IDX][i]);
+ pwr_mem_stat->n_mem_to_simt[PREV_STAT_IDX][i]);
}
}
return total;
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index c0161dd..7482e0e 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -1,17 +1,19 @@
// Copyright (c) 2009-2021, Tor M. Aamodt, Wilson W.L. Fung, Ali Bakhoda,
-// George L. Yuan, Andrew Turner, Inderpreet Singh, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// George L. Yuan, Andrew Turner, Inderpreet Singh, 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.
@@ -55,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;
}
@@ -68,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;
}
/////////////////////////////////////////////////////////////////////////////
@@ -106,7 +108,7 @@ void shader_core_ctx::create_front_pipeline() {
m_pipeline_reg.push_back(
register_set(m_config->pipe_widths[j], pipeline_stage_name_decode[j]));
}
- for (int j = 0; j < m_config->m_specialized_unit.size(); j++) {
+ for (unsigned j = 0; j < m_config->m_specialized_unit.size(); j++) {
m_pipeline_reg.push_back(
register_set(m_config->m_specialized_unit[j].id_oc_spec_reg_width,
m_config->m_specialized_unit[j].name));
@@ -114,7 +116,7 @@ void shader_core_ctx::create_front_pipeline() {
m_specilized_dispatch_reg.push_back(
&m_pipeline_reg[m_pipeline_reg.size() - 1]);
}
- for (int j = 0; j < m_config->m_specialized_unit.size(); j++) {
+ for (unsigned j = 0; j < m_config->m_specialized_unit.size(); j++) {
m_pipeline_reg.push_back(
register_set(m_config->m_specialized_unit[j].oc_ex_spec_reg_width,
m_config->m_specialized_unit[j].name));
@@ -139,7 +141,7 @@ void shader_core_ctx::create_front_pipeline() {
if (m_config->gpgpu_num_int_units > 0)
assert(m_config->gpgpu_num_sched_per_core ==
m_pipeline_reg[ID_OC_INT].get_size());
- for (int j = 0; j < m_config->m_specialized_unit.size(); j++) {
+ for (unsigned j = 0; j < m_config->m_specialized_unit.size(); j++) {
if (m_config->m_specialized_unit[j].num_units > 0)
assert(m_config->gpgpu_num_sched_per_core ==
m_config->m_specialized_unit[j].id_oc_spec_reg_width);
@@ -160,7 +162,10 @@ void shader_core_ctx::create_front_pipeline() {
}
// m_icnt = new shader_memory_interface(this,cluster);
- if (m_config->gpgpu_perfect_mem) {
+ if (m_memory_config->SST_mode) {
+ m_icnt = new sst_memory_interface(
+ this, static_cast<sst_simt_core_cluster *>(m_cluster));
+ } else if (m_config->gpgpu_perfect_mem) {
m_icnt = new perfect_memory_interface(this, m_cluster);
} else {
m_icnt = new shader_memory_interface(this, m_cluster);
@@ -176,7 +181,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() {
@@ -186,20 +191,16 @@ void shader_core_ctx::create_schedulers() {
// must currently occur after all inputs have been initialized.
std::string sched_config = m_config->gpgpu_scheduler_string;
const concrete_scheduler scheduler =
- sched_config.find("lrr") != std::string::npos
- ? CONCRETE_SCHEDULER_LRR
- : sched_config.find("two_level_active") != std::string::npos
- ? CONCRETE_SCHEDULER_TWO_LEVEL_ACTIVE
- : sched_config.find("gto") != std::string::npos
- ? CONCRETE_SCHEDULER_GTO
- : sched_config.find("rrr") != std::string::npos
- ? CONCRETE_SCHEDULER_RRR
- : sched_config.find("old") != std::string::npos
- ? CONCRETE_SCHEDULER_OLDEST_FIRST
- : sched_config.find("warp_limiting") !=
- std::string::npos
- ? CONCRETE_SCHEDULER_WARP_LIMITING
- : NUM_CONCRETE_SCHEDULERS;
+ sched_config.find("lrr") != std::string::npos ? CONCRETE_SCHEDULER_LRR
+ : sched_config.find("two_level_active") != std::string::npos
+ ? CONCRETE_SCHEDULER_TWO_LEVEL_ACTIVE
+ : sched_config.find("gto") != std::string::npos ? CONCRETE_SCHEDULER_GTO
+ : sched_config.find("rrr") != std::string::npos ? CONCRETE_SCHEDULER_RRR
+ : sched_config.find("old") != std::string::npos
+ ? CONCRETE_SCHEDULER_OLDEST_FIRST
+ : sched_config.find("warp_limiting") != std::string::npos
+ ? CONCRETE_SCHEDULER_WARP_LIMITING
+ : NUM_CONCRETE_SCHEDULERS;
assert(scheduler != NUM_CONCRETE_SCHEDULERS);
for (unsigned i = 0; i < m_config->gpgpu_num_sched_per_core; i++) {
@@ -449,7 +450,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);
@@ -480,14 +481,14 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu,
m_config = config;
m_memory_config = mem_config;
m_stats = stats;
- unsigned warp_size = config->warp_size;
+ // unsigned warp_size = config->warp_size;
Issue_Prio = 0;
m_sid = shader_id;
m_tpc = tpc_id;
- if(get_gpu()->get_config().g_power_simulation_enabled){
- scaling_coeffs = get_gpu()->get_scaling_coeffs();
+ if (get_gpu()->get_config().g_power_simulation_enabled) {
+ scaling_coeffs = get_gpu()->get_scaling_coeffs();
}
m_last_inst_gpu_sim_cycle = 0;
@@ -531,7 +532,6 @@ void shader_core_ctx::reinit(unsigned start_thread, unsigned end_thread,
void shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread,
unsigned end_thread, unsigned ctaid,
int cta_size, kernel_info_t &kernel) {
- //
address_type start_pc = next_pc(start_thread);
unsigned kernel_id = kernel.get_uid();
if (m_config->model == POST_DOMINATOR) {
@@ -570,7 +570,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;
@@ -641,7 +642,8 @@ void shader_core_stats::print(FILE *fout) const {
fprintf(fout, "gpgpu_n_param_mem_insn = %d\n", gpgpu_n_param_insn);
fprintf(fout, "gpgpu_n_shmem_bkconflict = %d\n", gpgpu_n_shmem_bkconflict);
- fprintf(fout, "gpgpu_n_cache_bkconflict = %d\n", gpgpu_n_cache_bkconflict);
+ fprintf(fout, "gpgpu_n_l1cache_bkconflict = %d\n",
+ gpgpu_n_l1cache_bkconflict);
fprintf(fout, "gpgpu_n_intrawarp_mshr_merge = %d\n",
gpgpu_n_intrawarp_mshr_merge);
@@ -839,8 +841,8 @@ void shader_core_stats::visualizer_print(gzFile visualizer_file) {
gzprintf(visualizer_file, "\n");
// overall cache miss rates
- gzprintf(visualizer_file, "gpgpu_n_cache_bkconflict: %d\n",
- gpgpu_n_cache_bkconflict);
+ gzprintf(visualizer_file, "gpgpu_n_l1cache_bkconflict: %d\n",
+ gpgpu_n_l1cache_bkconflict);
gzprintf(visualizer_file, "gpgpu_n_shmem_bkconflict: %d\n",
gpgpu_n_shmem_bkconflict);
@@ -893,7 +895,9 @@ void shader_core_ctx::decode() {
m_warp[m_inst_fetch_buffer.m_warp_id]->inc_inst_in_pipeline();
if (pI1) {
m_stats->m_num_decoded_insn[m_sid]++;
- if ((pI1->oprnd_type == INT_OP) || (pI1->oprnd_type == UN_OP)) { //these counters get added up in mcPat to compute scheduler power
+ if ((pI1->oprnd_type == INT_OP) ||
+ (pI1->oprnd_type == UN_OP)) { // these counters get added up in mcPat
+ // to compute scheduler power
m_stats->m_num_INTdecoded_insn[m_sid]++;
} else if (pI1->oprnd_type == FP_OP) {
m_stats->m_num_FPdecoded_insn[m_sid]++;
@@ -904,7 +908,9 @@ void shader_core_ctx::decode() {
m_warp[m_inst_fetch_buffer.m_warp_id]->ibuffer_fill(1, pI2);
m_warp[m_inst_fetch_buffer.m_warp_id]->inc_inst_in_pipeline();
m_stats->m_num_decoded_insn[m_sid]++;
- if ((pI1->oprnd_type == INT_OP) || (pI1->oprnd_type == UN_OP)) { //these counters get added up in mcPat to compute scheduler power
+ if ((pI1->oprnd_type == INT_OP) ||
+ (pI1->oprnd_type == UN_OP)) { // these counters get added up in
+ // mcPat to compute scheduler power
m_stats->m_num_INTdecoded_insn[m_sid]++;
} else if (pI2->oprnd_type == FP_OP) {
m_stats->m_num_FPdecoded_insn[m_sid]++;
@@ -950,7 +956,8 @@ void shader_core_ctx::fetch() {
m_threadState[tid].m_active = false;
unsigned cta_id = m_warp[warp_id]->get_cta_id();
if (m_thread[tid] == NULL) {
- register_cta_thread_exit(cta_id, m_kernel);
+ register_cta_thread_exit(cta_id,
+ m_warp[warp_id]->get_kernel_info());
} else {
register_cta_thread_exit(cta_id,
&(m_thread[tid]->get_kernel()));
@@ -982,16 +989,15 @@ 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;
- if (m_config->perfect_inst_const_cache){
+ if (m_config->perfect_inst_const_cache) {
status = HIT;
shader_cache_access_log(m_sid, INSTRUCTION, 0);
- }
- else
+ } else
status = m_L1I->access(
(new_addr_type)ppc, mf,
m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle, events);
@@ -1038,13 +1044,31 @@ 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);
+ // Add LDGSTS instructions into a buffer
+ unsigned int ldgdepbar_id = m_warp[warp_id]->m_ldgdepbar_id;
+ if (next_inst->m_is_ldgsts) {
+ if (m_warp[warp_id]->m_ldgdepbar_buf.size() == ldgdepbar_id + 1) {
+ m_warp[warp_id]->m_ldgdepbar_buf[ldgdepbar_id].push_back(*next_inst);
+ } else {
+ assert(m_warp[warp_id]->m_ldgdepbar_buf.size() < ldgdepbar_id + 1);
+ std::vector<warp_inst_t> l;
+ l.push_back(*next_inst);
+ m_warp[warp_id]->m_ldgdepbar_buf.push_back(l);
+ }
+ // If the mask of the instruction is all 0, then the address is also 0,
+ // so that there's no need to check through the writeback
+ if (next_inst->get_active_mask() == 0) {
+ (m_warp[warp_id]->m_ldgdepbar_buf.back()).back().pc = -1;
+ }
+ }
+
if (next_inst->op == BARRIER_OP) {
m_warp[warp_id]->store_info_of_last_inst_at_barrier(*pipe_reg);
m_barriers.warp_reaches_barrier(m_warp[warp_id]->get_cta_id(), warp_id,
@@ -1052,6 +1076,47 @@ void shader_core_ctx::issue_warp(register_set &pipe_reg_set,
} else if (next_inst->op == MEMORY_BARRIER_OP) {
m_warp[warp_id]->set_membar();
+ } else if (next_inst->m_is_ldgdepbar) { // Add for LDGDEPBAR
+ m_warp[warp_id]->m_ldgdepbar_id++;
+ // If there are no added LDGSTS, insert an empty vector
+ if (m_warp[warp_id]->m_ldgdepbar_buf.size() != ldgdepbar_id + 1) {
+ assert(m_warp[warp_id]->m_ldgdepbar_buf.size() < ldgdepbar_id + 1);
+ std::vector<warp_inst_t> l;
+ m_warp[warp_id]->m_ldgdepbar_buf.push_back(l);
+ }
+ } else if (next_inst->m_is_depbar) { // Add for DEPBAR
+ // Set to true immediately when a DEPBAR instruction is met
+ m_warp[warp_id]->m_waiting_ldgsts = true;
+ m_warp[warp_id]->m_depbar_group =
+ next_inst->m_depbar_group_no; // set in trace_driven.cc
+
+ // Record the last group that's possbily being monitored by this DEPBAR
+ // instr
+ m_warp[warp_id]->m_depbar_start_id = m_warp[warp_id]->m_ldgdepbar_id - 1;
+
+ // Record the last group that's actually being monitored by this DEPBAR
+ // instr
+ unsigned int end_group =
+ m_warp[warp_id]->m_ldgdepbar_id - m_warp[warp_id]->m_depbar_group;
+
+ // Check for the case that the LDGSTSs monitored have finished when
+ // encountering the DEPBAR instruction
+ bool done_flag = true;
+ for (int i = 0; i < end_group; i++) {
+ for (int j = 0; j < m_warp[warp_id]->m_ldgdepbar_buf[i].size(); j++) {
+ if (m_warp[warp_id]->m_ldgdepbar_buf[i][j].pc != -1) {
+ done_flag = false;
+ goto UpdateDEPBAR;
+ }
+ }
+ }
+
+ UpdateDEPBAR:
+ if (done_flag) {
+ if (m_warp[warp_id]->m_waiting_ldgsts) {
+ m_warp[warp_id]->m_waiting_ldgsts = false;
+ }
+ }
}
updateSIMTStack(warp_id, *pipe_reg);
@@ -1128,11 +1193,12 @@ void scheduler_unit::order_rrr(
if (m_num_issued_last_cycle > 0 || warp(m_current_turn_warp).done_exit() ||
warp(m_current_turn_warp).waiting()) {
std::vector<shd_warp_t *>::const_iterator iter =
- (last_issued_from_input == input_list.end()) ?
- input_list.begin() : last_issued_from_input + 1;
+ (last_issued_from_input == input_list.end())
+ ? input_list.begin()
+ : last_issued_from_input + 1;
for (unsigned count = 0; count < num_warps_to_add; ++iter, ++count) {
if (iter == input_list.end()) {
- iter = input_list.begin();
+ iter = input_list.begin();
}
unsigned warp_id = (*iter)->get_warp_id();
if (!(*iter)->done_exit() && !(*iter)->waiting()) {
@@ -1644,7 +1710,7 @@ void swl_scheduler::order_warps() {
}
void shader_core_ctx::read_operands() {
- for (int i = 0; i < m_config->reg_file_port_throughput; ++i)
+ for (unsigned int i = 0; i < m_config->reg_file_port_throughput; ++i)
m_operand_collector.step();
}
@@ -1795,12 +1861,55 @@ void ldst_unit::get_L1T_sub_stats(struct cache_sub_stats &css) const {
if (m_L1T) m_L1T->get_sub_stats(css);
}
+// Add this function to unset depbar
+void shader_core_ctx::unset_depbar(const warp_inst_t &inst) {
+ bool done_flag = true;
+ unsigned int end_group = m_warp[inst.warp_id()]->m_depbar_start_id == 0
+ ? m_warp[inst.warp_id()]->m_ldgdepbar_buf.size()
+ : (m_warp[inst.warp_id()]->m_depbar_start_id -
+ m_warp[inst.warp_id()]->m_depbar_group + 1);
+
+ if (inst.m_is_ldgsts) {
+ for (int i = 0; i < m_warp[inst.warp_id()]->m_ldgdepbar_buf.size(); i++) {
+ for (int j = 0; j < m_warp[inst.warp_id()]->m_ldgdepbar_buf[i].size();
+ j++) {
+ if (m_warp[inst.warp_id()]->m_ldgdepbar_buf[i][j].pc == inst.pc) {
+ // Handle the case that same pc results in multiple LDGSTS
+ // instructions
+ if (m_warp[inst.warp_id()]->m_ldgdepbar_buf[i][j].get_addr(0) ==
+ inst.get_addr(0)) {
+ m_warp[inst.warp_id()]->m_ldgdepbar_buf[i][j].pc = -1;
+ goto DoneWB;
+ }
+ }
+ }
+ }
+
+ DoneWB:
+ for (int i = 0; i < end_group; i++) {
+ for (int j = 0; j < m_warp[inst.warp_id()]->m_ldgdepbar_buf[i].size();
+ j++) {
+ if (m_warp[inst.warp_id()]->m_ldgdepbar_buf[i][j].pc != -1) {
+ done_flag = false;
+ goto UpdateDEPBAR;
+ }
+ }
+ }
+
+ UpdateDEPBAR:
+ if (done_flag) {
+ if (m_warp[inst.warp_id()]->m_waiting_ldgsts) {
+ m_warp[inst.warp_id()]->m_waiting_ldgsts = false;
+ }
+ }
+ }
+}
+
void shader_core_ctx::warp_inst_complete(const warp_inst_t &inst) {
#if 0
printf("[warp_inst_complete] uid=%u core=%u warp=%u pc=%#x @ time=%llu \n",
inst.get_uid(), m_sid, inst.warp_id(), inst.pc, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle);
#endif
-
if (inst.op_pipe == SP__OP)
m_stats->m_num_sp_committed[m_sid]++;
else if (inst.op_pipe == SFU__OP)
@@ -1879,6 +1988,7 @@ bool ldst_unit::shared_cycle(warp_inst_t &inst, mem_stage_stall_type &rc_fail,
if (stall) {
fail_type = S_MEM;
rc_fail = BK_CONF;
+ m_stats->gpgpu_n_shmem_bkconflict++;
} else
rc_fail = NO_RC_FAIL;
return !stall;
@@ -1905,6 +2015,14 @@ mem_stage_stall_type ldst_unit::process_cache_access(
if (inst.is_load()) {
for (unsigned r = 0; r < MAX_OUTPUT_VALUES; r++)
if (inst.out[r] > 0) m_pending_writes[inst.warp_id()][inst.out[r]]--;
+
+ // release LDGSTS
+ if (inst.m_is_ldgsts) {
+ m_pending_ldgsts[inst.warp_id()][inst.pc][inst.get_addr(0)]--;
+ if (m_pending_ldgsts[inst.warp_id()][inst.pc][inst.get_addr(0)] == 0) {
+ m_core->unset_depbar(inst);
+ }
+ }
}
if (!write_sent) delete mf;
} else if (status == RESERVATION_FAIL) {
@@ -1947,7 +2065,7 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue_l1cache(
if (inst.accessq_empty()) return result;
if (m_config->m_L1D_config.l1_latency > 0) {
- for (int j = 0; j < m_config->m_L1D_config.l1_banks;
+ for (unsigned int j = 0; j < m_config->m_L1D_config.l1_banks;
j++) { // We can handle at max l1_banks reqs per cycle
if (inst.accessq_empty()) return result;
@@ -1976,6 +2094,7 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue_l1cache(
inst.accessq_pop_back();
} else {
result = BK_CONF;
+ m_stats->gpgpu_n_l1cache_bkconflict++;
delete mf;
break; // do not try again, just break from the loop and try the next
// cycle
@@ -2000,7 +2119,7 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue_l1cache(
}
void ldst_unit::L1_latency_queue_cycle() {
- for (int j = 0; j < m_config->m_L1D_config.l1_banks; j++) {
+ for (unsigned int j = 0; j < m_config->m_L1D_config.l1_banks; j++) {
if ((l1_latency_queue[j][0]) != NULL) {
mem_fetch *mf_next = l1_latency_queue[j][0];
std::list<cache_event> events;
@@ -2032,6 +2151,18 @@ void ldst_unit::L1_latency_queue_cycle() {
m_core->warp_inst_complete(mf_next->get_inst());
}
}
+
+ // release LDGSTS
+ if (mf_next->get_inst().m_is_ldgsts) {
+ m_pending_ldgsts[mf_next->get_inst().warp_id()]
+ [mf_next->get_inst().pc]
+ [mf_next->get_inst().get_addr(0)]--;
+ if (m_pending_ldgsts[mf_next->get_inst().warp_id()]
+ [mf_next->get_inst().pc]
+ [mf_next->get_inst().get_addr(0)] == 0) {
+ m_core->unset_depbar(mf_next->get_inst());
+ }
+ }
}
// For write hit in WB policy
@@ -2091,10 +2222,12 @@ bool ldst_unit::constant_cycle(warp_inst_t &inst, mem_stage_stall_type &rc_fail,
mem_stage_stall_type fail;
if (m_config->perfect_inst_const_cache) {
fail = NO_RC_FAIL;
+ unsigned access_count = inst.accessq_count();
while (inst.accessq_count() > 0) inst.accessq_pop_back();
if (inst.is_load()) {
for (unsigned r = 0; r < MAX_OUTPUT_VALUES; r++)
- if (inst.out[r] > 0) m_pending_writes[inst.warp_id()][inst.out[r]]--;
+ if (inst.out[r] > 0)
+ m_pending_writes[inst.warp_id()][inst.out[r]] -= access_count;
}
} else {
fail = process_memory_access_queue(m_L1C, inst);
@@ -2151,7 +2284,15 @@ bool ldst_unit::memory_cycle(warp_inst_t &inst,
inst.is_store() ? WRITE_PACKET_SIZE : READ_PACKET_SIZE;
unsigned size = access.get_size() + control_size;
// printf("Interconnect:Addr: %x, size=%d\n",access.get_addr(),size);
- if (m_icnt->full(size, inst.is_store() || inst.isatomic())) {
+ if (m_memory_config->SST_mode &&
+ (static_cast<sst_memory_interface *>(m_icnt)->full(
+ size, inst.is_store() || inst.isatomic(), access.get_type()))) {
+ // SST need mf type here
+ // Cast it to sst_memory_interface pointer first as this full() method
+ // is not a virtual method in parent class
+ stall_cond = ICNT_RC_FAIL;
+ } else if (!m_memory_config->SST_mode &&
+ (m_icnt->full(size, inst.is_store() || inst.isatomic()))) {
stall_cond = ICNT_RC_FAIL;
} else {
mem_fetch *mf =
@@ -2282,7 +2423,7 @@ void sp_unit::active_lanes_in_pipeline() {
void dp_unit::active_lanes_in_pipeline() {
unsigned active_count = pipelined_simd_unit::get_active_lanes_in_pipeline();
assert(active_count <= m_core->get_config()->warp_size);
- //m_core->incspactivelanes_stat(active_count);
+ // m_core->incspactivelanes_stat(active_count);
m_core->incfuactivelanes_stat(active_count);
m_core->incfumemactivelanes_stat(active_count);
}
@@ -2326,7 +2467,7 @@ sp_unit::sp_unit(register_set *result_port, const shader_core_config *config,
specialized_unit::specialized_unit(register_set *result_port,
const shader_core_config *config,
- shader_core_ctx *core, unsigned supported_op,
+ shader_core_ctx *core, int supported_op,
char *unit_name, unsigned latency,
unsigned issue_reg_id)
: pipelined_simd_unit(result_port, config, latency, core, issue_reg_id) {
@@ -2414,8 +2555,10 @@ void pipelined_simd_unit::cycle() {
if (!m_dispatch_reg->dispatch_delay()) {
int start_stage =
m_dispatch_reg->latency - m_dispatch_reg->initiation_interval;
- move_warp(m_pipeline_reg[start_stage], m_dispatch_reg);
- active_insts_in_pipeline++;
+ if (m_pipeline_reg[start_stage]->empty()) {
+ move_warp(m_pipeline_reg[start_stage], m_dispatch_reg);
+ active_insts_in_pipeline++;
+ }
}
}
occupied >>= 1;
@@ -2466,7 +2609,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 =
@@ -2482,9 +2625,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);
@@ -2493,7 +2637,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);
@@ -2533,6 +2677,9 @@ void ldst_unit::issue(register_set &reg_set) {
m_pending_writes[warp_id][reg_id] += n_accesses;
}
}
+ if (inst->m_is_ldgsts) {
+ m_pending_ldgsts[warp_id][inst->pc][inst->get_addr(0)] += n_accesses;
+ }
}
inst->op_pipe = MEM__OP;
@@ -2564,11 +2711,24 @@ void ldst_unit::writeback() {
m_next_wb.out[r]);
insn_completed = true;
}
+ } else if (m_next_wb.m_is_ldgsts) { // for LDGSTS instructions where no
+ // output register is used
+ m_pending_ldgsts[m_next_wb.warp_id()][m_next_wb.pc]
+ [m_next_wb.get_addr(0)]--;
+ if (m_pending_ldgsts[m_next_wb.warp_id()][m_next_wb.pc]
+ [m_next_wb.get_addr(0)] == 0) {
+ insn_completed = true;
+ }
+ break;
}
}
if (insn_completed) {
m_core->warp_inst_complete(m_next_wb);
+ if (m_next_wb.m_is_ldgsts) {
+ m_core->unset_depbar(m_next_wb);
+ }
}
+
m_next_wb.clear();
m_last_inst_gpu_sim_cycle = m_core->get_gpu()->gpu_sim_cycle;
m_last_inst_gpu_tot_sim_cycle = m_core->get_gpu()->gpu_tot_sim_cycle;
@@ -2697,7 +2857,10 @@ void ldst_unit::cycle() {
}
} else {
if (mf->get_type() == WRITE_ACK ||
- (m_config->gpgpu_perfect_mem && mf->get_is_write())) {
+ ((m_config->gpgpu_perfect_mem || m_memory_config->SST_mode) &&
+ mf->get_is_write())) {
+ // SST memory is handled by SST mem hierarchy
+ // Perfect mem
m_core->store_ack(mf);
m_response_fifo.pop_front();
delete mf;
@@ -2790,6 +2953,15 @@ void ldst_unit::cycle() {
if (!pending_requests) {
m_core->warp_inst_complete(*m_dispatch_reg);
m_scoreboard->releaseRegisters(m_dispatch_reg);
+
+ // release LDGSTS
+ if (m_dispatch_reg->m_is_ldgsts) {
+ // m_pending_ldgsts[m_dispatch_reg->warp_id()][m_dispatch_reg->pc][m_dispatch_reg->get_addr(0)]--;
+ if (m_pending_ldgsts[m_dispatch_reg->warp_id()][m_dispatch_reg->pc]
+ [m_dispatch_reg->get_addr(0)] == 0) {
+ m_core->unset_depbar(*m_dispatch_reg);
+ }
+ }
}
m_core->dec_inst_in_pipeline(warp_id);
m_dispatch_reg->clear();
@@ -3078,7 +3250,7 @@ void warp_inst_t::print(FILE *fout) const {
fprintf(fout, "bubble\n");
return;
} else
- fprintf(fout, "0x%04x ", pc);
+ fprintf(fout, "0x%04llx ", pc);
fprintf(fout, "w%02d[", m_warp_id);
for (unsigned j = 0; j < m_config->warp_size; j++)
fprintf(fout, "%c", (active(j) ? '1' : '0'));
@@ -3086,68 +3258,68 @@ void warp_inst_t::print(FILE *fout) const {
m_config->gpgpu_ctx->func_sim->ptx_print_insn(pc, fout);
fprintf(fout, "\n");
}
-void shader_core_ctx::incexecstat(warp_inst_t *&inst)
-{
- // Latency numbers for next operations are used to scale the power values
- // for special operations, according observations from microbenchmarking
- // TODO: put these numbers in the xml configuration
- if(get_gpu()->get_config().g_power_simulation_enabled){
- switch(inst->sp_op){
- case INT__OP:
- incialu_stat(inst->active_count(), scaling_coeffs->int_coeff);
- break;
- case INT_MUL_OP:
- incimul_stat(inst->active_count(), scaling_coeffs->int_mul_coeff);
- break;
- case INT_MUL24_OP:
- incimul24_stat(inst->active_count(), scaling_coeffs->int_mul24_coeff);
- break;
- case INT_MUL32_OP:
- incimul32_stat(inst->active_count(), scaling_coeffs->int_mul32_coeff);
- break;
- case INT_DIV_OP:
- incidiv_stat(inst->active_count(), scaling_coeffs->int_div_coeff);
- break;
- case FP__OP:
- incfpalu_stat(inst->active_count(),scaling_coeffs->fp_coeff);
- break;
- case FP_MUL_OP:
- incfpmul_stat(inst->active_count(), scaling_coeffs->fp_mul_coeff);
- break;
- case FP_DIV_OP:
- incfpdiv_stat(inst->active_count(), scaling_coeffs->fp_div_coeff);
- break;
- case DP___OP:
- incdpalu_stat(inst->active_count(), scaling_coeffs->dp_coeff);
- break;
- case DP_MUL_OP:
- incdpmul_stat(inst->active_count(), scaling_coeffs->dp_mul_coeff);
- break;
- case DP_DIV_OP:
- incdpdiv_stat(inst->active_count(), scaling_coeffs->dp_div_coeff);
- break;
- case FP_SQRT_OP:
- incsqrt_stat(inst->active_count(), scaling_coeffs->sqrt_coeff);
- break;
- case FP_LG_OP:
- inclog_stat(inst->active_count(), scaling_coeffs->log_coeff);
- break;
- case FP_SIN_OP:
- incsin_stat(inst->active_count(), scaling_coeffs->sin_coeff);
- break;
- case FP_EXP_OP:
- incexp_stat(inst->active_count(), scaling_coeffs->exp_coeff);
- break;
- case TENSOR__OP:
- inctensor_stat(inst->active_count(), scaling_coeffs->tensor_coeff);
- break;
- case TEX__OP:
- inctex_stat(inst->active_count(), scaling_coeffs->tex_coeff);
- break;
- default:
- break;
+void shader_core_ctx::incexecstat(warp_inst_t *&inst) {
+ // Latency numbers for next operations are used to scale the power values
+ // for special operations, according observations from microbenchmarking
+ // TODO: put these numbers in the xml configuration
+ if (get_gpu()->get_config().g_power_simulation_enabled) {
+ switch (inst->sp_op) {
+ case INT__OP:
+ incialu_stat(inst->active_count(), scaling_coeffs->int_coeff);
+ break;
+ case INT_MUL_OP:
+ incimul_stat(inst->active_count(), scaling_coeffs->int_mul_coeff);
+ break;
+ case INT_MUL24_OP:
+ incimul24_stat(inst->active_count(), scaling_coeffs->int_mul24_coeff);
+ break;
+ case INT_MUL32_OP:
+ incimul32_stat(inst->active_count(), scaling_coeffs->int_mul32_coeff);
+ break;
+ case INT_DIV_OP:
+ incidiv_stat(inst->active_count(), scaling_coeffs->int_div_coeff);
+ break;
+ case FP__OP:
+ incfpalu_stat(inst->active_count(), scaling_coeffs->fp_coeff);
+ break;
+ case FP_MUL_OP:
+ incfpmul_stat(inst->active_count(), scaling_coeffs->fp_mul_coeff);
+ break;
+ case FP_DIV_OP:
+ incfpdiv_stat(inst->active_count(), scaling_coeffs->fp_div_coeff);
+ break;
+ case DP___OP:
+ incdpalu_stat(inst->active_count(), scaling_coeffs->dp_coeff);
+ break;
+ case DP_MUL_OP:
+ incdpmul_stat(inst->active_count(), scaling_coeffs->dp_mul_coeff);
+ break;
+ case DP_DIV_OP:
+ incdpdiv_stat(inst->active_count(), scaling_coeffs->dp_div_coeff);
+ break;
+ case FP_SQRT_OP:
+ incsqrt_stat(inst->active_count(), scaling_coeffs->sqrt_coeff);
+ break;
+ case FP_LG_OP:
+ inclog_stat(inst->active_count(), scaling_coeffs->log_coeff);
+ break;
+ case FP_SIN_OP:
+ incsin_stat(inst->active_count(), scaling_coeffs->sin_coeff);
+ break;
+ case FP_EXP_OP:
+ incexp_stat(inst->active_count(), scaling_coeffs->exp_coeff);
+ break;
+ case TENSOR__OP:
+ inctensor_stat(inst->active_count(), scaling_coeffs->tensor_coeff);
+ break;
+ case TEX__OP:
+ inctex_stat(inst->active_count(), scaling_coeffs->tex_coeff);
+ break;
+ default:
+ break;
}
- if(inst->const_cache_operand) //warp has const address space load as one operand
+ if (inst->const_cache_operand) // warp has const address space load as one
+ // operand
inc_const_accesses(1);
}
}
@@ -3264,7 +3436,7 @@ void shader_core_ctx::display_pipeline(FILE *fout, int print_mem,
if (!m_inst_fetch_buffer.m_valid)
fprintf(fout, "bubble\n");
else {
- fprintf(fout, "w%2u : pc = 0x%x, nbytes = %u\n",
+ fprintf(fout, "w%2u : pc = 0x%llx, nbytes = %u\n",
m_inst_fetch_buffer.m_warp_id, m_inst_fetch_buffer.m_pc,
m_inst_fetch_buffer.m_nbytes);
}
@@ -3497,7 +3669,7 @@ void shader_core_ctx::cycle() {
execute();
read_operands();
issue();
- for (int i = 0; i < m_config->inst_fetch_throughput; ++i) {
+ for (unsigned int i = 0; i < m_config->inst_fetch_throughput; ++i) {
decode();
fetch();
}
@@ -3862,7 +4034,8 @@ void shader_core_ctx::accept_ldst_unit_response(mem_fetch *mf) {
void shader_core_ctx::store_ack(class mem_fetch *mf) {
assert(mf->get_type() == WRITE_ACK ||
- (m_config->gpgpu_perfect_mem && mf->get_is_write()));
+ ((m_config->gpgpu_perfect_mem || m_memory_config->SST_mode) &&
+ mf->get_is_write()));
unsigned warp_id = mf->get_wid();
m_warp[warp_id]->dec_store_req();
}
@@ -3897,6 +4070,10 @@ void shader_core_ctx::get_icnt_power_stats(long &n_simt_to_mem,
n_mem_to_simt += m_stats->n_mem_to_simt[m_sid];
}
+kernel_info_t *shd_warp_t::get_kernel_info() const {
+ return m_shader->get_kernel_info();
+}
+
bool shd_warp_t::functional_done() const {
return get_n_completed() == m_warp_size;
}
@@ -3922,13 +4099,16 @@ bool shd_warp_t::waiting() {
// the functional execution of the atomic when it hits DRAM can cause
// the wrong register to be read.
return true;
+ } else if (m_waiting_ldgsts) { // Waiting for LDGSTS to finish
+ return true;
}
return false;
}
void shd_warp_t::print(FILE *fout) const {
if (!done_exit()) {
- fprintf(fout, "w%02u npc: 0x%04x, done:%c%c%c%c:%2u i:%u s:%u a:%u (done: ",
+ fprintf(fout,
+ "w%02u npc: 0x%04llx, done:%c%c%c%c:%2u i:%u s:%u a:%u (done: ",
m_warp_id, m_next_pc, (functional_done() ? 'f' : ' '),
(stores_done() ? 's' : ' '), (inst_in_pipeline() ? ' ' : 'i'),
(done_exit() ? 'e' : ' '), n_completed, m_inst_in_pipeline,
@@ -3997,14 +4177,11 @@ void opndcoll_rfu_t::init(unsigned num_banks, shader_core_ctx *shader) {
// for( unsigned n=0; n<m_num_ports;n++ )
// m_dispatch_units[m_output[n]].init( m_num_collector_units[n] );
m_num_banks = num_banks;
- m_bank_warp_shift = 0;
m_warp_size = shader->get_config()->warp_size;
- m_bank_warp_shift = (unsigned)(int)(log(m_warp_size + 0.5) / log(2.0));
- assert((m_bank_warp_shift == 5) || (m_warp_size != 32));
sub_core_model = shader->get_config()->sub_core_model;
m_num_warp_scheds = shader->get_config()->gpgpu_num_sched_per_core;
- unsigned reg_id;
+ unsigned reg_id = 0;
if (sub_core_model) {
assert(num_banks % shader->get_config()->gpgpu_num_sched_per_core == 0);
assert(m_num_warp_scheds <= m_cu.size() &&
@@ -4018,20 +4195,20 @@ void opndcoll_rfu_t::init(unsigned num_banks, shader_core_ctx *shader) {
unsigned cusPerSched = m_cu.size() / m_num_warp_scheds;
reg_id = j / cusPerSched;
}
- m_cu[j]->init(j, num_banks, m_bank_warp_shift, shader->get_config(), this,
- sub_core_model, reg_id, m_num_banks_per_sched);
+ m_cu[j]->init(j, num_banks, shader->get_config(), this, sub_core_model,
+ reg_id, m_num_banks_per_sched);
}
for (unsigned j = 0; j < m_dispatch_units.size(); j++) {
- m_dispatch_units[j].init(sub_core_model,m_num_warp_scheds);
+ m_dispatch_units[j].init(sub_core_model, m_num_warp_scheds);
}
m_initialized = true;
}
-int register_bank(int regnum, int wid, unsigned num_banks,
- unsigned bank_warp_shift, bool sub_core_model,
- unsigned banks_per_sched, unsigned sched_id) {
+unsigned register_bank(int regnum, int wid, unsigned num_banks,
+ bool sub_core_model, unsigned banks_per_sched,
+ unsigned sched_id) {
int bank = regnum;
- if (bank_warp_shift) bank += wid;
+ bank += wid;
if (sub_core_model) {
unsigned bank_num = (bank % banks_per_sched) + (sched_id * banks_per_sched);
assert(bank_num < num_banks);
@@ -4042,19 +4219,19 @@ int register_bank(int regnum, int wid, unsigned num_banks,
bool opndcoll_rfu_t::writeback(warp_inst_t &inst) {
assert(!inst.empty());
+
std::list<unsigned> regs = m_shader->get_regs_written(inst);
for (unsigned op = 0; op < MAX_REG_OPERANDS; op++) {
int reg_num = inst.arch_reg.dst[op]; // this math needs to match that used
// in function_info::ptx_decode_inst
if (reg_num >= 0) { // valid register
- unsigned bank = register_bank(reg_num, inst.warp_id(), m_num_banks,
- m_bank_warp_shift, sub_core_model,
- m_num_banks_per_sched, inst.get_schd_id());
+ unsigned bank =
+ register_bank(reg_num, inst.warp_id(), m_num_banks, sub_core_model,
+ m_num_banks_per_sched, inst.get_schd_id());
if (m_arbiter.bank_idle(bank)) {
m_arbiter.allocate_bank_for_write(
- bank,
- op_t(&inst, reg_num, m_num_banks, m_bank_warp_shift, sub_core_model,
- m_num_banks_per_sched, inst.get_schd_id()));
+ bank, op_t(&inst, reg_num, m_num_banks, sub_core_model,
+ m_num_banks_per_sched, inst.get_schd_id()));
inst.arch_reg.dst[op] = -1;
} else {
return false;
@@ -4162,9 +4339,8 @@ void opndcoll_rfu_t::allocate_reads() {
const op_t &rr = *r;
unsigned reg = rr.get_reg();
unsigned wid = rr.get_wid();
- unsigned bank =
- register_bank(reg, wid, m_num_banks, m_bank_warp_shift, sub_core_model,
- m_num_banks_per_sched, rr.get_sid());
+ unsigned bank = register_bank(reg, wid, m_num_banks, sub_core_model,
+ m_num_banks_per_sched, rr.get_sid());
m_arbiter.allocate_for_read(bank, rr);
read_ops[bank] = rr;
}
@@ -4214,16 +4390,17 @@ void opndcoll_rfu_t::collector_unit_t::dump(
}
}
-void opndcoll_rfu_t::collector_unit_t::init(
- unsigned n, unsigned num_banks, unsigned log2_warp_size,
- const core_config *config, opndcoll_rfu_t *rfu, bool sub_core_model,
- unsigned reg_id, unsigned banks_per_sched) {
+void opndcoll_rfu_t::collector_unit_t::init(unsigned n, unsigned num_banks,
+ const core_config *config,
+ opndcoll_rfu_t *rfu,
+ bool sub_core_model,
+ unsigned reg_id,
+ unsigned banks_per_sched) {
m_rfu = rfu;
m_cuid = n;
m_num_banks = num_banks;
assert(m_warp == NULL);
m_warp = new warp_inst_t(config);
- m_bank_warp_shift = log2_warp_size;
m_sub_core_model = sub_core_model;
m_reg_id = reg_id;
m_num_banks_per_sched = banks_per_sched;
@@ -4238,15 +4415,21 @@ bool opndcoll_rfu_t::collector_unit_t::allocate(register_set *pipeline_reg_set,
warp_inst_t **pipeline_reg = pipeline_reg_set->get_ready();
if ((pipeline_reg) and !((*pipeline_reg)->empty())) {
m_warp_id = (*pipeline_reg)->warp_id();
+ std::vector<int> prev_regs; // remove duplicate regs within same instr
for (unsigned op = 0; op < MAX_REG_OPERANDS; op++) {
int reg_num =
(*pipeline_reg)
->arch_reg.src[op]; // this math needs to match that used in
// function_info::ptx_decode_inst
- if (reg_num >= 0) { // valid register
- m_src_op[op] = op_t(this, op, reg_num, m_num_banks, m_bank_warp_shift,
- m_sub_core_model, m_num_banks_per_sched,
- (*pipeline_reg)->get_schd_id());
+ bool new_reg = true;
+ for (auto r : prev_regs) {
+ if (r == reg_num) new_reg = false;
+ }
+ if (reg_num >= 0 && new_reg) { // valid register
+ prev_regs.push_back(reg_num);
+ m_src_op[op] =
+ op_t(this, op, reg_num, m_num_banks, m_sub_core_model,
+ m_num_banks_per_sched, (*pipeline_reg)->get_schd_id());
m_not_ready.set(op);
} else
m_src_op[op] = op_t();
@@ -4405,7 +4588,46 @@ bool simt_core_cluster::icnt_injection_buffer_full(unsigned size, bool write) {
return !::icnt_has_buffer(m_cluster_id, request_size);
}
+bool sst_simt_core_cluster::SST_injection_buffer_full(unsigned size, bool write,
+ mem_access_type type) {
+ switch (type) {
+ case CONST_ACC_R:
+ case INST_ACC_R: {
+ return response_queue_full();
+ break;
+ }
+ default: {
+ return ::is_SST_buffer_full(m_cluster_id);
+ break;
+ }
+ }
+}
+
void simt_core_cluster::icnt_inject_request_packet(class mem_fetch *mf) {
+ // Update stats based on mf type
+ update_icnt_stats(mf);
+
+ // The packet size varies depending on the type of request:
+ // - For write request and atomic request, the packet contains the data
+ // - For read request (i.e. not write nor atomic), the packet only has control
+ // metadata
+ unsigned int packet_size = mf->size();
+ if (!mf->get_is_write() && !mf->isatomic()) {
+ packet_size = mf->get_ctrl_size();
+ }
+ m_stats->m_outgoing_traffic_stats->record_traffic(mf, packet_size);
+ unsigned destination = mf->get_sub_partition_id();
+ mf->set_status(IN_ICNT_TO_MEM,
+ m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
+ if (!mf->get_is_write() && !mf->isatomic())
+ ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void *)mf,
+ mf->get_ctrl_size());
+ else
+ ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void *)mf,
+ mf->size());
+}
+
+void simt_core_cluster::update_icnt_stats(class mem_fetch *mf) {
// stats
if (mf->get_is_write())
m_stats->made_write_mfs++;
@@ -4450,6 +4672,12 @@ void simt_core_cluster::icnt_inject_request_packet(class mem_fetch *mf) {
default:
assert(0);
}
+}
+
+void sst_simt_core_cluster::icnt_inject_request_packet_to_SST(
+ class mem_fetch *mf) {
+ // Update stats
+ update_icnt_stats(mf);
// The packet size varies depending on the type of request:
// - For write request and atomic request, the packet contains the data
@@ -4460,15 +4688,25 @@ void simt_core_cluster::icnt_inject_request_packet(class mem_fetch *mf) {
packet_size = mf->get_ctrl_size();
}
m_stats->m_outgoing_traffic_stats->record_traffic(mf, packet_size);
- unsigned destination = mf->get_sub_partition_id();
mf->set_status(IN_ICNT_TO_MEM,
m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- if (!mf->get_is_write() && !mf->isatomic())
- ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void *)mf,
- mf->get_ctrl_size());
- else
- ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void *)mf,
- mf->size());
+ switch (mf->get_access_type()) {
+ case CONST_ACC_R:
+ case INST_ACC_R: {
+ push_response_fifo(mf);
+ break;
+ }
+ default: {
+ if (!mf->get_is_write() && !mf->isatomic())
+ ::send_read_request_SST(m_cluster_id, mf->get_addr(),
+ mf->get_data_size(), (void *)mf);
+ else
+ ::send_write_request_SST(m_cluster_id, mf->get_addr(),
+ mf->get_data_size(), (void *)mf);
+
+ break;
+ }
+ }
}
void simt_core_cluster::icnt_cycle() {
@@ -4510,6 +4748,49 @@ void simt_core_cluster::icnt_cycle() {
}
}
+void sst_simt_core_cluster::icnt_cycle_SST() {
+ if (!m_response_fifo.empty()) {
+ mem_fetch *mf = m_response_fifo.front();
+ unsigned cid = m_config->sid_to_cid(mf->get_sid());
+ if (mf->get_access_type() == INST_ACC_R) {
+ // instruction fetch response
+ if (!m_core[cid]->fetch_unit_response_buffer_full()) {
+ m_response_fifo.pop_front();
+ m_core[cid]->accept_fetch_response(mf);
+ }
+ } else {
+ // data response
+ if (!m_core[cid]->ldst_unit_response_buffer_full()) {
+ m_response_fifo.pop_front();
+ m_memory_stats->memlatstat_read_done(mf);
+ m_core[cid]->accept_ldst_unit_response(mf);
+ }
+ }
+ }
+
+ // pop from SST buffers
+ if (m_response_fifo.size() < m_config->n_simt_ejection_buffer_size) {
+ mem_fetch *mf = (mem_fetch *)(static_cast<sst_gpgpu_sim *>(get_gpu())
+ ->SST_pop_mem_reply(m_cluster_id));
+ if (!mf) return;
+ assert(mf->get_tpc() == m_cluster_id);
+
+ // do atomic here
+ // For now, we execute atomic when the mem reply comes back
+ // This needs to be validated
+ if (mf && mf->isatomic()) mf->do_atomic();
+
+ unsigned int packet_size =
+ (mf->get_is_write()) ? mf->get_ctrl_size() : mf->size();
+ m_stats->m_incoming_traffic_stats->record_traffic(mf, packet_size);
+ mf->set_status(IN_CLUSTER_TO_SHADER_QUEUE,
+ m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
+ // m_memory_stats->memlatstat_read_done(mf,m_shader_config->max_warps_per_shader);
+ m_response_fifo.push_back(mf);
+ m_stats->n_mem_to_simt[m_cluster_id] += mf->get_num_flits(false);
+ }
+}
+
void simt_core_cluster::get_pdom_stack_top_info(unsigned sid, unsigned tid,
unsigned *pc,
unsigned *rpc) const {
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index 65d5625..ee10af6 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -1,17 +1,19 @@
// Copyright (c) 2009-2021, Tor M. Aamodt, Wilson W.L. Fung, Andrew Turner,
-// Ali Bakhoda, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// Ali Bakhoda, 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.
@@ -118,14 +120,30 @@ 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;
m_cdp_dummy = false;
+
+ // Ni: Initialize ldgdepbar_id
+ m_ldgdepbar_id = 0;
+ m_depbar_start_id = 0;
+ m_depbar_group = 0;
+
+ // Ni: Set waiting to false
+ m_waiting_ldgsts = false;
+
+ // Ni: Clear m_ldgdepbar_buf
+ for (unsigned i = 0; i < m_ldgdepbar_buf.size(); i++) {
+ m_ldgdepbar_buf[i].clear();
+ }
+ 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;
@@ -139,6 +157,20 @@ class shd_warp_t {
// Jin: cdp support
m_cdp_latency = 0;
m_cdp_dummy = false;
+
+ // Ni: Initialize ldgdepbar_id
+ m_ldgdepbar_id = 0;
+ m_depbar_start_id = 0;
+ m_depbar_group = 0;
+
+ // Ni: Set waiting to false
+ m_waiting_ldgsts = false;
+
+ // Ni: Clear m_ldgdepbar_buf
+ for (unsigned i = 0; i < m_ldgdepbar_buf.size(); i++) {
+ m_ldgdepbar_buf[i].clear();
+ }
+ m_ldgdepbar_buf.clear();
}
bool functional_done() const;
@@ -170,6 +202,7 @@ class shd_warp_t {
void clear_membar() { m_membar = false; }
bool get_membar() const { return m_membar; }
virtual address_type get_pc() const { return m_next_pc; }
+ virtual kernel_info_t *get_kernel_info() const;
void set_next_pc(address_type pc) { m_next_pc = pc; }
void store_info_of_last_inst_at_barrier(const warp_inst_t *pI) {
@@ -234,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; }
@@ -246,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;
@@ -286,6 +321,16 @@ class shd_warp_t {
public:
unsigned int m_cdp_latency;
bool m_cdp_dummy;
+
+ // Ni: LDGDEPBAR barrier support
+ public:
+ unsigned int m_ldgdepbar_id; // LDGDEPBAR barrier ID
+ std::vector<std::vector<warp_inst_t>>
+ m_ldgdepbar_buf; // LDGDEPBAR barrier buffer
+ unsigned int m_depbar_start_id;
+ unsigned int m_depbar_group;
+ bool m_waiting_ldgsts; // Ni: Whether the warp is waiting for the LDGSTS
+ // instrs to finish
};
inline unsigned hw_tid_from_wid(unsigned wid, unsigned warp_size, unsigned i) {
@@ -298,9 +343,9 @@ inline unsigned wid_from_hw_tid(unsigned tid, unsigned warp_size) {
const unsigned WARP_PER_CTA_MAX = 64;
typedef std::bitset<WARP_PER_CTA_MAX> warp_set_t;
-int register_bank(int regnum, int wid, unsigned num_banks,
- unsigned bank_warp_shift, bool sub_core_model,
- unsigned banks_per_sched, unsigned sched_id);
+unsigned register_bank(int regnum, int wid, unsigned num_banks,
+ bool sub_core_model, unsigned banks_per_sched,
+ unsigned sched_id);
class shader_core_ctx;
class shader_core_config;
@@ -349,8 +394,8 @@ class scheduler_unit { // this can be copied freely, so can be used in std
m_sfu_out(sfu_out),
m_int_out(int_out),
m_tensor_core_out(tensor_core_out),
- m_spec_cores_out(spec_cores_out),
m_mem_out(mem_out),
+ m_spec_cores_out(spec_cores_out),
m_id(id) {}
virtual ~scheduler_unit() {}
virtual void add_supervised_warp_id(int i) {
@@ -643,28 +688,26 @@ class opndcoll_rfu_t { // operand collector based register file unit
public:
op_t() { m_valid = false; }
op_t(collector_unit_t *cu, unsigned op, unsigned reg, unsigned num_banks,
- unsigned bank_warp_shift, bool sub_core_model,
- unsigned banks_per_sched, unsigned sched_id) {
+ bool sub_core_model, unsigned banks_per_sched, unsigned sched_id) {
m_valid = true;
m_warp = NULL;
m_cu = cu;
m_operand = op;
m_register = reg;
m_shced_id = sched_id;
- m_bank = register_bank(reg, cu->get_warp_id(), num_banks, bank_warp_shift,
- sub_core_model, banks_per_sched, sched_id);
+ m_bank = register_bank(reg, cu->get_warp_id(), num_banks, sub_core_model,
+ banks_per_sched, sched_id);
}
op_t(const warp_inst_t *warp, unsigned reg, unsigned num_banks,
- unsigned bank_warp_shift, bool sub_core_model,
- unsigned banks_per_sched, unsigned sched_id) {
+ bool sub_core_model, unsigned banks_per_sched, unsigned sched_id) {
m_valid = true;
m_warp = warp;
m_register = reg;
m_cu = NULL;
m_operand = -1;
m_shced_id = sched_id;
- m_bank = register_bank(reg, warp->warp_id(), num_banks, bank_warp_shift,
- sub_core_model, banks_per_sched, sched_id);
+ m_bank = register_bank(reg, warp->warp_id(), num_banks, sub_core_model,
+ banks_per_sched, sched_id);
}
// accessors
@@ -896,7 +939,6 @@ class opndcoll_rfu_t { // operand collector based register file unit
m_not_ready.reset();
m_warp_id = -1;
m_num_banks = 0;
- m_bank_warp_shift = 0;
}
// accessors
bool ready() const;
@@ -913,9 +955,8 @@ class opndcoll_rfu_t { // operand collector based register file unit
unsigned get_reg_id() const { return m_reg_id; }
// modifiers
- void init(unsigned n, unsigned num_banks, unsigned log2_warp_size,
- const core_config *config, opndcoll_rfu_t *rfu,
- bool m_sub_core_model, unsigned reg_id,
+ void init(unsigned n, unsigned num_banks, const core_config *config,
+ opndcoll_rfu_t *rfu, bool m_sub_core_model, unsigned reg_id,
unsigned num_banks_per_sched);
bool allocate(register_set *pipeline_reg, register_set *output_reg);
@@ -935,7 +976,6 @@ class opndcoll_rfu_t { // operand collector based register file unit
op_t *m_src_op;
std::bitset<MAX_REG_OPERANDS * 2> m_not_ready;
unsigned m_num_banks;
- unsigned m_bank_warp_shift;
opndcoll_rfu_t *m_rfu;
unsigned m_num_banks_per_sched;
@@ -954,41 +994,19 @@ class opndcoll_rfu_t { // operand collector based register file unit
void init(bool sub_core_model, unsigned num_warp_scheds) {
m_sub_core_model = sub_core_model;
m_num_warp_scheds = num_warp_scheds;
- if (m_sub_core_model) {
- m_last_cu_set = new unsigned(m_num_warp_scheds);
- for (unsigned i = 0; i < m_num_warp_scheds; i++)
- {
- m_last_cu_set[i] = i * m_num_collectors / m_num_warp_scheds;
- }
- }
-
}
collector_unit_t *find_ready() {
- if (m_sub_core_model) {
- assert(m_num_collectors % m_num_warp_scheds == 0 &&
- m_num_collectors >= m_num_warp_scheds);
- unsigned cusPerSched = m_num_collectors / m_num_warp_scheds;
- for (unsigned i = 0; i < m_num_warp_scheds; i++) {
- unsigned cuLowerBound = i * cusPerSched;
- unsigned cuUpperBound = cuLowerBound + cusPerSched;
- assert(0 <= cuLowerBound && cuUpperBound <= m_num_collectors);
- assert(cuLowerBound <= m_last_cu_set[i] && m_last_cu_set[i] <= cuUpperBound);
- for (unsigned j = cuLowerBound; j < cuUpperBound; j++) {
- unsigned c = cuLowerBound + (m_last_cu_set[i] + j + 1) % cusPerSched;
- if ((*m_collector_units)[c].ready()) {
- m_last_cu_set[i] = c;
- return &((*m_collector_units)[c]);
- }
- }
- }
- } else {
- for (unsigned n = 0; n < m_num_collectors; n++) {
- unsigned c = (m_last_cu + n + 1) % m_num_collectors;
- if ((*m_collector_units)[c].ready()) {
- m_last_cu = c;
- return &((*m_collector_units)[c]);
- }
+ // With sub-core enabled round robin starts with the next cu assigned to a
+ // different sub-core than the one that dispatched last
+ unsigned cusPerSched = m_num_collectors / m_num_warp_scheds;
+ unsigned rr_increment =
+ m_sub_core_model ? cusPerSched - (m_last_cu % cusPerSched) : 1;
+ for (unsigned n = 0; n < m_num_collectors; n++) {
+ unsigned c = (m_last_cu + n + rr_increment) % m_num_collectors;
+ if ((*m_collector_units)[c].ready()) {
+ m_last_cu = c;
+ return &((*m_collector_units)[c]);
}
}
return NULL;
@@ -998,9 +1016,7 @@ class opndcoll_rfu_t { // operand collector based register file unit
unsigned m_num_collectors;
std::vector<collector_unit_t> *m_collector_units;
unsigned m_last_cu; // dispatch ready cu's rr
- unsigned *m_last_cu_set;
unsigned m_next_cu; // for initialization
-
bool m_sub_core_model;
unsigned m_num_warp_scheds;
};
@@ -1011,7 +1027,6 @@ class opndcoll_rfu_t { // operand collector based register file unit
unsigned m_num_collector_sets;
// unsigned m_num_collectors;
unsigned m_num_banks;
- unsigned m_bank_warp_shift;
unsigned m_warp_size;
std::vector<collector_unit_t *> m_cu;
arbiter_t m_arbiter;
@@ -1306,8 +1321,8 @@ class sp_unit : public pipelined_simd_unit {
class specialized_unit : public pipelined_simd_unit {
public:
specialized_unit(register_set *result_port, const shader_core_config *config,
- shader_core_ctx *core, unsigned supported_op,
- char *unit_name, unsigned latency, unsigned issue_reg_id);
+ shader_core_ctx *core, int supported_op, char *unit_name,
+ unsigned latency, unsigned issue_reg_id);
virtual bool can_issue(const warp_inst_t &inst) const {
if (inst.op != m_supported_op) {
return false;
@@ -1319,7 +1334,7 @@ class specialized_unit : public pipelined_simd_unit {
bool is_issue_partitioned() { return true; }
private:
- unsigned m_supported_op;
+ int m_supported_op;
};
class simt_core_cluster;
@@ -1334,8 +1349,18 @@ 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
+ // register to write to, so a new structure needs to be added
+ /* A multi-level map: unsigned (warp_id) -> unsigned (pc) -> unsigned (addr)
+ * -> unsigned (count)
+ */
+ std::map<unsigned /*warp_id*/,
+ std::map<unsigned /*pc*/,
+ std::map<unsigned /*addr*/, unsigned /*count*/>>>
+ m_pending_ldgsts;
// modifiers
virtual void issue(register_set &inst);
bool is_issue_partitioned() { return false; }
@@ -1414,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;
@@ -1644,13 +1670,13 @@ class shader_core_config : public core_config {
unsigned int gpgpu_operand_collector_num_out_ports_gen;
unsigned int gpgpu_operand_collector_num_out_ports_int;
- int gpgpu_num_sp_units;
- int gpgpu_tensor_core_avail;
- int gpgpu_num_dp_units;
- int gpgpu_num_sfu_units;
- int gpgpu_num_tensor_core_units;
- int gpgpu_num_mem_units;
- int gpgpu_num_int_units;
+ unsigned int gpgpu_num_sp_units;
+ unsigned int gpgpu_tensor_core_avail;
+ unsigned int gpgpu_num_dp_units;
+ unsigned int gpgpu_num_sfu_units;
+ unsigned int gpgpu_num_tensor_core_units;
+ unsigned int gpgpu_num_mem_units;
+ unsigned int gpgpu_num_int_units;
// Shader core resources
unsigned gpgpu_shader_registers;
@@ -1746,8 +1772,8 @@ struct shader_core_stats_pod {
unsigned *m_active_tensor_core_lanes;
unsigned *m_active_fu_lanes;
unsigned *m_active_fu_mem_lanes;
- double *m_active_exu_threads; //For power model
- double *m_active_exu_warps; //For power model
+ double *m_active_exu_threads; // For power model
+ double *m_active_exu_warps; // For power model
unsigned *m_n_diverge; // number of divergence occurring in this shader
unsigned gpgpu_n_load_insn;
unsigned gpgpu_n_store_insn;
@@ -1757,7 +1783,7 @@ struct shader_core_stats_pod {
unsigned gpgpu_n_const_insn;
unsigned gpgpu_n_param_insn;
unsigned gpgpu_n_shmem_bkconflict;
- unsigned gpgpu_n_cache_bkconflict;
+ unsigned gpgpu_n_l1cache_bkconflict;
int gpgpu_n_intrawarp_mshr_merge;
unsigned gpgpu_n_cmem_portconflict;
unsigned gpu_stall_shd_mem_breakdown[N_MEM_STAGE_ACCESS_TYPE]
@@ -1818,56 +1844,41 @@ class shader_core_stats : public shader_core_stats_pod {
(unsigned *)calloc(config->num_shader(), sizeof(unsigned));
m_num_loadqueued_insn =
(unsigned *)calloc(config->num_shader(), sizeof(unsigned));
- m_num_tex_inst =
- (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
+ m_num_tex_inst = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
m_num_INTdecoded_insn =
(unsigned *)calloc(config->num_shader(), sizeof(unsigned));
- m_num_ialu_acesses =
- (double *)calloc(config->num_shader(), sizeof(double));
- m_num_fp_acesses =
- (double *)calloc(config->num_shader(), sizeof(double));
- m_num_imul_acesses =
- (double *)calloc(config->num_shader(), sizeof(double));
+ m_num_ialu_acesses = (double *)calloc(config->num_shader(), sizeof(double));
+ m_num_fp_acesses = (double *)calloc(config->num_shader(), sizeof(double));
+ m_num_imul_acesses = (double *)calloc(config->num_shader(), sizeof(double));
m_num_imul24_acesses =
(double *)calloc(config->num_shader(), sizeof(double));
m_num_imul32_acesses =
(double *)calloc(config->num_shader(), sizeof(double));
m_num_fpmul_acesses =
(double *)calloc(config->num_shader(), sizeof(double));
- m_num_idiv_acesses =
- (double *)calloc(config->num_shader(), sizeof(double));
+ m_num_idiv_acesses = (double *)calloc(config->num_shader(), sizeof(double));
m_num_fpdiv_acesses =
(double *)calloc(config->num_shader(), sizeof(double));
- m_num_dp_acesses =
- (double*) calloc(config->num_shader(),sizeof(double));
- m_num_dpmul_acesses =
- (double*) calloc(config->num_shader(),sizeof(double));
- m_num_dpdiv_acesses =
- (double*) calloc(config->num_shader(),sizeof(double));
- m_num_sp_acesses =
+ m_num_dp_acesses = (double *)calloc(config->num_shader(), sizeof(double));
+ m_num_dpmul_acesses =
(double *)calloc(config->num_shader(), sizeof(double));
- m_num_sfu_acesses =
+ m_num_dpdiv_acesses =
(double *)calloc(config->num_shader(), sizeof(double));
- m_num_tensor_core_acesses =
+ m_num_sp_acesses = (double *)calloc(config->num_shader(), sizeof(double));
+ m_num_sfu_acesses = (double *)calloc(config->num_shader(), sizeof(double));
+ m_num_tensor_core_acesses =
(double *)calloc(config->num_shader(), sizeof(double));
m_num_const_acesses =
(double *)calloc(config->num_shader(), sizeof(double));
- m_num_tex_acesses =
- (double *)calloc(config->num_shader(), sizeof(double));
- m_num_sqrt_acesses =
- (double*) calloc(config->num_shader(),sizeof(double));
- m_num_log_acesses =
- (double*) calloc(config->num_shader(),sizeof(double));
- m_num_sin_acesses =
- (double*) calloc(config->num_shader(),sizeof(double));
- m_num_exp_acesses =
- (double*) calloc(config->num_shader(),sizeof(double));
- m_num_mem_acesses =
- (double *)calloc(config->num_shader(), sizeof(double));
+ m_num_tex_acesses = (double *)calloc(config->num_shader(), sizeof(double));
+ m_num_sqrt_acesses = (double *)calloc(config->num_shader(), sizeof(double));
+ m_num_log_acesses = (double *)calloc(config->num_shader(), sizeof(double));
+ m_num_sin_acesses = (double *)calloc(config->num_shader(), sizeof(double));
+ m_num_exp_acesses = (double *)calloc(config->num_shader(), sizeof(double));
+ m_num_mem_acesses = (double *)calloc(config->num_shader(), sizeof(double));
m_num_sp_committed =
(unsigned *)calloc(config->num_shader(), sizeof(unsigned));
- m_num_tlb_hits =
- (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
+ m_num_tlb_hits = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
m_num_tlb_accesses =
(unsigned *)calloc(config->num_shader(), sizeof(unsigned));
m_active_sp_lanes =
@@ -1880,8 +1891,7 @@ class shader_core_stats : public shader_core_stats_pod {
(unsigned *)calloc(config->num_shader(), sizeof(unsigned));
m_active_exu_threads =
(double *)calloc(config->num_shader(), sizeof(double));
- m_active_exu_warps =
- (double *)calloc(config->num_shader(), sizeof(double));
+ m_active_exu_warps = (double *)calloc(config->num_shader(), sizeof(double));
m_active_fu_mem_lanes =
(unsigned *)calloc(config->num_shader(), sizeof(unsigned));
m_num_sfu_committed =
@@ -1896,8 +1906,7 @@ class shader_core_stats : public shader_core_stats_pod {
(unsigned *)calloc(config->num_shader(), sizeof(unsigned));
m_non_rf_operands =
(unsigned *)calloc(config->num_shader(), sizeof(unsigned));
- m_n_diverge =
- (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
+ m_n_diverge = (unsigned *)calloc(config->num_shader(), sizeof(unsigned));
shader_cycle_distro =
(unsigned *)calloc(config->warp_size + 3, sizeof(unsigned));
last_shader_cycle_distro =
@@ -2006,6 +2015,7 @@ class shader_core_stats : public shader_core_stats_pod {
friend class shader_core_ctx;
friend class ldst_unit;
friend class simt_core_cluster;
+ friend class sst_simt_core_cluster;
friend class scheduler_unit;
friend class TwoLevelScheduler;
friend class LooseRoundRobbinScheduler;
@@ -2021,18 +2031,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;
@@ -2091,6 +2103,9 @@ class shader_core_ctx : public core_t {
// modifiers
virtual void warp_exit(unsigned warp_id);
+ // Ni: Unset ldgdepbar
+ void unset_depbar(const warp_inst_t &inst);
+
// accessors
virtual bool warp_waiting_at_barrier(unsigned warp_id) const;
void get_pdom_stack_top_info(unsigned tid, unsigned *pc, unsigned *rpc) const;
@@ -2130,206 +2145,244 @@ class shader_core_ctx : public core_t {
void incload_stat() { m_stats->m_num_loadqueued_insn[m_sid]++; }
void incstore_stat() { m_stats->m_num_storequeued_insn[m_sid]++; }
- void incialu_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_ialu_acesses[m_sid]=m_stats->m_num_ialu_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_nonsfu(active_count, latency);
- }else {
- m_stats->m_num_ialu_acesses[m_sid]=m_stats->m_num_ialu_acesses[m_sid]+(double)active_count*latency;
+ void incialu_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_ialu_acesses[m_sid] =
+ m_stats->m_num_ialu_acesses[m_sid] + (double)active_count * latency +
+ inactive_lanes_accesses_nonsfu(active_count, latency);
+ } else {
+ m_stats->m_num_ialu_acesses[m_sid] =
+ m_stats->m_num_ialu_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
m_stats->m_active_exu_warps[m_sid]++;
}
- void incimul_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_imul_acesses[m_sid]=m_stats->m_num_imul_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_nonsfu(active_count, latency);
- }else {
- m_stats->m_num_imul_acesses[m_sid]=m_stats->m_num_imul_acesses[m_sid]+(double)active_count*latency;
+ void incimul_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_imul_acesses[m_sid] =
+ m_stats->m_num_imul_acesses[m_sid] + (double)active_count * latency +
+ inactive_lanes_accesses_nonsfu(active_count, latency);
+ } else {
+ m_stats->m_num_imul_acesses[m_sid] =
+ m_stats->m_num_imul_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
m_stats->m_active_exu_warps[m_sid]++;
}
- void incimul24_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_imul24_acesses[m_sid]=m_stats->m_num_imul24_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_nonsfu(active_count, latency);
- }else {
- m_stats->m_num_imul24_acesses[m_sid]=m_stats->m_num_imul24_acesses[m_sid]+(double)active_count*latency;
+ void incimul24_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_imul24_acesses[m_sid] =
+ m_stats->m_num_imul24_acesses[m_sid] +
+ (double)active_count * latency +
+ inactive_lanes_accesses_nonsfu(active_count, latency);
+ } else {
+ m_stats->m_num_imul24_acesses[m_sid] =
+ m_stats->m_num_imul24_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
- m_stats->m_active_exu_warps[m_sid]++;
- }
- void incimul32_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_imul32_acesses[m_sid]=m_stats->m_num_imul32_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_sfu(active_count, latency);
- }else{
- m_stats->m_num_imul32_acesses[m_sid]=m_stats->m_num_imul32_acesses[m_sid]+(double)active_count*latency;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
+ m_stats->m_active_exu_warps[m_sid]++;
+ }
+ void incimul32_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_imul32_acesses[m_sid] =
+ m_stats->m_num_imul32_acesses[m_sid] +
+ (double)active_count * latency +
+ inactive_lanes_accesses_sfu(active_count, latency);
+ } else {
+ m_stats->m_num_imul32_acesses[m_sid] =
+ m_stats->m_num_imul32_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
m_stats->m_active_exu_warps[m_sid]++;
}
- void incidiv_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_idiv_acesses[m_sid]=m_stats->m_num_idiv_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_sfu(active_count, latency);
- }else {
- m_stats->m_num_idiv_acesses[m_sid]=m_stats->m_num_idiv_acesses[m_sid]+(double)active_count*latency;
+ void incidiv_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_idiv_acesses[m_sid] =
+ m_stats->m_num_idiv_acesses[m_sid] + (double)active_count * latency +
+ inactive_lanes_accesses_sfu(active_count, latency);
+ } else {
+ m_stats->m_num_idiv_acesses[m_sid] =
+ m_stats->m_num_idiv_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
- m_stats->m_active_exu_warps[m_sid]++;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
+ m_stats->m_active_exu_warps[m_sid]++;
}
- void incfpalu_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_fp_acesses[m_sid]=m_stats->m_num_fp_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_nonsfu(active_count, latency);
- }else {
- m_stats->m_num_fp_acesses[m_sid]=m_stats->m_num_fp_acesses[m_sid]+(double)active_count*latency;
+ void incfpalu_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_fp_acesses[m_sid] =
+ m_stats->m_num_fp_acesses[m_sid] + (double)active_count * latency +
+ inactive_lanes_accesses_nonsfu(active_count, latency);
+ } else {
+ m_stats->m_num_fp_acesses[m_sid] =
+ m_stats->m_num_fp_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
- m_stats->m_active_exu_warps[m_sid]++;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
+ m_stats->m_active_exu_warps[m_sid]++;
}
- void incfpmul_stat(unsigned active_count,double latency) {
- // printf("FP MUL stat increament\n");
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_fpmul_acesses[m_sid]=m_stats->m_num_fpmul_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_nonsfu(active_count, latency);
- }else {
- m_stats->m_num_fpmul_acesses[m_sid]=m_stats->m_num_fpmul_acesses[m_sid]+(double)active_count*latency;
+ void incfpmul_stat(unsigned active_count, double latency) {
+ // printf("FP MUL stat increament\n");
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_fpmul_acesses[m_sid] =
+ m_stats->m_num_fpmul_acesses[m_sid] + (double)active_count * latency +
+ inactive_lanes_accesses_nonsfu(active_count, latency);
+ } else {
+ m_stats->m_num_fpmul_acesses[m_sid] =
+ m_stats->m_num_fpmul_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
m_stats->m_active_exu_warps[m_sid]++;
- }
- void incfpdiv_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_fpdiv_acesses[m_sid]=m_stats->m_num_fpdiv_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_sfu(active_count, latency);
- }else {
- m_stats->m_num_fpdiv_acesses[m_sid]=m_stats->m_num_fpdiv_acesses[m_sid]+(double)active_count*latency;
+ }
+ void incfpdiv_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_fpdiv_acesses[m_sid] =
+ m_stats->m_num_fpdiv_acesses[m_sid] + (double)active_count * latency +
+ inactive_lanes_accesses_sfu(active_count, latency);
+ } else {
+ m_stats->m_num_fpdiv_acesses[m_sid] =
+ m_stats->m_num_fpdiv_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
m_stats->m_active_exu_warps[m_sid]++;
- }
- void incdpalu_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_dp_acesses[m_sid]=m_stats->m_num_dp_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_nonsfu(active_count, latency);
- }else {
- m_stats->m_num_dp_acesses[m_sid]=m_stats->m_num_dp_acesses[m_sid]+(double)active_count*latency;
+ }
+ void incdpalu_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_dp_acesses[m_sid] =
+ m_stats->m_num_dp_acesses[m_sid] + (double)active_count * latency +
+ inactive_lanes_accesses_nonsfu(active_count, latency);
+ } else {
+ m_stats->m_num_dp_acesses[m_sid] =
+ m_stats->m_num_dp_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
- m_stats->m_active_exu_warps[m_sid]++;
- }
- void incdpmul_stat(unsigned active_count,double latency) {
- // printf("FP MUL stat increament\n");
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_dpmul_acesses[m_sid]=m_stats->m_num_dpmul_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_nonsfu(active_count, latency);
- }else {
- m_stats->m_num_dpmul_acesses[m_sid]=m_stats->m_num_dpmul_acesses[m_sid]+(double)active_count*latency;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
+ m_stats->m_active_exu_warps[m_sid]++;
+ }
+ void incdpmul_stat(unsigned active_count, double latency) {
+ // printf("FP MUL stat increament\n");
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_dpmul_acesses[m_sid] =
+ m_stats->m_num_dpmul_acesses[m_sid] + (double)active_count * latency +
+ inactive_lanes_accesses_nonsfu(active_count, latency);
+ } else {
+ m_stats->m_num_dpmul_acesses[m_sid] =
+ m_stats->m_num_dpmul_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
m_stats->m_active_exu_warps[m_sid]++;
- }
- void incdpdiv_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_dpdiv_acesses[m_sid]=m_stats->m_num_dpdiv_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_sfu(active_count, latency);
- }else {
- m_stats->m_num_dpdiv_acesses[m_sid]=m_stats->m_num_dpdiv_acesses[m_sid]+(double)active_count*latency;
+ }
+ void incdpdiv_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_dpdiv_acesses[m_sid] =
+ m_stats->m_num_dpdiv_acesses[m_sid] + (double)active_count * latency +
+ inactive_lanes_accesses_sfu(active_count, latency);
+ } else {
+ m_stats->m_num_dpdiv_acesses[m_sid] =
+ m_stats->m_num_dpdiv_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
m_stats->m_active_exu_warps[m_sid]++;
- }
+ }
- void incsqrt_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_sqrt_acesses[m_sid]=m_stats->m_num_sqrt_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_sfu(active_count, latency);
- }else{
- m_stats->m_num_sqrt_acesses[m_sid]=m_stats->m_num_sqrt_acesses[m_sid]+(double)active_count*latency;
+ void incsqrt_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_sqrt_acesses[m_sid] =
+ m_stats->m_num_sqrt_acesses[m_sid] + (double)active_count * latency +
+ inactive_lanes_accesses_sfu(active_count, latency);
+ } else {
+ m_stats->m_num_sqrt_acesses[m_sid] =
+ m_stats->m_num_sqrt_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
m_stats->m_active_exu_warps[m_sid]++;
- }
+ }
- void inclog_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_log_acesses[m_sid]=m_stats->m_num_log_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_sfu(active_count, latency);
- }else{
- m_stats->m_num_log_acesses[m_sid]=m_stats->m_num_log_acesses[m_sid]+(double)active_count*latency;
+ void inclog_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_log_acesses[m_sid] =
+ m_stats->m_num_log_acesses[m_sid] + (double)active_count * latency +
+ inactive_lanes_accesses_sfu(active_count, latency);
+ } else {
+ m_stats->m_num_log_acesses[m_sid] =
+ m_stats->m_num_log_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
m_stats->m_active_exu_warps[m_sid]++;
- }
+ }
- void incexp_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_exp_acesses[m_sid]=m_stats->m_num_exp_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_sfu(active_count, latency);
- }else{
- m_stats->m_num_exp_acesses[m_sid]=m_stats->m_num_exp_acesses[m_sid]+(double)active_count*latency;
+ void incexp_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_exp_acesses[m_sid] =
+ m_stats->m_num_exp_acesses[m_sid] + (double)active_count * latency +
+ inactive_lanes_accesses_sfu(active_count, latency);
+ } else {
+ m_stats->m_num_exp_acesses[m_sid] =
+ m_stats->m_num_exp_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
m_stats->m_active_exu_warps[m_sid]++;
}
- void incsin_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_sin_acesses[m_sid]=m_stats->m_num_sin_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_sfu(active_count, latency);
- }else{
- m_stats->m_num_sin_acesses[m_sid]=m_stats->m_num_sin_acesses[m_sid]+(double)active_count*latency;
+ void incsin_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_sin_acesses[m_sid] =
+ m_stats->m_num_sin_acesses[m_sid] + (double)active_count * latency +
+ inactive_lanes_accesses_sfu(active_count, latency);
+ } else {
+ m_stats->m_num_sin_acesses[m_sid] =
+ m_stats->m_num_sin_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
m_stats->m_active_exu_warps[m_sid]++;
}
-
- void inctensor_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_tensor_core_acesses[m_sid]=m_stats->m_num_tensor_core_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_sfu(active_count, latency);
- }else{
- m_stats->m_num_tensor_core_acesses[m_sid]=m_stats->m_num_tensor_core_acesses[m_sid]+(double)active_count*latency;
+ void inctensor_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_tensor_core_acesses[m_sid] =
+ m_stats->m_num_tensor_core_acesses[m_sid] +
+ (double)active_count * latency +
+ inactive_lanes_accesses_sfu(active_count, latency);
+ } else {
+ m_stats->m_num_tensor_core_acesses[m_sid] =
+ m_stats->m_num_tensor_core_acesses[m_sid] +
+ (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
m_stats->m_active_exu_warps[m_sid]++;
}
- void inctex_stat(unsigned active_count,double latency) {
- if(m_config->gpgpu_clock_gated_lanes==false){
- m_stats->m_num_tex_acesses[m_sid]=m_stats->m_num_tex_acesses[m_sid]+(double)active_count*latency
- + inactive_lanes_accesses_sfu(active_count, latency);
- }else{
- m_stats->m_num_tex_acesses[m_sid]=m_stats->m_num_tex_acesses[m_sid]+(double)active_count*latency;
+ void inctex_stat(unsigned active_count, double latency) {
+ if (m_config->gpgpu_clock_gated_lanes == false) {
+ m_stats->m_num_tex_acesses[m_sid] =
+ m_stats->m_num_tex_acesses[m_sid] + (double)active_count * latency +
+ inactive_lanes_accesses_sfu(active_count, latency);
+ } else {
+ m_stats->m_num_tex_acesses[m_sid] =
+ m_stats->m_num_tex_acesses[m_sid] + (double)active_count * latency;
}
- m_stats->m_active_exu_threads[m_sid]+=active_count;
+ m_stats->m_active_exu_threads[m_sid] += active_count;
m_stats->m_active_exu_warps[m_sid]++;
}
void inc_const_accesses(unsigned active_count) {
- m_stats->m_num_const_acesses[m_sid]=m_stats->m_num_const_acesses[m_sid]+active_count;
+ m_stats->m_num_const_acesses[m_sid] =
+ m_stats->m_num_const_acesses[m_sid] + active_count;
}
void incsfu_stat(unsigned active_count, double latency) {
m_stats->m_num_sfu_acesses[m_sid] =
- m_stats->m_num_sfu_acesses[m_sid] + (double)active_count*latency;
+ m_stats->m_num_sfu_acesses[m_sid] + (double)active_count * latency;
}
void incsp_stat(unsigned active_count, double latency) {
m_stats->m_num_sp_acesses[m_sid] =
- m_stats->m_num_sp_acesses[m_sid] + (double)active_count*latency;
+ m_stats->m_num_sp_acesses[m_sid] + (double)active_count * latency;
}
void incmem_stat(unsigned active_count, double latency) {
if (m_config->gpgpu_clock_gated_lanes == false) {
m_stats->m_num_mem_acesses[m_sid] =
- m_stats->m_num_mem_acesses[m_sid] + (double)active_count*latency +
+ m_stats->m_num_mem_acesses[m_sid] + (double)active_count * latency +
inactive_lanes_accesses_nonsfu(active_count, latency);
} else {
m_stats->m_num_mem_acesses[m_sid] =
- m_stats->m_num_mem_acesses[m_sid] + (double)active_count*latency;
+ m_stats->m_num_mem_acesses[m_sid] + (double)active_count * latency;
}
}
void incexecstat(warp_inst_t *&inst);
@@ -2572,6 +2625,7 @@ class simt_core_cluster {
void cache_invalidate();
bool icnt_injection_buffer_full(unsigned size, bool write);
void icnt_inject_request_packet(class mem_fetch *mf);
+ void update_icnt_stats(class mem_fetch *mf);
// for perfect memory interface
bool response_queue_full() {
@@ -2633,6 +2687,50 @@ class exec_simt_core_cluster : public simt_core_cluster {
virtual void create_shader_core_ctx();
};
+/**
+ * @brief SST cluster class
+ *
+ */
+class sst_simt_core_cluster : public exec_simt_core_cluster {
+ public:
+ sst_simt_core_cluster(class gpgpu_sim *gpu, unsigned cluster_id,
+ const shader_core_config *config,
+ const memory_config *mem_config,
+ class shader_core_stats *stats,
+ class memory_stats_t *mstats)
+ : exec_simt_core_cluster(gpu, cluster_id, config, mem_config, stats,
+ mstats) {}
+
+ /**
+ * @brief Check if SST memory request injection
+ * buffer is full by using extern
+ * function is_SST_buffer_full()
+ * defined in Balar
+ *
+ * @param size
+ * @param write
+ * @param type
+ * @return true
+ * @return false
+ */
+ bool SST_injection_buffer_full(unsigned size, bool write,
+ mem_access_type type);
+
+ /**
+ * @brief Send memory request packets to SST
+ * memory
+ *
+ * @param mf
+ */
+ void icnt_inject_request_packet_to_SST(class mem_fetch *mf);
+
+ /**
+ * @brief Advance ICNT between core and SST
+ *
+ */
+ void icnt_cycle_SST();
+};
+
class shader_memory_interface : public mem_fetch_interface {
public:
shader_memory_interface(shader_core_ctx *core, simt_core_cluster *cluster) {
@@ -2673,6 +2771,61 @@ class perfect_memory_interface : public mem_fetch_interface {
simt_core_cluster *m_cluster;
};
+/**
+ * @brief SST memory interface
+ *
+ */
+class sst_memory_interface : public mem_fetch_interface {
+ public:
+ sst_memory_interface(shader_core_ctx *core, sst_simt_core_cluster *cluster) {
+ m_core = core;
+ m_cluster = cluster;
+ }
+ /**
+ * @brief For constant, inst, tex cache access
+ *
+ * @param size
+ * @param write
+ * @return true
+ * @return false
+ */
+ virtual bool full(unsigned size, bool write) const {
+ assert(false && "Use the full() method with access type instead!");
+ return true;
+ }
+
+ /**
+ * @brief With SST, the core will direct all mem access except for
+ * constant, tex, and inst reads to SST mem system
+ * (i.e. not modeling constant mem right now), thus
+ * requiring the mem_access_type information to be passed in
+ *
+ * @param size
+ * @param write
+ * @param type
+ * @return true
+ * @return false
+ */
+ bool full(unsigned size, bool write, mem_access_type type) const {
+ return m_cluster->SST_injection_buffer_full(size, write, type);
+ }
+
+ /**
+ * @brief Push memory request to SST memory system and
+ * update stats
+ *
+ * @param mf
+ */
+ virtual void push(mem_fetch *mf) {
+ m_core->inc_simt_to_mem(mf->get_num_flits(true));
+ m_cluster->icnt_inject_request_packet_to_SST(mf);
+ }
+
+ private:
+ shader_core_ctx *m_core;
+ sst_simt_core_cluster *m_cluster;
+};
+
inline int scheduler_unit::get_sid() const { return m_shader->get_sid(); }
#endif /* SHADER_H */
diff --git a/src/gpgpu-sim/shader_trace.h b/src/gpgpu-sim/shader_trace.h
index e7486d8..367262c 100644
--- a/src/gpgpu-sim/shader_trace.h
+++ b/src/gpgpu-sim/shader_trace.h
@@ -38,7 +38,7 @@
#define SCHED_PRINT_STR SHADER_PRINT_STR "Scheduler %d - "
#define SHADER_DTRACE(x) \
(DTRACE(x) && \
- (Trace::sampling_core == get_sid() || Trace::sampling_core == -1))
+ (Trace::sampling_core == (int)get_sid() || Trace::sampling_core == -1))
// Intended to be called from inside components of a shader core.
// Depends on a get_sid() function
diff --git a/src/gpgpu-sim/stat-tool.cc b/src/gpgpu-sim/stat-tool.cc
index 0513d17..08bbe9e 100644
--- a/src/gpgpu-sim/stat-tool.cc
+++ b/src/gpgpu-sim/stat-tool.cc
@@ -519,7 +519,7 @@ void thread_insn_span::print_span(FILE *fout) const {
fprintf(fout, "%d: ", (int)m_cycle);
span_count_map::const_iterator i_sc = m_insn_span_count.begin();
for (; i_sc != m_insn_span_count.end(); ++i_sc) {
- fprintf(fout, "%d ", i_sc->first);
+ fprintf(fout, "%llx ", i_sc->first);
}
fprintf(fout, "\n");
}