summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt19
-rw-r--r--src/abstract_hardware_model.cc35
-rw-r--r--src/abstract_hardware_model.h125
-rw-r--r--src/accelwattch/CMakeLists.txt46
-rw-r--r--src/accelwattch/XML_Parse.cc130
-rw-r--r--src/accelwattch/XML_Parse.h40
-rw-r--r--src/accelwattch/gpgpu_sim_wrapper.cc879
-rw-r--r--src/accelwattch/gpgpu_sim_wrapper.h69
-rw-r--r--src/accelwattch/processor.cc4
-rw-r--r--src/accelwattch/xmlParser.cc28
-rw-r--r--src/cuda-sim/CMakeLists.txt78
-rw-r--r--src/cuda-sim/Makefile12
-rw-r--r--src/cuda-sim/cuda-sim.cc309
-rw-r--r--src/cuda-sim/cuda_device_runtime.cc4
-rw-r--r--src/cuda-sim/instructions.cc61
-rw-r--r--src/cuda-sim/memory.cc8
-rw-r--r--src/cuda-sim/opcodes.def1
-rw-r--r--src/cuda-sim/ptx.l13
-rw-r--r--src/cuda-sim/ptx.y8
-rw-r--r--src/cuda-sim/ptx_ir.cc48
-rw-r--r--src/cuda-sim/ptx_ir.h7
-rw-r--r--src/cuda-sim/ptx_loader.cc6
-rw-r--r--src/cuda-sim/ptx_parser.cc6
-rw-r--r--src/cuda-sim/ptx_sim.cc3
-rw-r--r--src/cuda-sim/ptx_sim.h3
-rw-r--r--src/debug.cc8
-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
-rw-r--r--src/gpgpusim_entrypoint.cc145
-rw-r--r--src/intersim2/CMakeLists.txt106
-rw-r--r--src/intersim2/Makefile6
-rw-r--r--src/intersim2/config_utils.cpp10
-rw-r--r--src/intersim2/config_utils.hpp2
-rw-r--r--src/intersim2/interconnect_interface.cpp2
-rw-r--r--src/intersim2/networks/anynet.cpp2
-rw-r--r--src/intersim2/networks/dragonfly.cpp26
-rw-r--r--src/intersim2/networks/flatfly_onchip.cpp4
-rw-r--r--src/intersim2/networks/kncube.cpp2
-rw-r--r--src/intersim2/networks/qtree.cpp2
-rw-r--r--src/intersim2/vc.cpp2
-rw-r--r--src/stream_manager.cc30
-rw-r--r--src/stream_manager.h2
62 files changed, 4663 insertions, 2638 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..5849629
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,19 @@
+# gpgpusim_entrypoint objects
+add_library(gpgpusim_entrypoint OBJECT
+ abstract_hardware_model.cc
+ debug.cc
+ gpgpusim_entrypoint.cc
+ option_parser.cc
+ statwrapper.cc
+ stream_manager.cc
+ trace.cc)
+
+# Add current folder and CUDA include to include path
+target_include_directories(gpgpusim_entrypoint PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(gpgpusim_entrypoint PUBLIC ${CUDAToolkit_INCLUDE_DIRS})
+
+# Add subdir
+add_subdirectory(accelwattch)
+add_subdirectory(cuda-sim)
+add_subdirectory(gpgpu-sim)
+add_subdirectory(intersim2) \ No newline at end of file
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index 208047e..e8ddf95 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -1,16 +1,18 @@
-// Copyright (c) 2009-2021, Tor M. Aamodt, Inderpreet Singh, Timothy Rogers, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// Copyright (c) 2009-2021, Tor M. Aamodt, Inderpreet Singh, Timothy Rogers,
+// 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.
-
#include "abstract_hardware_model.h"
#include <sys/stat.h>
#include <algorithm>
@@ -48,12 +49,14 @@ void mem_access_t::init(gpgpu_context *ctx) {
m_addr = 0;
m_req_size = 0;
}
+
void warp_inst_t::issue(const active_mask_t &mask, unsigned warp_id,
unsigned long long cycle, int dynamic_warp_id,
- int sch_id) {
+ int sch_id, unsigned long long streamID) {
m_warp_active_mask = mask;
m_warp_issued_mask = mask;
m_uid = ++(m_config->gpgpu_ctx->warp_inst_sm_next_uid);
+ m_streamID = streamID;
m_warp_id = warp_id;
m_dynamic_warp_id = dynamic_warp_id;
issue_cycle = cycle;
@@ -74,7 +77,7 @@ void checkpoint::load_global_mem(class memory_space *temp_mem, char *f1name) {
FILE *fp2 = fopen(f1name, "r");
assert(fp2 != NULL);
char line[128]; /* or other suitable maximum line size */
- unsigned int offset;
+ unsigned int offset = 0;
while (fgets(line, sizeof line, fp2) != NULL) /* read a line */
{
unsigned int index;
@@ -283,7 +286,7 @@ void warp_inst_t::broadcast_barrier_reduction(
void warp_inst_t::generate_mem_accesses() {
if (empty() || op == MEMORY_BARRIER_OP || m_mem_accesses_created) return;
if (!((op == LOAD_OP) || (op == TENSOR_CORE_LOAD_OP) || (op == STORE_OP) ||
- (op == TENSOR_CORE_STORE_OP) ))
+ (op == TENSOR_CORE_STORE_OP)))
return;
if (m_warp_active_mask.count() == 0) return; // predicated off
@@ -291,8 +294,8 @@ void warp_inst_t::generate_mem_accesses() {
assert(is_load() || is_store());
- //if((space.get_type() != tex_space) && (space.get_type() != const_space))
- assert(m_per_scalar_thread_valid); // need address information per thread
+ // if((space.get_type() != tex_space) && (space.get_type() != const_space))
+ assert(m_per_scalar_thread_valid); // need address information per thread
bool is_write = is_store();
@@ -754,7 +757,8 @@ void warp_inst_t::completed(unsigned long long cycle) const {
}
kernel_info_t::kernel_info_t(dim3 gridDim, dim3 blockDim,
- class function_info *entry) {
+ class function_info *entry,
+ unsigned long long streamID) {
m_kernel_entry = entry;
m_grid_dim = gridDim;
m_block_dim = blockDim;
@@ -764,6 +768,7 @@ kernel_info_t::kernel_info_t(dim3 gridDim, dim3 blockDim,
m_next_tid = m_next_cta;
m_num_cores_running = 0;
m_uid = (entry->gpgpu_ctx->kernel_info_m_next_uid)++;
+ m_streamID = streamID;
m_param_mem = new memory_space_impl<8192>("param", 64 * 1024);
// Jin: parent and child kernel management for CDP
@@ -1005,13 +1010,13 @@ void simt_stack::print(FILE *fout) const {
}
for (unsigned j = 0; j < m_warp_size; j++)
fprintf(fout, "%c", (stack_entry.m_active_mask.test(j) ? '1' : '0'));
- fprintf(fout, " pc: 0x%03x", stack_entry.m_pc);
+ fprintf(fout, " pc: 0x%03llx", stack_entry.m_pc);
if (stack_entry.m_recvg_pc == (unsigned)-1) {
fprintf(fout, " rp: ---- tp: %s cd: %2u ",
(stack_entry.m_type == STACK_ENTRY_TYPE_CALL ? "C" : "N"),
stack_entry.m_calldepth);
} else {
- fprintf(fout, " rp: %4u tp: %s cd: %2u ", stack_entry.m_recvg_pc,
+ fprintf(fout, " rp: %4llu tp: %s cd: %2u ", stack_entry.m_recvg_pc,
(stack_entry.m_type == STACK_ENTRY_TYPE_CALL ? "C" : "N"),
stack_entry.m_calldepth);
}
@@ -1031,7 +1036,7 @@ void simt_stack::print_checkpoint(FILE *fout) const {
for (unsigned j = 0; j < m_warp_size; j++)
fprintf(fout, "%c ", (stack_entry.m_active_mask.test(j) ? '1' : '0'));
- fprintf(fout, "%d %d %d %lld %d ", stack_entry.m_pc,
+ fprintf(fout, "%llu %d %llu %lld %d ", stack_entry.m_pc,
stack_entry.m_calldepth, stack_entry.m_recvg_pc,
stack_entry.m_branch_div_cycle, stack_entry.m_type);
fprintf(fout, "%d %d\n", m_warp_id, m_warp_size);
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index f04741f..98a4039 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -1,16 +1,18 @@
-// Copyright (c) 2009-2021, Tor M. Aamodt, Inderpreet Singh, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
+// Copyright (c) 2009-2021, Tor M. Aamodt, 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.
@@ -63,24 +65,24 @@ enum _memory_space_t {
#ifndef COEFF_STRUCT
#define COEFF_STRUCT
-struct PowerscalingCoefficients{
- double int_coeff;
- double int_mul_coeff;
- double int_mul24_coeff;
- double int_mul32_coeff;
- double int_div_coeff;
- double fp_coeff;
- double dp_coeff;
- double fp_mul_coeff;
- double fp_div_coeff;
- double dp_mul_coeff;
- double dp_div_coeff;
- double sqrt_coeff;
- double log_coeff;
- double sin_coeff;
- double exp_coeff;
- double tensor_coeff;
- double tex_coeff;
+struct PowerscalingCoefficients {
+ double int_coeff;
+ double int_mul_coeff;
+ double int_mul24_coeff;
+ double int_mul32_coeff;
+ double int_div_coeff;
+ double fp_coeff;
+ double dp_coeff;
+ double fp_mul_coeff;
+ double fp_div_coeff;
+ double dp_mul_coeff;
+ double dp_div_coeff;
+ double sqrt_coeff;
+ double log_coeff;
+ double sin_coeff;
+ double exp_coeff;
+ double tensor_coeff;
+ double tex_coeff;
};
#endif
@@ -231,7 +233,8 @@ class kernel_info_t {
// m_num_cores_running=0;
// m_param_mem=NULL;
// }
- kernel_info_t(dim3 gridDim, dim3 blockDim, class function_info *entry);
+ kernel_info_t(dim3 gridDim, dim3 blockDim, class function_info *entry,
+ unsigned long long streamID);
kernel_info_t(
dim3 gridDim, dim3 blockDim, class function_info *entry,
std::map<std::string, const struct cudaArray *> nameToCudaArray,
@@ -290,6 +293,8 @@ class kernel_info_t {
m_next_tid.x < m_block_dim.x;
}
unsigned get_uid() const { return m_uid; }
+ unsigned long long get_streamID() const { return m_streamID; }
+ std::string get_name() const { return name(); }
std::string name() const;
std::list<class ptx_thread_info *> &active_threads() {
@@ -322,7 +327,8 @@ class kernel_info_t {
class function_info *m_kernel_entry;
- unsigned m_uid;
+ unsigned m_uid; // Kernel ID
+ unsigned long long m_streamID;
// These maps contain the snapshot of the texture mappings at kernel launch
std::map<std::string, const struct cudaArray *> m_NameToCudaArray;
@@ -897,8 +903,8 @@ class mem_fetch_interface {
class mem_fetch_allocator {
public:
virtual mem_fetch *alloc(new_addr_type addr, mem_access_type type,
- unsigned size, bool wr,
- unsigned long long cycle) const = 0;
+ unsigned size, bool wr, unsigned long long cycle,
+ unsigned long long streamID) const = 0;
virtual mem_fetch *alloc(const class warp_inst_t &inst,
const mem_access_t &access,
unsigned long long cycle) const = 0;
@@ -908,7 +914,8 @@ class mem_fetch_allocator {
const mem_access_sector_mask_t &sector_mask,
unsigned size, bool wr, unsigned long long cycle,
unsigned wid, unsigned sid, unsigned tpc,
- mem_fetch *original_mf) const = 0;
+ mem_fetch *original_mf,
+ unsigned long long streamID) const = 0;
};
// the maximum number of destination, source, or address uarch operands in a
@@ -961,7 +968,7 @@ class inst_t {
}
bool valid() const { return m_decoded; }
virtual void print_insn(FILE *fp) const {
- fprintf(fp, " [inst @ pc=0x%04x] ", pc);
+ fprintf(fp, " [inst @ pc=0x%04llx] ", pc);
}
bool is_load() const {
return (op == LOAD_OP || op == TENSOR_CORE_LOAD_OP ||
@@ -972,18 +979,22 @@ class inst_t {
memory_op == memory_store);
}
- bool is_fp() const { return ((sp_op == FP__OP));} //VIJAY
- bool is_fpdiv() const { return ((sp_op == FP_DIV_OP));}
- bool is_fpmul() const { return ((sp_op == FP_MUL_OP));}
- bool is_dp() const { return ((sp_op == DP___OP));}
- bool is_dpdiv() const { return ((sp_op == DP_DIV_OP));}
- bool is_dpmul() const { return ((sp_op == DP_MUL_OP));}
- bool is_imul() const { return ((sp_op == INT_MUL_OP));}
- bool is_imul24() const { return ((sp_op == INT_MUL24_OP));}
- bool is_imul32() const { return ((sp_op == INT_MUL32_OP));}
- bool is_idiv() const { return ((sp_op == INT_DIV_OP));}
- bool is_sfu() const {return ((sp_op == FP_SQRT_OP) || (sp_op == FP_LG_OP) || (sp_op == FP_SIN_OP) || (sp_op == FP_EXP_OP) || (sp_op == TENSOR__OP));}
- bool is_alu() const {return (sp_op == INT__OP);}
+ bool is_fp() const { return ((sp_op == FP__OP)); } // VIJAY
+ bool is_fpdiv() const { return ((sp_op == FP_DIV_OP)); }
+ bool is_fpmul() const { return ((sp_op == FP_MUL_OP)); }
+ bool is_dp() const { return ((sp_op == DP___OP)); }
+ bool is_dpdiv() const { return ((sp_op == DP_DIV_OP)); }
+ bool is_dpmul() const { return ((sp_op == DP_MUL_OP)); }
+ bool is_imul() const { return ((sp_op == INT_MUL_OP)); }
+ bool is_imul24() const { return ((sp_op == INT_MUL24_OP)); }
+ bool is_imul32() const { return ((sp_op == INT_MUL32_OP)); }
+ bool is_idiv() const { return ((sp_op == INT_DIV_OP)); }
+ bool is_sfu() const {
+ return ((sp_op == FP_SQRT_OP) || (sp_op == FP_LG_OP) ||
+ (sp_op == FP_SIN_OP) || (sp_op == FP_EXP_OP) ||
+ (sp_op == TENSOR__OP));
+ }
+ bool is_alu() const { return (sp_op == INT__OP); }
unsigned get_num_operands() const { return num_operands; }
unsigned get_num_regs() const { return num_regs; }
@@ -1008,7 +1019,7 @@ class inst_t {
operation_pipeline op_pipe; // code (uarch visible) identify the pipeline of
// the operation (SP, SFU or MEM)
mem_operation mem_op; // code (uarch visible) identify memory type
- bool const_cache_operand; // has a load from constant memory as an operand
+ bool const_cache_operand; // has a load from constant memory as an operand
_memory_op_t memory_op; // memory_op used by ptxplus
unsigned num_operands;
unsigned num_regs; // count vector operand as one register operand
@@ -1052,11 +1063,20 @@ class warp_inst_t : public inst_t {
// constructors
warp_inst_t() {
m_uid = 0;
+ m_streamID = (unsigned long long)-1;
m_empty = true;
m_config = NULL;
+
+ // Ni:
+ m_is_ldgsts = false;
+ m_is_ldgdepbar = false;
+ m_is_depbar = false;
+
+ m_depbar_group_no = 0;
}
warp_inst_t(const core_config *config) {
m_uid = 0;
+ m_streamID = (unsigned long long)-1;
assert(config->warp_size <= MAX_WARP_SIZE);
m_config = config;
m_empty = true;
@@ -1067,6 +1087,13 @@ class warp_inst_t : public inst_t {
m_is_printf = false;
m_is_cdp = 0;
should_do_atomic = true;
+
+ // Ni:
+ m_is_ldgsts = false;
+ m_is_ldgdepbar = false;
+ m_is_depbar = false;
+
+ m_depbar_group_no = 0;
}
virtual ~warp_inst_t() {}
@@ -1077,7 +1104,8 @@ class warp_inst_t : public inst_t {
void clear() { m_empty = true; }
void issue(const active_mask_t &mask, unsigned warp_id,
- unsigned long long cycle, int dynamic_warp_id, int sch_id);
+ unsigned long long cycle, int dynamic_warp_id, int sch_id,
+ unsigned long long streamID);
const active_mask_t &get_active_mask() const { return m_warp_active_mask; }
void completed(unsigned long long cycle)
@@ -1155,7 +1183,7 @@ class warp_inst_t : public inst_t {
// accessors
virtual void print_insn(FILE *fp) const {
- fprintf(fp, " [inst @ pc=0x%04x] ", pc);
+ fprintf(fp, " [inst @ pc=0x%04llx] ", pc);
for (int i = (int)m_config->warp_size - 1; i >= 0; i--)
fprintf(fp, "%c", ((m_warp_active_mask[i]) ? '1' : '0'));
}
@@ -1205,11 +1233,13 @@ class warp_inst_t : public inst_t {
void print(FILE *fout) const;
unsigned get_uid() const { return m_uid; }
+ unsigned long long get_streamID() const { return m_streamID; }
unsigned get_schd_id() const { return m_scheduler_id; }
active_mask_t get_warp_active_mask() const { return m_warp_active_mask; }
protected:
unsigned m_uid;
+ unsigned long long m_streamID;
bool m_empty;
bool m_cache_hit;
unsigned long long issue_cycle;
@@ -1249,6 +1279,13 @@ class warp_inst_t : public inst_t {
// Jin: cdp support
public:
int m_is_cdp;
+
+ // Ni: add boolean to indicate whether the instruction is ldgsts
+ bool m_is_ldgsts;
+ bool m_is_ldgdepbar;
+ bool m_is_depbar;
+
+ unsigned int m_depbar_group_no;
};
void move_warp(warp_inst_t *&dst, warp_inst_t *&src);
@@ -1384,7 +1421,7 @@ class register_set {
assert(has_ready());
warp_inst_t **ready;
ready = NULL;
- unsigned reg_id;
+ unsigned reg_id = 0;
for (unsigned i = 0; i < regs.size(); i++) {
if (not regs[i]->empty()) {
if (ready and (*ready)->get_uid() < regs[i]->get_uid()) {
diff --git a/src/accelwattch/CMakeLists.txt b/src/accelwattch/CMakeLists.txt
new file mode 100644
index 0000000..cb7dd71
--- /dev/null
+++ b/src/accelwattch/CMakeLists.txt
@@ -0,0 +1,46 @@
+set(GPGPUSIM_ACCELWATTCH_NTHREADS "4" CACHE STRING "Accelwattch MCPAT thread count")
+add_library(accelwattch STATIC
+ cacti/Ucache.cc
+ XML_Parse.cc
+ cacti/arbiter.cc
+ cacti/area.cc
+ array.cc
+ cacti/bank.cc
+ cacti/basic_circuit.cc
+ basic_components.cc
+ cacti/cacti_interface.cc
+ cacti/component.cc
+ core.cc
+ cacti/crossbar.cc
+ cacti/decoder.cc
+ cacti/htree2.cc
+ interconnect.cc
+ cacti/io.cc
+ iocontrollers.cc
+ logic.cc
+ main.cc
+ cacti/mat.cc
+ memoryctrl.cc
+ noc.cc
+ cacti/nuca.cc
+ cacti/parameter.cc
+ processor.cc
+ cacti/router.cc
+ sharedcache.cc
+ cacti/subarray.cc
+ cacti/technology.cc
+ cacti/uca.cc
+ cacti/wire.cc
+ xmlParser.cc
+ gpgpu_sim_wrapper.cc)
+target_include_directories(accelwattch PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(accelwattch PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/cacti)
+# Compile options
+target_compile_options(accelwattch PRIVATE "-Wno-unknown-pragmas")
+if($<CONFIG:Debug>)
+ target_compile_definitions(NTHREADS=1)
+else()
+ target_compile_options(accelwattch PRIVATE "-msse2;-mfpmath=sse")
+ target_compile_definitions(accelwattch PRIVATE -DNTHREADS=${GPGPUSIM_ACCELWATTCH_NTHREADS})
+endif()
+target_link_options(accelwattch PRIVATE "-lm;-lpthread;-lz") \ No newline at end of file
diff --git a/src/accelwattch/XML_Parse.cc b/src/accelwattch/XML_Parse.cc
index eaec748..801de6f 100644
--- a/src/accelwattch/XML_Parse.cc
+++ b/src/accelwattch/XML_Parse.cc
@@ -30,14 +30,13 @@
***************************************************************************/
/********************************************************************
* Modified by:
- * Jingwen Leng, University of Texas, Austin
- * Syed Gilani, University of Wisconsin–Madison
+ * Jingwen Leng, University of Texas, Austin
+ * Syed Gilani, University of Wisconsin–Madison
* Tayler Hetherington, University of British Columbia
* Ahmed ElTantawy, University of British Columbia
* Vijay Kandiah, Northwestern University
********************************************************************/
-
#include "XML_Parse.h"
#include <stdio.h>
#include <string>
@@ -45,14 +44,18 @@
using namespace std;
-const char * perf_count_label[] = {
- "TOT_INST,", "FP_INT,", "IC_H,", "IC_M,", "DC_RH,", "DC_RM,", "DC_WH,", "DC_WM,",
- "TC_H,", "TC_M,", "CC_H,", "CC_M,", "SHRD_ACC,", "REG_RD,", "REG_WR,", "NON_REG_OPs,",
- "INT_ACC,", "FPU_ACC,", "DPU_ACC,", "INT_MUL24_ACC,", "INT_MUL32_ACC,", "INT_MUL_ACC,","INT_DIV_ACC,",
- "FP_MUL_ACC,", "FP_DIV_ACC,", "FP_SQRT_ACC,", "FP_LG_ACC,", "FP_SIN_ACC,", "FP_EXP_ACC,", "DP_MUL_ACC,",
- "DP_DIV_ACC,", "TENSOR_ACC,", "TEX_ACC,", "MEM_RD,","MEM_WR,", "MEM_PRE,", "L2_RH,", "L2_RM,", "L2_WH,",
- "L2_WM,", "NOC_A,", "PIPE_A,", "IDLE_CORE_N,", "constant_power"};
-
+const char* perf_count_label[] = {
+ "TOT_INST,", "FP_INT,", "IC_H,", "IC_M,",
+ "DC_RH,", "DC_RM,", "DC_WH,", "DC_WM,",
+ "TC_H,", "TC_M,", "CC_H,", "CC_M,",
+ "SHRD_ACC,", "REG_RD,", "REG_WR,", "NON_REG_OPs,",
+ "INT_ACC,", "FPU_ACC,", "DPU_ACC,", "INT_MUL24_ACC,",
+ "INT_MUL32_ACC,", "INT_MUL_ACC,", "INT_DIV_ACC,", "FP_MUL_ACC,",
+ "FP_DIV_ACC,", "FP_SQRT_ACC,", "FP_LG_ACC,", "FP_SIN_ACC,",
+ "FP_EXP_ACC,", "DP_MUL_ACC,", "DP_DIV_ACC,", "TENSOR_ACC,",
+ "TEX_ACC,", "MEM_RD,", "MEM_WR,", "MEM_PRE,",
+ "L2_RH,", "L2_RM,", "L2_WH,", "L2_WM,",
+ "NOC_A,", "PIPE_A,", "IDLE_CORE_N,", "constant_power"};
void ParseXML::parse(char* filepath) {
unsigned int i, j, k, m, n;
@@ -171,8 +174,6 @@ void ParseXML::parse(char* filepath) {
continue;
}
-
-
if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
"static_cat1_flane") == 0) {
sys.static_cat1_flane =
@@ -355,7 +356,6 @@ void ParseXML::parse(char* filepath) {
continue;
}
-
if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
"target_chip_area") == 0) {
sys.target_chip_area =
@@ -615,106 +615,106 @@ void ParseXML::parse(char* filepath) {
atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "INT_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "INT_ACC") == 0) {
sys.scaling_coefficients[INT_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "FP_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "FP_ACC") == 0) {
sys.scaling_coefficients[FP_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "DP_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "DP_ACC") == 0) {
sys.scaling_coefficients[DP_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "INT_MUL24_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "INT_MUL24_ACC") == 0) {
sys.scaling_coefficients[INT_MUL24_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "INT_MUL32_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "INT_MUL32_ACC") == 0) {
sys.scaling_coefficients[INT_MUL32_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "INT_MUL_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "INT_MUL_ACC") == 0) {
sys.scaling_coefficients[INT_MUL_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "INT_DIV_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "INT_DIV_ACC") == 0) {
sys.scaling_coefficients[INT_DIV_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "FP_MUL_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "FP_MUL_ACC") == 0) {
sys.scaling_coefficients[FP_MUL_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "FP_DIV_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "FP_DIV_ACC") == 0) {
sys.scaling_coefficients[FP_DIV_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "FP_SQRT_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "FP_SQRT_ACC") == 0) {
sys.scaling_coefficients[FP_SQRT_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "FP_LG_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "FP_LG_ACC") == 0) {
sys.scaling_coefficients[FP_LG_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "FP_SIN_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "FP_SIN_ACC") == 0) {
sys.scaling_coefficients[FP_SIN_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "FP_EXP_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "FP_EXP_ACC") == 0) {
sys.scaling_coefficients[FP_EXP_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "DP_MUL_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "DP_MUL_ACC") == 0) {
sys.scaling_coefficients[DP_MUL_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "DP_DIV_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "DP_DIV_ACC") == 0) {
sys.scaling_coefficients[DP_DIV_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "TENSOR_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "TENSOR_ACC") == 0) {
sys.scaling_coefficients[TENSOR_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "TEX_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "TEX_ACC") == 0) {
sys.scaling_coefficients[TEX_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
diff --git a/src/accelwattch/XML_Parse.h b/src/accelwattch/XML_Parse.h
index c82359f..176b82f 100644
--- a/src/accelwattch/XML_Parse.h
+++ b/src/accelwattch/XML_Parse.h
@@ -30,8 +30,8 @@
***************************************************************************/
/********************************************************************
* Modified by:
- * Jingwen Leng, University of Texas, Austin
- * Syed Gilani, University of Wisconsin–Madison
+ * Jingwen Leng, University of Texas, Austin
+ * Syed Gilani, University of Wisconsin–Madison
* Tayler Hetherington, University of British Columbia
* Ahmed ElTantawy, University of British Columbia
* Vijay Kandiah, Northwestern University
@@ -70,7 +70,7 @@ ToXMLStringTool tx,tx2;
extern const char* perf_count_label[];
enum perf_count_t {
- TOT_INST=0,
+ TOT_INST = 0,
FP_INT,
IC_H,
IC_M,
@@ -86,23 +86,23 @@ enum perf_count_t {
REG_RD,
REG_WR,
NON_REG_OPs,
- INT_ACC, //SPU
- FP_ACC, //FPU
- DP_ACC, //FPU
- INT_MUL24_ACC, //SFU
- INT_MUL32_ACC, //SFU
- INT_MUL_ACC, //SFU
- INT_DIV_ACC, //SFU
- FP_MUL_ACC, //SFU
- FP_DIV_ACC, //SFU
- FP_SQRT_ACC, //SFU
- FP_LG_ACC, //SFU
- FP_SIN_ACC, //SFU
- FP_EXP_ACC, //SFU
- DP_MUL_ACC, //SFU
- DP_DIV_ACC, //SFU
- TENSOR_ACC, //SFU
- TEX_ACC, //SFU
+ INT_ACC, // SPU
+ FP_ACC, // FPU
+ DP_ACC, // FPU
+ INT_MUL24_ACC, // SFU
+ INT_MUL32_ACC, // SFU
+ INT_MUL_ACC, // SFU
+ INT_DIV_ACC, // SFU
+ FP_MUL_ACC, // SFU
+ FP_DIV_ACC, // SFU
+ FP_SQRT_ACC, // SFU
+ FP_LG_ACC, // SFU
+ FP_SIN_ACC, // SFU
+ FP_EXP_ACC, // SFU
+ DP_MUL_ACC, // SFU
+ DP_DIV_ACC, // SFU
+ TENSOR_ACC, // SFU
+ TEX_ACC, // SFU
MEM_RD,
MEM_WR,
MEM_PRE,
diff --git a/src/accelwattch/gpgpu_sim_wrapper.cc b/src/accelwattch/gpgpu_sim_wrapper.cc
index 67d9daa..4883c7c 100644
--- a/src/accelwattch/gpgpu_sim_wrapper.cc
+++ b/src/accelwattch/gpgpu_sim_wrapper.cc
@@ -1,16 +1,17 @@
-// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington, Ahmed ElTantawy, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington, Ahmed ElTantawy,
+// Vijay Kandiah, Nikos Hardavellas The University of British Columbia,
+// Northwestern 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.
@@ -33,14 +34,16 @@
#define SFU_BASE_POWER 0
static const char* pwr_cmp_label[] = {
- "IBP,", "ICP,", "DCP,", "TCP,", "CCP,", "SHRDP,", "RFP,", "INTP,",
- "FPUP,", "DPUP,", "INT_MUL24P,", "INT_MUL32P,", "INT_MULP,", "INT_DIVP,",
- "FP_MULP,", "FP_DIVP,", "FP_SQRTP,", "FP_LGP,", "FP_SINP,", "FP_EXP,",
- "DP_MULP,", "DP_DIVP,", "TENSORP,", "TEXP,", "SCHEDP,", "L2CP,", "MCP,", "NOCP,",
- "DRAMP,", "PIPEP,", "IDLE_COREP,", "CONSTP", "STATICP"};
+ "IBP,", "ICP,", "DCP,", "TCP,", "CCP,",
+ "SHRDP,", "RFP,", "INTP,", "FPUP,", "DPUP,",
+ "INT_MUL24P,", "INT_MUL32P,", "INT_MULP,", "INT_DIVP,", "FP_MULP,",
+ "FP_DIVP,", "FP_SQRTP,", "FP_LGP,", "FP_SINP,", "FP_EXP,",
+ "DP_MULP,", "DP_DIVP,", "TENSORP,", "TEXP,", "SCHEDP,",
+ "L2CP,", "MCP,", "NOCP,", "DRAMP,", "PIPEP,",
+ "IDLE_COREP,", "CONSTP", "STATICP"};
enum pwr_cmp_t {
- IBP=0,
+ IBP = 0,
ICP,
DCP,
TCP,
@@ -77,7 +80,8 @@ enum pwr_cmp_t {
};
gpgpu_sim_wrapper::gpgpu_sim_wrapper(bool power_simulation_enabled,
- char* xmlfile, int power_simulation_mode, bool dvfs_enabled) {
+ char* xmlfile, int power_simulation_mode,
+ bool dvfs_enabled) {
kernel_sample_count = 0;
total_sample_count = 0;
@@ -142,7 +146,8 @@ bool gpgpu_sim_wrapper::sanity_check(double a, double b) {
return false;
}
void gpgpu_sim_wrapper::init_mcpat_hw_mode(unsigned gpu_sim_cycle) {
- p->sys.total_cycles = gpu_sim_cycle; //total simulated cycles for current kernel
+ p->sys.total_cycles =
+ gpu_sim_cycle; // total simulated cycles for current kernel
}
void gpgpu_sim_wrapper::init_mcpat(
@@ -150,9 +155,9 @@ void gpgpu_sim_wrapper::init_mcpat(
char* metric_trace_filename, char* steady_state_filename,
bool power_sim_enabled, bool trace_enabled, bool steady_state_enabled,
bool power_per_cycle_dump, double steady_power_deviation,
- double steady_min_period, int zlevel, double init_val,
- int stat_sample_freq, int power_sim_mode, bool dvfs_enabled,
- unsigned clock_freq, unsigned num_shaders) {
+ double steady_min_period, int zlevel, double init_val, int stat_sample_freq,
+ int power_sim_mode, bool dvfs_enabled, unsigned clock_freq,
+ unsigned num_shaders) {
// Write File Headers for (-metrics trace, -power trace)
reset_counters();
@@ -382,10 +387,7 @@ void gpgpu_sim_wrapper::set_l2cache_power(double read_hits, double read_misses,
sample_perf_counters[L2_WM] = write_misses;
}
-void gpgpu_sim_wrapper::set_num_cores(double num_core) {
-
- num_cores = num_core;
-}
+void gpgpu_sim_wrapper::set_num_cores(double num_core) { num_cores = num_core; }
void gpgpu_sim_wrapper::set_idle_core_power(double num_idle_core) {
p->sys.num_idle_cores = num_idle_core;
@@ -411,29 +413,25 @@ void gpgpu_sim_wrapper::set_mem_ctrl_power(double reads, double writes,
sample_perf_counters[MEM_PRE] = dram_precharge;
}
-
void gpgpu_sim_wrapper::set_model_voltage(double model_voltage) {
- modeled_chip_voltage = model_voltage;
+ modeled_chip_voltage = model_voltage;
}
-
void gpgpu_sim_wrapper::set_exec_unit_power(double fpu_accesses,
double ialu_accesses,
double sfu_accesses) {
p->sys.core[0].fpu_accesses = fpu_accesses;
tot_fpu_accesses = fpu_accesses;
- //Integer ALU (not present in Tesla)
+ // Integer ALU (not present in Tesla)
p->sys.core[0].ialu_accesses = ialu_accesses;
- //Sfu accesses
+ // Sfu accesses
p->sys.core[0].mul_accesses = sfu_accesses;
tot_sfu_accesses = sfu_accesses;
}
-PowerscalingCoefficients * gpgpu_sim_wrapper::get_scaling_coeffs()
-{
-
- PowerscalingCoefficients * scalingCoeffs = new PowerscalingCoefficients();
+PowerscalingCoefficients* gpgpu_sim_wrapper::get_scaling_coeffs() {
+ PowerscalingCoefficients* scalingCoeffs = new PowerscalingCoefficients();
scalingCoeffs->int_coeff = p->sys.scaling_coefficients[INT_ACC];
scalingCoeffs->int_mul_coeff = p->sys.scaling_coefficients[INT_MUL_ACC];
@@ -453,68 +451,55 @@ PowerscalingCoefficients * gpgpu_sim_wrapper::get_scaling_coeffs()
scalingCoeffs->tensor_coeff = p->sys.scaling_coefficients[TENSOR_ACC];
scalingCoeffs->tex_coeff = p->sys.scaling_coefficients[TEX_ACC];
return scalingCoeffs;
-
}
-void gpgpu_sim_wrapper::set_int_accesses(double ialu_accesses,
- double imul24_accesses,
- double imul32_accesses,
- double imul_accesses,
- double idiv_accesses)
-{
-
- sample_perf_counters[INT_ACC]=ialu_accesses;
- sample_perf_counters[INT_MUL24_ACC]=imul24_accesses;
- sample_perf_counters[INT_MUL32_ACC]=imul32_accesses;
- sample_perf_counters[INT_MUL_ACC]=imul_accesses;
- sample_perf_counters[INT_DIV_ACC]=idiv_accesses;
+void gpgpu_sim_wrapper::set_int_accesses(double ialu_accesses,
+ double imul24_accesses,
+ double imul32_accesses,
+ double imul_accesses,
+ double idiv_accesses) {
+ sample_perf_counters[INT_ACC] = ialu_accesses;
+ sample_perf_counters[INT_MUL24_ACC] = imul24_accesses;
+ sample_perf_counters[INT_MUL32_ACC] = imul32_accesses;
+ sample_perf_counters[INT_MUL_ACC] = imul_accesses;
+ sample_perf_counters[INT_DIV_ACC] = idiv_accesses;
}
-void gpgpu_sim_wrapper::set_dp_accesses(double dpu_accesses,
- double dpmul_accesses,
- double dpdiv_accesses)
-{
- sample_perf_counters[DP_ACC]=dpu_accesses;
- sample_perf_counters[DP_MUL_ACC]=dpmul_accesses;
- sample_perf_counters[DP_DIV_ACC]=dpdiv_accesses;
+void gpgpu_sim_wrapper::set_dp_accesses(double dpu_accesses,
+ double dpmul_accesses,
+ double dpdiv_accesses) {
+ sample_perf_counters[DP_ACC] = dpu_accesses;
+ sample_perf_counters[DP_MUL_ACC] = dpmul_accesses;
+ sample_perf_counters[DP_DIV_ACC] = dpdiv_accesses;
}
-void gpgpu_sim_wrapper::set_fp_accesses(double fpu_accesses,
- double fpmul_accesses,
- double fpdiv_accesses)
-{
- sample_perf_counters[FP_ACC]=fpu_accesses;
- sample_perf_counters[FP_MUL_ACC]=fpmul_accesses;
- sample_perf_counters[FP_DIV_ACC]=fpdiv_accesses;
+void gpgpu_sim_wrapper::set_fp_accesses(double fpu_accesses,
+ double fpmul_accesses,
+ double fpdiv_accesses) {
+ sample_perf_counters[FP_ACC] = fpu_accesses;
+ sample_perf_counters[FP_MUL_ACC] = fpmul_accesses;
+ sample_perf_counters[FP_DIV_ACC] = fpdiv_accesses;
}
-void gpgpu_sim_wrapper::set_trans_accesses(double sqrt_accesses,
- double log_accesses,
- double sin_accesses,
- double exp_accesses)
-{
-
- sample_perf_counters[FP_SQRT_ACC]=sqrt_accesses;
- sample_perf_counters[FP_LG_ACC]=log_accesses;
- sample_perf_counters[FP_SIN_ACC]=sin_accesses;
- sample_perf_counters[FP_EXP_ACC]=exp_accesses;
-
+void gpgpu_sim_wrapper::set_trans_accesses(double sqrt_accesses,
+ double log_accesses,
+ double sin_accesses,
+ double exp_accesses) {
+ sample_perf_counters[FP_SQRT_ACC] = sqrt_accesses;
+ sample_perf_counters[FP_LG_ACC] = log_accesses;
+ sample_perf_counters[FP_SIN_ACC] = sin_accesses;
+ sample_perf_counters[FP_EXP_ACC] = exp_accesses;
}
-void gpgpu_sim_wrapper::set_tensor_accesses(double tensor_accesses)
-{
- sample_perf_counters[TENSOR_ACC]=tensor_accesses;
-
+void gpgpu_sim_wrapper::set_tensor_accesses(double tensor_accesses) {
+ sample_perf_counters[TENSOR_ACC] = tensor_accesses;
}
-void gpgpu_sim_wrapper::set_tex_accesses(double tex_accesses)
-{
- sample_perf_counters[TEX_ACC]=tex_accesses;
-
+void gpgpu_sim_wrapper::set_tex_accesses(double tex_accesses) {
+ sample_perf_counters[TEX_ACC] = tex_accesses;
}
-void gpgpu_sim_wrapper::set_avg_active_threads(float active_threads)
-{
+void gpgpu_sim_wrapper::set_avg_active_threads(float active_threads) {
avg_threads_per_warp = (unsigned)ceil(active_threads);
avg_threads_per_warp_tot += active_threads;
}
@@ -536,7 +521,8 @@ void gpgpu_sim_wrapper::power_metrics_calculations() {
kernel_sample_count++;
// Current sample power
- double sample_power = proc->rt_power.readOp.dynamic + sample_cmp_pwr[CONSTP] + sample_cmp_pwr[STATICP];
+ double sample_power = proc->rt_power.readOp.dynamic + sample_cmp_pwr[CONSTP] +
+ sample_cmp_pwr[STATICP];
// double sample_power;
// for(unsigned i=0; i<num_pwr_cmps; i++){
// sample_power+=sample_cmp_pwr[i]; //fix for dvfs
@@ -602,371 +588,503 @@ void gpgpu_sim_wrapper::print_trace_files() {
close_files();
}
-void gpgpu_sim_wrapper::update_coefficients()
-{
+void gpgpu_sim_wrapper::update_coefficients() {
+ initpower_coeff[FP_INT] = proc->cores[0]->get_coefficient_fpint_insts();
+ effpower_coeff[FP_INT] =
+ initpower_coeff[FP_INT] * p->sys.scaling_coefficients[FP_INT];
- initpower_coeff[FP_INT]=proc->cores[0]->get_coefficient_fpint_insts();
- effpower_coeff[FP_INT]=initpower_coeff[FP_INT] * p->sys.scaling_coefficients[FP_INT];
+ initpower_coeff[TOT_INST] = proc->cores[0]->get_coefficient_tot_insts();
+ effpower_coeff[TOT_INST] =
+ initpower_coeff[TOT_INST] * p->sys.scaling_coefficients[TOT_INST];
- initpower_coeff[TOT_INST]=proc->cores[0]->get_coefficient_tot_insts();
- effpower_coeff[TOT_INST]=initpower_coeff[TOT_INST] * p->sys.scaling_coefficients[TOT_INST];
+ initpower_coeff[REG_RD] =
+ proc->cores[0]->get_coefficient_regreads_accesses() *
+ (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate);
+ initpower_coeff[REG_WR] =
+ proc->cores[0]->get_coefficient_regwrites_accesses() *
+ (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate);
+ initpower_coeff[NON_REG_OPs] =
+ proc->cores[0]->get_coefficient_noregfileops_accesses() *
+ (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate);
+ effpower_coeff[REG_RD] =
+ initpower_coeff[REG_RD] * p->sys.scaling_coefficients[REG_RD];
+ effpower_coeff[REG_WR] =
+ initpower_coeff[REG_WR] * p->sys.scaling_coefficients[REG_WR];
+ effpower_coeff[NON_REG_OPs] =
+ initpower_coeff[NON_REG_OPs] * p->sys.scaling_coefficients[NON_REG_OPs];
- initpower_coeff[REG_RD]=proc->cores[0]->get_coefficient_regreads_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate);
- initpower_coeff[REG_WR]=proc->cores[0]->get_coefficient_regwrites_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate);
- initpower_coeff[NON_REG_OPs]=proc->cores[0]->get_coefficient_noregfileops_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate);
- effpower_coeff[REG_RD]=initpower_coeff[REG_RD]*p->sys.scaling_coefficients[REG_RD];
- effpower_coeff[REG_WR]=initpower_coeff[REG_WR]*p->sys.scaling_coefficients[REG_WR];
- effpower_coeff[NON_REG_OPs]=initpower_coeff[NON_REG_OPs]*p->sys.scaling_coefficients[NON_REG_OPs];
+ initpower_coeff[IC_H] = proc->cores[0]->get_coefficient_icache_hits();
+ initpower_coeff[IC_M] = proc->cores[0]->get_coefficient_icache_misses();
+ effpower_coeff[IC_H] =
+ initpower_coeff[IC_H] * p->sys.scaling_coefficients[IC_H];
+ effpower_coeff[IC_M] =
+ initpower_coeff[IC_M] * p->sys.scaling_coefficients[IC_M];
- initpower_coeff[IC_H]=proc->cores[0]->get_coefficient_icache_hits();
- initpower_coeff[IC_M]=proc->cores[0]->get_coefficient_icache_misses();
- effpower_coeff[IC_H]=initpower_coeff[IC_H]*p->sys.scaling_coefficients[IC_H];
- effpower_coeff[IC_M]=initpower_coeff[IC_M]*p->sys.scaling_coefficients[IC_M];
+ initpower_coeff[CC_H] = (proc->cores[0]->get_coefficient_ccache_readhits() +
+ proc->get_coefficient_readcoalescing());
+ initpower_coeff[CC_M] = (proc->cores[0]->get_coefficient_ccache_readmisses() +
+ proc->get_coefficient_readcoalescing());
+ effpower_coeff[CC_H] =
+ initpower_coeff[CC_H] * p->sys.scaling_coefficients[CC_H];
+ effpower_coeff[CC_M] =
+ initpower_coeff[CC_M] * p->sys.scaling_coefficients[CC_M];
- initpower_coeff[CC_H]=(proc->cores[0]->get_coefficient_ccache_readhits()+proc->get_coefficient_readcoalescing());
- initpower_coeff[CC_M]=(proc->cores[0]->get_coefficient_ccache_readmisses()+proc->get_coefficient_readcoalescing());
- effpower_coeff[CC_H]=initpower_coeff[CC_H]*p->sys.scaling_coefficients[CC_H];
- effpower_coeff[CC_M]=initpower_coeff[CC_M]*p->sys.scaling_coefficients[CC_M];
+ initpower_coeff[TC_H] = (proc->cores[0]->get_coefficient_tcache_readhits() +
+ proc->get_coefficient_readcoalescing());
+ initpower_coeff[TC_M] = (proc->cores[0]->get_coefficient_tcache_readmisses() +
+ proc->get_coefficient_readcoalescing());
+ effpower_coeff[TC_H] =
+ initpower_coeff[TC_H] * p->sys.scaling_coefficients[TC_H];
+ effpower_coeff[TC_M] =
+ initpower_coeff[TC_M] * p->sys.scaling_coefficients[TC_M];
- initpower_coeff[TC_H]=(proc->cores[0]->get_coefficient_tcache_readhits()+proc->get_coefficient_readcoalescing());
- initpower_coeff[TC_M]=(proc->cores[0]->get_coefficient_tcache_readmisses()+proc->get_coefficient_readcoalescing());
- effpower_coeff[TC_H]=initpower_coeff[TC_H]*p->sys.scaling_coefficients[TC_H];
- effpower_coeff[TC_M]=initpower_coeff[TC_M]*p->sys.scaling_coefficients[TC_M];
+ initpower_coeff[SHRD_ACC] =
+ proc->cores[0]->get_coefficient_sharedmemory_readhits();
+ effpower_coeff[SHRD_ACC] =
+ initpower_coeff[SHRD_ACC] * p->sys.scaling_coefficients[SHRD_ACC];
- initpower_coeff[SHRD_ACC]=proc->cores[0]->get_coefficient_sharedmemory_readhits();
- effpower_coeff[SHRD_ACC]=initpower_coeff[SHRD_ACC]*p->sys.scaling_coefficients[SHRD_ACC];
+ initpower_coeff[DC_RH] = (proc->cores[0]->get_coefficient_dcache_readhits() +
+ proc->get_coefficient_readcoalescing());
+ initpower_coeff[DC_RM] =
+ (proc->cores[0]->get_coefficient_dcache_readmisses() +
+ proc->get_coefficient_readcoalescing());
+ initpower_coeff[DC_WH] = (proc->cores[0]->get_coefficient_dcache_writehits() +
+ proc->get_coefficient_writecoalescing());
+ initpower_coeff[DC_WM] =
+ (proc->cores[0]->get_coefficient_dcache_writemisses() +
+ proc->get_coefficient_writecoalescing());
+ effpower_coeff[DC_RH] =
+ initpower_coeff[DC_RH] * p->sys.scaling_coefficients[DC_RH];
+ effpower_coeff[DC_RM] =
+ initpower_coeff[DC_RM] * p->sys.scaling_coefficients[DC_RM];
+ effpower_coeff[DC_WH] =
+ initpower_coeff[DC_WH] * p->sys.scaling_coefficients[DC_WH];
+ effpower_coeff[DC_WM] =
+ initpower_coeff[DC_WM] * p->sys.scaling_coefficients[DC_WM];
- initpower_coeff[DC_RH]=(proc->cores[0]->get_coefficient_dcache_readhits() + proc->get_coefficient_readcoalescing());
- initpower_coeff[DC_RM]=(proc->cores[0]->get_coefficient_dcache_readmisses() + proc->get_coefficient_readcoalescing());
- initpower_coeff[DC_WH]=(proc->cores[0]->get_coefficient_dcache_writehits() + proc->get_coefficient_writecoalescing());
- initpower_coeff[DC_WM]=(proc->cores[0]->get_coefficient_dcache_writemisses() + proc->get_coefficient_writecoalescing());
- effpower_coeff[DC_RH]=initpower_coeff[DC_RH]*p->sys.scaling_coefficients[DC_RH];
- effpower_coeff[DC_RM]=initpower_coeff[DC_RM]*p->sys.scaling_coefficients[DC_RM];
- effpower_coeff[DC_WH]=initpower_coeff[DC_WH]*p->sys.scaling_coefficients[DC_WH];
- effpower_coeff[DC_WM]=initpower_coeff[DC_WM]*p->sys.scaling_coefficients[DC_WM];
+ initpower_coeff[L2_RH] = proc->get_coefficient_l2_read_hits();
+ initpower_coeff[L2_RM] = proc->get_coefficient_l2_read_misses();
+ initpower_coeff[L2_WH] = proc->get_coefficient_l2_write_hits();
+ initpower_coeff[L2_WM] = proc->get_coefficient_l2_write_misses();
+ effpower_coeff[L2_RH] =
+ initpower_coeff[L2_RH] * p->sys.scaling_coefficients[L2_RH];
+ effpower_coeff[L2_RM] =
+ initpower_coeff[L2_RM] * p->sys.scaling_coefficients[L2_RM];
+ effpower_coeff[L2_WH] =
+ initpower_coeff[L2_WH] * p->sys.scaling_coefficients[L2_WH];
+ effpower_coeff[L2_WM] =
+ initpower_coeff[L2_WM] * p->sys.scaling_coefficients[L2_WM];
- initpower_coeff[L2_RH]=proc->get_coefficient_l2_read_hits();
- initpower_coeff[L2_RM]=proc->get_coefficient_l2_read_misses();
- initpower_coeff[L2_WH]=proc->get_coefficient_l2_write_hits();
- initpower_coeff[L2_WM]=proc->get_coefficient_l2_write_misses();
- effpower_coeff[L2_RH]=initpower_coeff[L2_RH]*p->sys.scaling_coefficients[L2_RH];
- effpower_coeff[L2_RM]=initpower_coeff[L2_RM]*p->sys.scaling_coefficients[L2_RM];
- effpower_coeff[L2_WH]=initpower_coeff[L2_WH]*p->sys.scaling_coefficients[L2_WH];
- effpower_coeff[L2_WM]=initpower_coeff[L2_WM]*p->sys.scaling_coefficients[L2_WM];
+ initpower_coeff[IDLE_CORE_N] =
+ p->sys.idle_core_power * proc->cores[0]->executionTime;
+ effpower_coeff[IDLE_CORE_N] =
+ initpower_coeff[IDLE_CORE_N] * p->sys.scaling_coefficients[IDLE_CORE_N];
- initpower_coeff[IDLE_CORE_N]=p->sys.idle_core_power * proc->cores[0]->executionTime;
- effpower_coeff[IDLE_CORE_N]=initpower_coeff[IDLE_CORE_N]*p->sys.scaling_coefficients[IDLE_CORE_N];
+ initpower_coeff[PIPE_A] = proc->cores[0]->get_coefficient_duty_cycle();
+ effpower_coeff[PIPE_A] =
+ initpower_coeff[PIPE_A] * p->sys.scaling_coefficients[PIPE_A];
- initpower_coeff[PIPE_A]=proc->cores[0]->get_coefficient_duty_cycle();
- effpower_coeff[PIPE_A]=initpower_coeff[PIPE_A]*p->sys.scaling_coefficients[PIPE_A];
+ initpower_coeff[MEM_RD] = proc->get_coefficient_mem_reads();
+ initpower_coeff[MEM_WR] = proc->get_coefficient_mem_writes();
+ initpower_coeff[MEM_PRE] = proc->get_coefficient_mem_pre();
+ effpower_coeff[MEM_RD] =
+ initpower_coeff[MEM_RD] * p->sys.scaling_coefficients[MEM_RD];
+ effpower_coeff[MEM_WR] =
+ initpower_coeff[MEM_WR] * p->sys.scaling_coefficients[MEM_WR];
+ effpower_coeff[MEM_PRE] =
+ initpower_coeff[MEM_PRE] * p->sys.scaling_coefficients[MEM_PRE];
- initpower_coeff[MEM_RD]=proc->get_coefficient_mem_reads();
- initpower_coeff[MEM_WR]=proc->get_coefficient_mem_writes();
- initpower_coeff[MEM_PRE]=proc->get_coefficient_mem_pre();
- effpower_coeff[MEM_RD]=initpower_coeff[MEM_RD]*p->sys.scaling_coefficients[MEM_RD];
- effpower_coeff[MEM_WR]=initpower_coeff[MEM_WR]*p->sys.scaling_coefficients[MEM_WR];
- effpower_coeff[MEM_PRE]=initpower_coeff[MEM_PRE]*p->sys.scaling_coefficients[MEM_PRE];
-
double fp_coeff = proc->cores[0]->get_coefficient_fpu_accesses();
double sfu_coeff = proc->cores[0]->get_coefficient_sfu_accesses();
- initpower_coeff[INT_ACC]= proc->cores[0]->get_coefficient_ialu_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate);
+ initpower_coeff[INT_ACC] =
+ proc->cores[0]->get_coefficient_ialu_accesses() *
+ (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate);
- if(tot_fpu_accesses != 0){
- initpower_coeff[FP_ACC]= fp_coeff * sample_perf_counters[FP_ACC]/tot_fpu_accesses;
- initpower_coeff[DP_ACC]= fp_coeff * sample_perf_counters[DP_ACC]/tot_fpu_accesses;
- }
- else{
- initpower_coeff[FP_ACC]= 0;
- initpower_coeff[DP_ACC]= 0;
+ if (tot_fpu_accesses != 0) {
+ initpower_coeff[FP_ACC] =
+ fp_coeff * sample_perf_counters[FP_ACC] / tot_fpu_accesses;
+ initpower_coeff[DP_ACC] =
+ fp_coeff * sample_perf_counters[DP_ACC] / tot_fpu_accesses;
+ } else {
+ initpower_coeff[FP_ACC] = 0;
+ initpower_coeff[DP_ACC] = 0;
}
- if(tot_sfu_accesses != 0){
- initpower_coeff[INT_MUL24_ACC]= sfu_coeff * sample_perf_counters[INT_MUL24_ACC]/tot_sfu_accesses;
- initpower_coeff[INT_MUL32_ACC]= sfu_coeff * sample_perf_counters[INT_MUL32_ACC]/tot_sfu_accesses;
- initpower_coeff[INT_MUL_ACC]= sfu_coeff * sample_perf_counters[INT_MUL_ACC]/tot_sfu_accesses;
- initpower_coeff[INT_DIV_ACC]= sfu_coeff * sample_perf_counters[INT_DIV_ACC]/tot_sfu_accesses;
- initpower_coeff[DP_MUL_ACC]= sfu_coeff * sample_perf_counters[DP_MUL_ACC]/tot_sfu_accesses;
- initpower_coeff[DP_DIV_ACC]= sfu_coeff * sample_perf_counters[DP_DIV_ACC]/tot_sfu_accesses;
- initpower_coeff[FP_MUL_ACC]= sfu_coeff * sample_perf_counters[FP_MUL_ACC]/tot_sfu_accesses;
- initpower_coeff[FP_DIV_ACC]= sfu_coeff * sample_perf_counters[FP_DIV_ACC]/tot_sfu_accesses;
- initpower_coeff[FP_SQRT_ACC]= sfu_coeff * sample_perf_counters[FP_SQRT_ACC]/tot_sfu_accesses;
- initpower_coeff[FP_LG_ACC]= sfu_coeff * sample_perf_counters[FP_LG_ACC]/tot_sfu_accesses;
- initpower_coeff[FP_SIN_ACC]= sfu_coeff * sample_perf_counters[FP_SIN_ACC]/tot_sfu_accesses;
- initpower_coeff[FP_EXP_ACC]= sfu_coeff * sample_perf_counters[FP_EXP_ACC]/tot_sfu_accesses;
- initpower_coeff[TENSOR_ACC]= sfu_coeff * sample_perf_counters[TENSOR_ACC]/tot_sfu_accesses;
- initpower_coeff[TEX_ACC]= sfu_coeff * sample_perf_counters[TEX_ACC]/tot_sfu_accesses;
- }
- else{
- initpower_coeff[INT_MUL24_ACC]= 0;
- initpower_coeff[INT_MUL32_ACC]= 0;
- initpower_coeff[INT_MUL_ACC]= 0;
- initpower_coeff[INT_DIV_ACC]= 0;
- initpower_coeff[DP_MUL_ACC]= 0;
- initpower_coeff[DP_DIV_ACC]= 0;
- initpower_coeff[FP_MUL_ACC]= 0;
- initpower_coeff[FP_DIV_ACC]= 0;
- initpower_coeff[FP_SQRT_ACC]= 0;
- initpower_coeff[FP_LG_ACC]= 0;
- initpower_coeff[FP_SIN_ACC]= 0;
- initpower_coeff[FP_EXP_ACC]= 0;
- initpower_coeff[TENSOR_ACC]= 0;
- initpower_coeff[TEX_ACC]= 0;
+ if (tot_sfu_accesses != 0) {
+ initpower_coeff[INT_MUL24_ACC] =
+ sfu_coeff * sample_perf_counters[INT_MUL24_ACC] / tot_sfu_accesses;
+ initpower_coeff[INT_MUL32_ACC] =
+ sfu_coeff * sample_perf_counters[INT_MUL32_ACC] / tot_sfu_accesses;
+ initpower_coeff[INT_MUL_ACC] =
+ sfu_coeff * sample_perf_counters[INT_MUL_ACC] / tot_sfu_accesses;
+ initpower_coeff[INT_DIV_ACC] =
+ sfu_coeff * sample_perf_counters[INT_DIV_ACC] / tot_sfu_accesses;
+ initpower_coeff[DP_MUL_ACC] =
+ sfu_coeff * sample_perf_counters[DP_MUL_ACC] / tot_sfu_accesses;
+ initpower_coeff[DP_DIV_ACC] =
+ sfu_coeff * sample_perf_counters[DP_DIV_ACC] / tot_sfu_accesses;
+ initpower_coeff[FP_MUL_ACC] =
+ sfu_coeff * sample_perf_counters[FP_MUL_ACC] / tot_sfu_accesses;
+ initpower_coeff[FP_DIV_ACC] =
+ sfu_coeff * sample_perf_counters[FP_DIV_ACC] / tot_sfu_accesses;
+ initpower_coeff[FP_SQRT_ACC] =
+ sfu_coeff * sample_perf_counters[FP_SQRT_ACC] / tot_sfu_accesses;
+ initpower_coeff[FP_LG_ACC] =
+ sfu_coeff * sample_perf_counters[FP_LG_ACC] / tot_sfu_accesses;
+ initpower_coeff[FP_SIN_ACC] =
+ sfu_coeff * sample_perf_counters[FP_SIN_ACC] / tot_sfu_accesses;
+ initpower_coeff[FP_EXP_ACC] =
+ sfu_coeff * sample_perf_counters[FP_EXP_ACC] / tot_sfu_accesses;
+ initpower_coeff[TENSOR_ACC] =
+ sfu_coeff * sample_perf_counters[TENSOR_ACC] / tot_sfu_accesses;
+ initpower_coeff[TEX_ACC] =
+ sfu_coeff * sample_perf_counters[TEX_ACC] / tot_sfu_accesses;
+ } else {
+ initpower_coeff[INT_MUL24_ACC] = 0;
+ initpower_coeff[INT_MUL32_ACC] = 0;
+ initpower_coeff[INT_MUL_ACC] = 0;
+ initpower_coeff[INT_DIV_ACC] = 0;
+ initpower_coeff[DP_MUL_ACC] = 0;
+ initpower_coeff[DP_DIV_ACC] = 0;
+ initpower_coeff[FP_MUL_ACC] = 0;
+ initpower_coeff[FP_DIV_ACC] = 0;
+ initpower_coeff[FP_SQRT_ACC] = 0;
+ initpower_coeff[FP_LG_ACC] = 0;
+ initpower_coeff[FP_SIN_ACC] = 0;
+ initpower_coeff[FP_EXP_ACC] = 0;
+ initpower_coeff[TENSOR_ACC] = 0;
+ initpower_coeff[TEX_ACC] = 0;
}
- effpower_coeff[INT_ACC]= initpower_coeff[INT_ACC];
- effpower_coeff[FP_ACC]= initpower_coeff[FP_ACC];
- effpower_coeff[DP_ACC]= initpower_coeff[DP_ACC];
- effpower_coeff[INT_MUL24_ACC]= initpower_coeff[INT_MUL24_ACC];
- effpower_coeff[INT_MUL32_ACC]= initpower_coeff[INT_MUL32_ACC];
- effpower_coeff[INT_MUL_ACC]= initpower_coeff[INT_MUL_ACC];
- effpower_coeff[INT_DIV_ACC]= initpower_coeff[INT_DIV_ACC];
- effpower_coeff[DP_MUL_ACC]= initpower_coeff[DP_MUL_ACC];
- effpower_coeff[DP_DIV_ACC]= initpower_coeff[DP_DIV_ACC];
- effpower_coeff[FP_MUL_ACC]= initpower_coeff[FP_MUL_ACC];
- effpower_coeff[FP_DIV_ACC]= initpower_coeff[FP_DIV_ACC];
- effpower_coeff[FP_SQRT_ACC]= initpower_coeff[FP_SQRT_ACC];
- effpower_coeff[FP_LG_ACC]= initpower_coeff[FP_LG_ACC];
- effpower_coeff[FP_SIN_ACC]= initpower_coeff[FP_SIN_ACC];
- effpower_coeff[FP_EXP_ACC]= initpower_coeff[FP_EXP_ACC];
- effpower_coeff[TENSOR_ACC]= initpower_coeff[TENSOR_ACC];
- effpower_coeff[TEX_ACC]= initpower_coeff[TEX_ACC];
+ effpower_coeff[INT_ACC] = initpower_coeff[INT_ACC];
+ effpower_coeff[FP_ACC] = initpower_coeff[FP_ACC];
+ effpower_coeff[DP_ACC] = initpower_coeff[DP_ACC];
+ effpower_coeff[INT_MUL24_ACC] = initpower_coeff[INT_MUL24_ACC];
+ effpower_coeff[INT_MUL32_ACC] = initpower_coeff[INT_MUL32_ACC];
+ effpower_coeff[INT_MUL_ACC] = initpower_coeff[INT_MUL_ACC];
+ effpower_coeff[INT_DIV_ACC] = initpower_coeff[INT_DIV_ACC];
+ effpower_coeff[DP_MUL_ACC] = initpower_coeff[DP_MUL_ACC];
+ effpower_coeff[DP_DIV_ACC] = initpower_coeff[DP_DIV_ACC];
+ effpower_coeff[FP_MUL_ACC] = initpower_coeff[FP_MUL_ACC];
+ effpower_coeff[FP_DIV_ACC] = initpower_coeff[FP_DIV_ACC];
+ effpower_coeff[FP_SQRT_ACC] = initpower_coeff[FP_SQRT_ACC];
+ effpower_coeff[FP_LG_ACC] = initpower_coeff[FP_LG_ACC];
+ effpower_coeff[FP_SIN_ACC] = initpower_coeff[FP_SIN_ACC];
+ effpower_coeff[FP_EXP_ACC] = initpower_coeff[FP_EXP_ACC];
+ effpower_coeff[TENSOR_ACC] = initpower_coeff[TENSOR_ACC];
+ effpower_coeff[TEX_ACC] = initpower_coeff[TEX_ACC];
- initpower_coeff[NOC_A]=proc->get_coefficient_noc_accesses();
- effpower_coeff[NOC_A]=initpower_coeff[NOC_A]*p->sys.scaling_coefficients[NOC_A];
+ initpower_coeff[NOC_A] = proc->get_coefficient_noc_accesses();
+ effpower_coeff[NOC_A] =
+ initpower_coeff[NOC_A] * p->sys.scaling_coefficients[NOC_A];
- //const_dynamic_power=proc->get_const_dynamic_power()/(proc->cores[0]->executionTime);
+ // const_dynamic_power=proc->get_const_dynamic_power()/(proc->cores[0]->executionTime);
- for(unsigned i=0; i<num_perf_counters; i++){
- initpower_coeff[i]/=(proc->cores[0]->executionTime);
- effpower_coeff[i]/=(proc->cores[0]->executionTime);
+ for (unsigned i = 0; i < num_perf_counters; i++) {
+ initpower_coeff[i] /= (proc->cores[0]->executionTime);
+ effpower_coeff[i] /= (proc->cores[0]->executionTime);
}
}
-double gpgpu_sim_wrapper::calculate_static_power(){
- double int_accesses = initpower_coeff[INT_ACC] + initpower_coeff[INT_MUL24_ACC] + initpower_coeff[INT_MUL32_ACC] + initpower_coeff[INT_MUL_ACC] + initpower_coeff[INT_DIV_ACC];
- double int_add_accesses = initpower_coeff[INT_ACC];
- double int_mul_accesses = initpower_coeff[INT_MUL24_ACC] + initpower_coeff[INT_MUL32_ACC] + initpower_coeff[INT_MUL_ACC] + initpower_coeff[INT_DIV_ACC];
- double fp_accesses = initpower_coeff[FP_ACC] + initpower_coeff[FP_MUL_ACC] + initpower_coeff[FP_DIV_ACC];
- double dp_accesses = initpower_coeff[DP_ACC] + initpower_coeff[DP_MUL_ACC] + initpower_coeff[DP_DIV_ACC];
- double sfu_accesses = initpower_coeff[FP_SQRT_ACC] + initpower_coeff[FP_LG_ACC] + initpower_coeff[FP_SIN_ACC] + initpower_coeff[FP_EXP_ACC];
- double tensor_accesses = initpower_coeff[TENSOR_ACC];
- double tex_accesses = initpower_coeff[TEX_ACC];
- double total_static_power = 0.0;
- double base_static_power = 0.0;
- double lane_static_power = 0.0;
- double per_active_core = (num_cores - num_idle_cores)/num_cores;
-
+double gpgpu_sim_wrapper::calculate_static_power() {
+ double int_accesses =
+ initpower_coeff[INT_ACC] + initpower_coeff[INT_MUL24_ACC] +
+ initpower_coeff[INT_MUL32_ACC] + initpower_coeff[INT_MUL_ACC] +
+ initpower_coeff[INT_DIV_ACC];
+ double int_add_accesses = initpower_coeff[INT_ACC];
+ double int_mul_accesses =
+ initpower_coeff[INT_MUL24_ACC] + initpower_coeff[INT_MUL32_ACC] +
+ initpower_coeff[INT_MUL_ACC] + initpower_coeff[INT_DIV_ACC];
+ double fp_accesses = initpower_coeff[FP_ACC] + initpower_coeff[FP_MUL_ACC] +
+ initpower_coeff[FP_DIV_ACC];
+ double dp_accesses = initpower_coeff[DP_ACC] + initpower_coeff[DP_MUL_ACC] +
+ initpower_coeff[DP_DIV_ACC];
+ double sfu_accesses =
+ initpower_coeff[FP_SQRT_ACC] + initpower_coeff[FP_LG_ACC] +
+ initpower_coeff[FP_SIN_ACC] + initpower_coeff[FP_EXP_ACC];
+ double tensor_accesses = initpower_coeff[TENSOR_ACC];
+ double tex_accesses = initpower_coeff[TEX_ACC];
+ double total_static_power = 0.0;
+ double base_static_power = 0.0;
+ double lane_static_power = 0.0;
+ double per_active_core = (num_cores - num_idle_cores) / num_cores;
- double l1_accesses = initpower_coeff[DC_RH] + initpower_coeff[DC_RM] + initpower_coeff[DC_WH] + initpower_coeff[DC_WM];
- double l2_accesses = initpower_coeff[L2_RH] + initpower_coeff[L2_RM] + initpower_coeff[L2_WH] + initpower_coeff[L2_WM];
- double shared_accesses = initpower_coeff[SHRD_ACC];
+ double l1_accesses = initpower_coeff[DC_RH] + initpower_coeff[DC_RM] +
+ initpower_coeff[DC_WH] + initpower_coeff[DC_WM];
+ double l2_accesses = initpower_coeff[L2_RH] + initpower_coeff[L2_RM] +
+ initpower_coeff[L2_WH] + initpower_coeff[L2_WM];
+ double shared_accesses = initpower_coeff[SHRD_ACC];
+ if (avg_threads_per_warp ==
+ 0) { // no functional unit threads, check for memory or a 'LIGHT_SM'
+ if (l1_accesses != 0.0)
+ return (p->sys.static_l1_flane * per_active_core);
+ else if (shared_accesses != 0.0)
+ return (p->sys.static_shared_flane * per_active_core);
+ else if (l2_accesses != 0.0)
+ return (p->sys.static_l2_flane * per_active_core);
+ else // LIGHT_SM
+ return (p->sys.static_light_flane *
+ per_active_core); // return LIGHT_SM base static power
+ }
- if(avg_threads_per_warp == 0){ //no functional unit threads, check for memory or a 'LIGHT_SM'
- if(l1_accesses != 0.0)
- return (p->sys.static_l1_flane*per_active_core);
- else if(shared_accesses != 0.0)
- return (p->sys.static_shared_flane*per_active_core);
- else if(l2_accesses != 0.0)
- return (p->sys.static_l2_flane*per_active_core);
- else //LIGHT_SM
- return (p->sys.static_light_flane*per_active_core); //return LIGHT_SM base static power
- }
-
- /* using a linear model for thread divergence */
- if((int_accesses != 0.0) && (fp_accesses != 0.0) && (dp_accesses != 0.0) && (sfu_accesses == 0.0) && (tensor_accesses == 0.0) && (tex_accesses == 0.0)){
- /* INT_FP_DP */
- base_static_power = p->sys.static_cat3_flane;
- lane_static_power = p->sys.static_cat3_addlane;
- }
+ /* using a linear model for thread divergence */
+ if ((int_accesses != 0.0) && (fp_accesses != 0.0) && (dp_accesses != 0.0) &&
+ (sfu_accesses == 0.0) && (tensor_accesses == 0.0) &&
+ (tex_accesses == 0.0)) {
+ /* INT_FP_DP */
+ base_static_power = p->sys.static_cat3_flane;
+ lane_static_power = p->sys.static_cat3_addlane;
+ }
- else if((int_accesses != 0.0) && (fp_accesses != 0.0) && (dp_accesses == 0.0) && (sfu_accesses == 0.0) && (tensor_accesses != 0.0) && (tex_accesses == 0.0)){
- /* INT_FP_TENSOR */
- base_static_power = p->sys.static_cat6_flane;
- lane_static_power = p->sys.static_cat6_addlane;
- }
+ else if ((int_accesses != 0.0) && (fp_accesses != 0.0) &&
+ (dp_accesses == 0.0) && (sfu_accesses == 0.0) &&
+ (tensor_accesses != 0.0) && (tex_accesses == 0.0)) {
+ /* INT_FP_TENSOR */
+ base_static_power = p->sys.static_cat6_flane;
+ lane_static_power = p->sys.static_cat6_addlane;
+ }
- else if((int_accesses != 0.0) && (fp_accesses != 0.0) && (dp_accesses == 0.0) && (sfu_accesses != 0.0) && (tensor_accesses == 0.0) && (tex_accesses == 0.0)){
- /* INT_FP_SFU */
- base_static_power = p->sys.static_cat4_flane;
- lane_static_power = p->sys.static_cat4_addlane;
- }
+ else if ((int_accesses != 0.0) && (fp_accesses != 0.0) &&
+ (dp_accesses == 0.0) && (sfu_accesses != 0.0) &&
+ (tensor_accesses == 0.0) && (tex_accesses == 0.0)) {
+ /* INT_FP_SFU */
+ base_static_power = p->sys.static_cat4_flane;
+ lane_static_power = p->sys.static_cat4_addlane;
+ }
- else if((int_accesses != 0.0) && (fp_accesses != 0.0) && (dp_accesses == 0.0) && (sfu_accesses == 0.0) && (tensor_accesses == 0.0) && (tex_accesses != 0.0)){
- /* INT_FP_TEX */
- base_static_power = p->sys.static_cat5_flane;
- lane_static_power = p->sys.static_cat5_addlane;
- }
+ else if ((int_accesses != 0.0) && (fp_accesses != 0.0) &&
+ (dp_accesses == 0.0) && (sfu_accesses == 0.0) &&
+ (tensor_accesses == 0.0) && (tex_accesses != 0.0)) {
+ /* INT_FP_TEX */
+ base_static_power = p->sys.static_cat5_flane;
+ lane_static_power = p->sys.static_cat5_addlane;
+ }
- else if((int_accesses != 0.0) && (fp_accesses != 0.0) && (dp_accesses == 0.0) && (sfu_accesses == 0.0) && (tensor_accesses == 0.0) && (tex_accesses == 0.0)){
- /* INT_FP */
- base_static_power = p->sys.static_cat2_flane;
- lane_static_power = p->sys.static_cat2_addlane;
- }
+ else if ((int_accesses != 0.0) && (fp_accesses != 0.0) &&
+ (dp_accesses == 0.0) && (sfu_accesses == 0.0) &&
+ (tensor_accesses == 0.0) && (tex_accesses == 0.0)) {
+ /* INT_FP */
+ base_static_power = p->sys.static_cat2_flane;
+ lane_static_power = p->sys.static_cat2_addlane;
+ }
- else if((int_accesses != 0.0) && (fp_accesses == 0.0) && (dp_accesses == 0.0) && (sfu_accesses == 0.0) && (tensor_accesses == 0.0) && (tex_accesses == 0.0)){
- /* INT */
- /* Seperating INT_ADD only and INT_MUL only from mix of INT instructions */
- if((int_add_accesses != 0.0) && (int_mul_accesses == 0.0)){ //INT_ADD
- base_static_power = p->sys.static_intadd_flane;
- lane_static_power = p->sys.static_intadd_addlane;
- }
- else if((int_add_accesses == 0.0) && (int_mul_accesses != 0.0)){ //INT_MUL
- base_static_power = p->sys.static_intmul_flane;
- lane_static_power = p->sys.static_intmul_addlane;
- }
- else{ //INT_ADD+MUL
- base_static_power = p->sys.static_cat1_flane;
- lane_static_power = p->sys.static_cat1_addlane;
- }
- }
+ else if ((int_accesses != 0.0) && (fp_accesses == 0.0) &&
+ (dp_accesses == 0.0) && (sfu_accesses == 0.0) &&
+ (tensor_accesses == 0.0) && (tex_accesses == 0.0)) {
+ /* INT */
+ /* Seperating INT_ADD only and INT_MUL only from mix of INT instructions */
+ if ((int_add_accesses != 0.0) && (int_mul_accesses == 0.0)) { // INT_ADD
+ base_static_power = p->sys.static_intadd_flane;
+ lane_static_power = p->sys.static_intadd_addlane;
+ } else if ((int_add_accesses == 0.0) &&
+ (int_mul_accesses != 0.0)) { // INT_MUL
+ base_static_power = p->sys.static_intmul_flane;
+ lane_static_power = p->sys.static_intmul_addlane;
+ } else { // INT_ADD+MUL
+ base_static_power = p->sys.static_cat1_flane;
+ lane_static_power = p->sys.static_cat1_addlane;
+ }
+ }
- else if((int_accesses == 0.0) && (fp_accesses == 0.0) && (dp_accesses == 0.0) && (sfu_accesses == 0.0) && (tensor_accesses == 0.0) && (tex_accesses == 0.0)){
- /* LIGHT_SM or memory only sample */
- lane_static_power = 0.0; //addlane static power is 0 for l1/l2/shared memory only accesses
- if(l1_accesses != 0.0)
- base_static_power = p->sys.static_l1_flane;
- else if(shared_accesses != 0.0)
- base_static_power = p->sys.static_shared_flane;
- else if(l2_accesses != 0.0)
- base_static_power = p->sys.static_l2_flane;
- else{
- base_static_power = p->sys.static_light_flane;
- lane_static_power = p->sys.static_light_addlane;
- }
- }
- else{
- base_static_power = p->sys.static_geomean_flane; //GEOMEAN except LIGHT_SM if we don't fall into any of the categories above
- lane_static_power = p->sys.static_geomean_addlane;
- }
+ else if ((int_accesses == 0.0) && (fp_accesses == 0.0) &&
+ (dp_accesses == 0.0) && (sfu_accesses == 0.0) &&
+ (tensor_accesses == 0.0) && (tex_accesses == 0.0)) {
+ /* LIGHT_SM or memory only sample */
+ lane_static_power =
+ 0.0; // addlane static power is 0 for l1/l2/shared memory only accesses
+ if (l1_accesses != 0.0)
+ base_static_power = p->sys.static_l1_flane;
+ else if (shared_accesses != 0.0)
+ base_static_power = p->sys.static_shared_flane;
+ else if (l2_accesses != 0.0)
+ base_static_power = p->sys.static_l2_flane;
+ else {
+ base_static_power = p->sys.static_light_flane;
+ lane_static_power = p->sys.static_light_addlane;
+ }
+ } else {
+ base_static_power =
+ p->sys.static_geomean_flane; // GEOMEAN except LIGHT_SM if we don't
+ // fall into any of the categories above
+ lane_static_power = p->sys.static_geomean_addlane;
+ }
- total_static_power = base_static_power + (((double)avg_threads_per_warp-1.0)*lane_static_power); //Linear Model
- return (total_static_power*per_active_core);
+ total_static_power =
+ base_static_power + (((double)avg_threads_per_warp - 1.0) *
+ lane_static_power); // Linear Model
+ return (total_static_power * per_active_core);
}
-void gpgpu_sim_wrapper::update_components_power()
-{
-
+void gpgpu_sim_wrapper::update_components_power() {
update_coefficients();
- proc_power=proc->rt_power.readOp.dynamic;
- sample_cmp_pwr[IBP]=(proc->cores[0]->ifu->IB->rt_power.readOp.dynamic
- +proc->cores[0]->ifu->IB->rt_power.writeOp.dynamic
- +proc->cores[0]->ifu->ID_misc->rt_power.readOp.dynamic
- +proc->cores[0]->ifu->ID_operand->rt_power.readOp.dynamic
- +proc->cores[0]->ifu->ID_inst->rt_power.readOp.dynamic)/(proc->cores[0]->executionTime);
+ proc_power = proc->rt_power.readOp.dynamic;
+ sample_cmp_pwr[IBP] =
+ (proc->cores[0]->ifu->IB->rt_power.readOp.dynamic +
+ proc->cores[0]->ifu->IB->rt_power.writeOp.dynamic +
+ proc->cores[0]->ifu->ID_misc->rt_power.readOp.dynamic +
+ proc->cores[0]->ifu->ID_operand->rt_power.readOp.dynamic +
+ proc->cores[0]->ifu->ID_inst->rt_power.readOp.dynamic) /
+ (proc->cores[0]->executionTime);
- sample_cmp_pwr[ICP]=proc->cores[0]->ifu->icache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime);
+ sample_cmp_pwr[ICP] = proc->cores[0]->ifu->icache.rt_power.readOp.dynamic /
+ (proc->cores[0]->executionTime);
- sample_cmp_pwr[DCP]=proc->cores[0]->lsu->dcache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime);
+ sample_cmp_pwr[DCP] = proc->cores[0]->lsu->dcache.rt_power.readOp.dynamic /
+ (proc->cores[0]->executionTime);
- sample_cmp_pwr[TCP]=proc->cores[0]->lsu->tcache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime);
+ sample_cmp_pwr[TCP] = proc->cores[0]->lsu->tcache.rt_power.readOp.dynamic /
+ (proc->cores[0]->executionTime);
- sample_cmp_pwr[CCP]=proc->cores[0]->lsu->ccache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime);
+ sample_cmp_pwr[CCP] = proc->cores[0]->lsu->ccache.rt_power.readOp.dynamic /
+ (proc->cores[0]->executionTime);
- sample_cmp_pwr[SHRDP]=proc->cores[0]->lsu->sharedmemory.rt_power.readOp.dynamic/(proc->cores[0]->executionTime);
+ sample_cmp_pwr[SHRDP] =
+ proc->cores[0]->lsu->sharedmemory.rt_power.readOp.dynamic /
+ (proc->cores[0]->executionTime);
- sample_cmp_pwr[RFP]=(proc->cores[0]->exu->rfu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime))
- *(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate);
+ sample_cmp_pwr[RFP] =
+ (proc->cores[0]->exu->rfu->rt_power.readOp.dynamic /
+ (proc->cores[0]->executionTime)) *
+ (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate);
- double sample_fp_pwr = (proc->cores[0]->exu->fp_u->rt_power.readOp.dynamic/(proc->cores[0]->executionTime));
+ double sample_fp_pwr = (proc->cores[0]->exu->fp_u->rt_power.readOp.dynamic /
+ (proc->cores[0]->executionTime));
- double sample_sfu_pwr = (proc->cores[0]->exu->mul->rt_power.readOp.dynamic/(proc->cores[0]->executionTime));
+ double sample_sfu_pwr = (proc->cores[0]->exu->mul->rt_power.readOp.dynamic /
+ (proc->cores[0]->executionTime));
- sample_cmp_pwr[INTP]=(proc->cores[0]->exu->exeu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime))
- *(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate);
+ sample_cmp_pwr[INTP] =
+ (proc->cores[0]->exu->exeu->rt_power.readOp.dynamic /
+ (proc->cores[0]->executionTime)) *
+ (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate);
-
- if(tot_fpu_accesses != 0){
- sample_cmp_pwr[FPUP]= sample_fp_pwr * sample_perf_counters[FP_ACC]/tot_fpu_accesses;
- sample_cmp_pwr[DPUP]= sample_fp_pwr * sample_perf_counters[DP_ACC]/tot_fpu_accesses;
- }
- else{
- sample_cmp_pwr[FPUP]= 0;
- sample_cmp_pwr[DPUP]= 0;
- }
- if(tot_sfu_accesses != 0){
- sample_cmp_pwr[INT_MUL24P]= sample_sfu_pwr * sample_perf_counters[INT_MUL24_ACC]/tot_sfu_accesses;
- sample_cmp_pwr[INT_MUL32P]= sample_sfu_pwr * sample_perf_counters[INT_MUL32_ACC]/tot_sfu_accesses;
- sample_cmp_pwr[INT_MULP]= sample_sfu_pwr * sample_perf_counters[INT_MUL_ACC]/tot_sfu_accesses;
- sample_cmp_pwr[INT_DIVP]= sample_sfu_pwr * sample_perf_counters[INT_DIV_ACC]/tot_sfu_accesses;
- sample_cmp_pwr[FP_MULP]= sample_sfu_pwr * sample_perf_counters[FP_MUL_ACC]/tot_sfu_accesses;
- sample_cmp_pwr[FP_DIVP]= sample_sfu_pwr * sample_perf_counters[FP_DIV_ACC]/tot_sfu_accesses;
- sample_cmp_pwr[FP_SQRTP]= sample_sfu_pwr * sample_perf_counters[FP_SQRT_ACC]/tot_sfu_accesses;
- sample_cmp_pwr[FP_LGP]= sample_sfu_pwr * sample_perf_counters[FP_LG_ACC]/tot_sfu_accesses;
- sample_cmp_pwr[FP_SINP]= sample_sfu_pwr * sample_perf_counters[FP_SIN_ACC]/tot_sfu_accesses;
- sample_cmp_pwr[FP_EXP]= sample_sfu_pwr * sample_perf_counters[FP_EXP_ACC]/tot_sfu_accesses;
- sample_cmp_pwr[DP_MULP]= sample_sfu_pwr * sample_perf_counters[DP_MUL_ACC]/tot_sfu_accesses;
- sample_cmp_pwr[DP_DIVP]= sample_sfu_pwr * sample_perf_counters[DP_DIV_ACC]/tot_sfu_accesses;
- sample_cmp_pwr[TENSORP]= sample_sfu_pwr * sample_perf_counters[TENSOR_ACC]/tot_sfu_accesses;
- sample_cmp_pwr[TEXP]= sample_sfu_pwr * sample_perf_counters[TEX_ACC]/tot_sfu_accesses;
+ if (tot_fpu_accesses != 0) {
+ sample_cmp_pwr[FPUP] =
+ sample_fp_pwr * sample_perf_counters[FP_ACC] / tot_fpu_accesses;
+ sample_cmp_pwr[DPUP] =
+ sample_fp_pwr * sample_perf_counters[DP_ACC] / tot_fpu_accesses;
+ } else {
+ sample_cmp_pwr[FPUP] = 0;
+ sample_cmp_pwr[DPUP] = 0;
}
- else{
- sample_cmp_pwr[INT_MUL24P]= 0;
- sample_cmp_pwr[INT_MUL32P]= 0;
- sample_cmp_pwr[INT_MULP]= 0;
- sample_cmp_pwr[INT_DIVP]= 0;
- sample_cmp_pwr[FP_MULP]= 0;
- sample_cmp_pwr[FP_DIVP]= 0;
- sample_cmp_pwr[FP_SQRTP]= 0;
- sample_cmp_pwr[FP_LGP]= 0;
- sample_cmp_pwr[FP_SINP]= 0;
- sample_cmp_pwr[FP_EXP]= 0;
- sample_cmp_pwr[DP_MULP]= 0;
- sample_cmp_pwr[DP_DIVP]= 0;
- sample_cmp_pwr[TENSORP]= 0;
- sample_cmp_pwr[TEXP]= 0;
+ if (tot_sfu_accesses != 0) {
+ sample_cmp_pwr[INT_MUL24P] =
+ sample_sfu_pwr * sample_perf_counters[INT_MUL24_ACC] / tot_sfu_accesses;
+ sample_cmp_pwr[INT_MUL32P] =
+ sample_sfu_pwr * sample_perf_counters[INT_MUL32_ACC] / tot_sfu_accesses;
+ sample_cmp_pwr[INT_MULP] =
+ sample_sfu_pwr * sample_perf_counters[INT_MUL_ACC] / tot_sfu_accesses;
+ sample_cmp_pwr[INT_DIVP] =
+ sample_sfu_pwr * sample_perf_counters[INT_DIV_ACC] / tot_sfu_accesses;
+ sample_cmp_pwr[FP_MULP] =
+ sample_sfu_pwr * sample_perf_counters[FP_MUL_ACC] / tot_sfu_accesses;
+ sample_cmp_pwr[FP_DIVP] =
+ sample_sfu_pwr * sample_perf_counters[FP_DIV_ACC] / tot_sfu_accesses;
+ sample_cmp_pwr[FP_SQRTP] =
+ sample_sfu_pwr * sample_perf_counters[FP_SQRT_ACC] / tot_sfu_accesses;
+ sample_cmp_pwr[FP_LGP] =
+ sample_sfu_pwr * sample_perf_counters[FP_LG_ACC] / tot_sfu_accesses;
+ sample_cmp_pwr[FP_SINP] =
+ sample_sfu_pwr * sample_perf_counters[FP_SIN_ACC] / tot_sfu_accesses;
+ sample_cmp_pwr[FP_EXP] =
+ sample_sfu_pwr * sample_perf_counters[FP_EXP_ACC] / tot_sfu_accesses;
+ sample_cmp_pwr[DP_MULP] =
+ sample_sfu_pwr * sample_perf_counters[DP_MUL_ACC] / tot_sfu_accesses;
+ sample_cmp_pwr[DP_DIVP] =
+ sample_sfu_pwr * sample_perf_counters[DP_DIV_ACC] / tot_sfu_accesses;
+ sample_cmp_pwr[TENSORP] =
+ sample_sfu_pwr * sample_perf_counters[TENSOR_ACC] / tot_sfu_accesses;
+ sample_cmp_pwr[TEXP] =
+ sample_sfu_pwr * sample_perf_counters[TEX_ACC] / tot_sfu_accesses;
+ } else {
+ sample_cmp_pwr[INT_MUL24P] = 0;
+ sample_cmp_pwr[INT_MUL32P] = 0;
+ sample_cmp_pwr[INT_MULP] = 0;
+ sample_cmp_pwr[INT_DIVP] = 0;
+ sample_cmp_pwr[FP_MULP] = 0;
+ sample_cmp_pwr[FP_DIVP] = 0;
+ sample_cmp_pwr[FP_SQRTP] = 0;
+ sample_cmp_pwr[FP_LGP] = 0;
+ sample_cmp_pwr[FP_SINP] = 0;
+ sample_cmp_pwr[FP_EXP] = 0;
+ sample_cmp_pwr[DP_MULP] = 0;
+ sample_cmp_pwr[DP_DIVP] = 0;
+ sample_cmp_pwr[TENSORP] = 0;
+ sample_cmp_pwr[TEXP] = 0;
}
- sample_cmp_pwr[SCHEDP]=proc->cores[0]->exu->scheu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime);
+ sample_cmp_pwr[SCHEDP] = proc->cores[0]->exu->scheu->rt_power.readOp.dynamic /
+ (proc->cores[0]->executionTime);
- sample_cmp_pwr[L2CP]=(proc->XML->sys.number_of_L2s>0)? proc->l2array[0]->rt_power.readOp.dynamic/(proc->cores[0]->executionTime):0;
+ sample_cmp_pwr[L2CP] = (proc->XML->sys.number_of_L2s > 0)
+ ? proc->l2array[0]->rt_power.readOp.dynamic /
+ (proc->cores[0]->executionTime)
+ : 0;
- sample_cmp_pwr[MCP]=(proc->mc->rt_power.readOp.dynamic-proc->mc->dram->rt_power.readOp.dynamic)/(proc->cores[0]->executionTime);
+ sample_cmp_pwr[MCP] = (proc->mc->rt_power.readOp.dynamic -
+ proc->mc->dram->rt_power.readOp.dynamic) /
+ (proc->cores[0]->executionTime);
- sample_cmp_pwr[NOCP]=proc->nocs[0]->rt_power.readOp.dynamic/(proc->cores[0]->executionTime);
+ sample_cmp_pwr[NOCP] =
+ proc->nocs[0]->rt_power.readOp.dynamic / (proc->cores[0]->executionTime);
- sample_cmp_pwr[DRAMP]=proc->mc->dram->rt_power.readOp.dynamic/(proc->cores[0]->executionTime);
+ sample_cmp_pwr[DRAMP] =
+ proc->mc->dram->rt_power.readOp.dynamic / (proc->cores[0]->executionTime);
- sample_cmp_pwr[PIPEP]=proc->cores[0]->Pipeline_energy/(proc->cores[0]->executionTime);
+ sample_cmp_pwr[PIPEP] =
+ proc->cores[0]->Pipeline_energy / (proc->cores[0]->executionTime);
- sample_cmp_pwr[IDLE_COREP]=proc->cores[0]->IdleCoreEnergy/(proc->cores[0]->executionTime);
+ sample_cmp_pwr[IDLE_COREP] =
+ proc->cores[0]->IdleCoreEnergy / (proc->cores[0]->executionTime);
- // This constant dynamic power (e.g., clock power) part is estimated via regression model.
- sample_cmp_pwr[CONSTP]=0;
- sample_cmp_pwr[STATICP]=0;
- // double cnst_dyn = proc->get_const_dynamic_power()/(proc->cores[0]->executionTime);
- // // If the regression scaling term is greater than the recorded constant dynamic power
- // // then use the difference (other portion already added to dynamic power). Else,
+ // This constant dynamic power (e.g., clock power) part is estimated via
+ // regression model.
+ sample_cmp_pwr[CONSTP] = 0;
+ sample_cmp_pwr[STATICP] = 0;
+ // double cnst_dyn =
+ // proc->get_const_dynamic_power()/(proc->cores[0]->executionTime);
+ // // If the regression scaling term is greater than the recorded constant
+ // dynamic power
+ // // then use the difference (other portion already added to dynamic power).
+ // Else,
// // all the constant dynamic power is accounted for, add nothing.
// if(p->sys.scaling_coefficients[constant_power] > cnst_dyn)
- // sample_cmp_pwr[CONSTP] = (p->sys.scaling_coefficients[constant_power]-cnst_dyn);
+ // sample_cmp_pwr[CONSTP] =
+ // (p->sys.scaling_coefficients[constant_power]-cnst_dyn);
sample_cmp_pwr[CONSTP] = p->sys.scaling_coefficients[constant_power];
sample_cmp_pwr[STATICP] = calculate_static_power();
- if(g_dvfs_enabled){
- double voltage_ratio = modeled_chip_voltage/p->sys.modeled_chip_voltage_ref;
- sample_cmp_pwr[IDLE_COREP] *= voltage_ratio; // static power scaled by voltage_ratio
- sample_cmp_pwr[STATICP] *= voltage_ratio; // static power scaled by voltage_ratio
- for(unsigned i=0; i<num_pwr_cmps; i++){
- if((i != IDLE_COREP) && (i != STATICP)){
- sample_cmp_pwr[i] *= voltage_ratio*voltage_ratio; // dynamic power scaled by square of voltage_ratio
- }
- }
+ if (g_dvfs_enabled) {
+ double voltage_ratio =
+ modeled_chip_voltage / p->sys.modeled_chip_voltage_ref;
+ sample_cmp_pwr[IDLE_COREP] *=
+ voltage_ratio; // static power scaled by voltage_ratio
+ sample_cmp_pwr[STATICP] *=
+ voltage_ratio; // static power scaled by voltage_ratio
+ for (unsigned i = 0; i < num_pwr_cmps; i++) {
+ if ((i != IDLE_COREP) && (i != STATICP)) {
+ sample_cmp_pwr[i] *=
+ voltage_ratio *
+ voltage_ratio; // dynamic power scaled by square of voltage_ratio
+ }
+ }
}
-
- proc_power+=sample_cmp_pwr[CONSTP]+sample_cmp_pwr[STATICP];
- if(!g_dvfs_enabled){ // sanity check will fail when voltage scaling is applied, fix later
- double sum_pwr_cmp=0;
- for(unsigned i=0; i<num_pwr_cmps; i++){
- sum_pwr_cmp+=sample_cmp_pwr[i];
- }
- bool check=false;
- check=sanity_check(sum_pwr_cmp,proc_power);
- if(!check)
- printf("sum_pwr_cmp %f : proc_power %f \n",sum_pwr_cmp,proc_power);
- assert("Total Power does not equal the sum of the components\n" && (check));
+
+ proc_power += sample_cmp_pwr[CONSTP] + sample_cmp_pwr[STATICP];
+ if (!g_dvfs_enabled) { // sanity check will fail when voltage scaling is
+ // applied, fix later
+ double sum_pwr_cmp = 0;
+ for (unsigned i = 0; i < num_pwr_cmps; i++) {
+ sum_pwr_cmp += sample_cmp_pwr[i];
+ }
+ bool check = false;
+ check = sanity_check(sum_pwr_cmp, proc_power);
+ if (!check)
+ printf("sum_pwr_cmp %f : proc_power %f \n", sum_pwr_cmp, proc_power);
+ assert("Total Power does not equal the sum of the components\n" && (check));
}
}
@@ -993,13 +1111,12 @@ void gpgpu_sim_wrapper::print_power_kernel_stats(
}
powerfile << "gpu_avg_threads_per_warp = "
- << avg_threads_per_warp_tot / (double)kernel_sample_count
- << std::endl;
+ << avg_threads_per_warp_tot / (double)kernel_sample_count
+ << std::endl;
for (unsigned i = 0; i < num_perf_counters; ++i) {
powerfile << "gpu_tot_" << perf_count_label[i] << " = "
- << kernel_cmp_perf_counters[i].avg
- << std::endl;
+ << kernel_cmp_perf_counters[i].avg << std::endl;
}
powerfile << std::endl << "Kernel Maximum Power Data:" << std::endl;
diff --git a/src/accelwattch/gpgpu_sim_wrapper.h b/src/accelwattch/gpgpu_sim_wrapper.h
index 33c4b72..dd71d89 100644
--- a/src/accelwattch/gpgpu_sim_wrapper.h
+++ b/src/accelwattch/gpgpu_sim_wrapper.h
@@ -1,16 +1,17 @@
-// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington, Ahmed ElTantawy, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington, Ahmed ElTantawy,
+// Vijay Kandiah, Nikos Hardavellas The University of British Columbia,
+// Northwestern 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.
@@ -58,31 +59,32 @@ struct avg_max_min_counters {
#ifndef COEFF_STRUCT
#define COEFF_STRUCT
-struct PowerscalingCoefficients{
- double int_coeff;
- double int_mul_coeff;
- double int_mul24_coeff;
- double int_mul32_coeff;
- double int_div_coeff;
- double fp_coeff;
- double dp_coeff;
- double fp_mul_coeff;
- double fp_div_coeff;
- double dp_mul_coeff;
- double dp_div_coeff;
- double sqrt_coeff;
- double log_coeff;
- double sin_coeff;
- double exp_coeff;
- double tensor_coeff;
- double tex_coeff;
+struct PowerscalingCoefficients {
+ double int_coeff;
+ double int_mul_coeff;
+ double int_mul24_coeff;
+ double int_mul32_coeff;
+ double int_div_coeff;
+ double fp_coeff;
+ double dp_coeff;
+ double fp_mul_coeff;
+ double fp_div_coeff;
+ double dp_mul_coeff;
+ double dp_div_coeff;
+ double sqrt_coeff;
+ double log_coeff;
+ double sin_coeff;
+ double exp_coeff;
+ double tensor_coeff;
+ double tex_coeff;
};
#endif
class gpgpu_sim_wrapper {
public:
- gpgpu_sim_wrapper(bool power_simulation_enabled, char* xmlfile, int power_simulation_mode, bool dvfs_enabled);
+ gpgpu_sim_wrapper(bool power_simulation_enabled, char* xmlfile,
+ int power_simulation_mode, bool dvfs_enabled);
~gpgpu_sim_wrapper();
void init_mcpat(char* xmlfile, char* powerfile, char* power_trace_file,
@@ -90,8 +92,9 @@ class gpgpu_sim_wrapper {
bool power_sim_enabled, bool trace_enabled,
bool steady_state_enabled, bool power_per_cycle_dump,
double steady_power_deviation, double steady_min_period,
- int zlevel, double init_val, int stat_sample_freq, int power_sim_mode,
- bool dvfs_enabled, unsigned clock_freq, unsigned num_shaders);
+ int zlevel, double init_val, int stat_sample_freq,
+ int power_sim_mode, bool dvfs_enabled, unsigned clock_freq,
+ unsigned num_shaders);
void init_mcpat_hw_mode(unsigned gpu_sim_cycle);
void detect_print_steady_state(int position, double init_val);
void close_files();
@@ -128,15 +131,15 @@ class gpgpu_sim_wrapper {
void set_mem_ctrl_power(double reads, double writes, double dram_precharge);
void set_exec_unit_power(double fpu_accesses, double ialu_accesses,
double sfu_accesses);
- void set_int_accesses(double ialu_accesses, double imul24_accesses,
- double imul32_accesses, double imul_accesses,
+ void set_int_accesses(double ialu_accesses, double imul24_accesses,
+ double imul32_accesses, double imul_accesses,
double idiv_accesses);
- void set_dp_accesses(double dpu_accesses, double dpmul_accesses,
+ void set_dp_accesses(double dpu_accesses, double dpmul_accesses,
double dpdiv_accesses);
- void set_fp_accesses(double fpu_accesses, double fpmul_accesses,
+ void set_fp_accesses(double fpu_accesses, double fpmul_accesses,
double fpdiv_accesses);
- void set_trans_accesses(double sqrt_accesses, double log_accesses,
- double sin_accesses, double exp_accesses);
+ void set_trans_accesses(double sqrt_accesses, double log_accesses,
+ double sin_accesses, double exp_accesses);
void set_tensor_accesses(double tensor_accesses);
void set_tex_accesses(double tex_accesses);
void set_avg_active_threads(float active_threads);
@@ -145,7 +148,7 @@ class gpgpu_sim_wrapper {
void set_NoC_power(double noc_tot_acc);
bool sanity_check(double a, double b);
- PowerscalingCoefficients * get_scaling_coeffs();
+ PowerscalingCoefficients* get_scaling_coeffs();
private:
void print_steady_state(int position, double init_val);
diff --git a/src/accelwattch/processor.cc b/src/accelwattch/processor.cc
index 9e7f5b2..d5c7cdd 100644
--- a/src/accelwattch/processor.cc
+++ b/src/accelwattch/processor.cc
@@ -30,8 +30,8 @@
***************************************************************************/
/********************************************************************
* Modified by:
- * Jingwen Leng, University of Texas, Austin
- * Syed Gilani, University of Wisconsin–Madison
+ * Jingwen Leng, University of Texas, Austin
+ * Syed Gilani, University of Wisconsin–Madison
* Tayler Hetherington, University of British Columbia
* Ahmed ElTantawy, University of British Columbia
* Vijay Kandiah, Northwestern University
diff --git a/src/accelwattch/xmlParser.cc b/src/accelwattch/xmlParser.cc
index 8f49b39..780d2ad 100644
--- a/src/accelwattch/xmlParser.cc
+++ b/src/accelwattch/xmlParser.cc
@@ -1236,12 +1236,10 @@ static NextToken GetNextToken(XML *pXML, int *pcbToken,
// Indicate we are dealing with text
*pType = eTokenText;
while ((ch = getNextChar(pXML))) {
- if
- XML_isSPACECHAR(ch) {
- indexStart++;
- break;
- }
- else if (ch == _CXML('/')) {
+ if XML_isSPACECHAR (ch) {
+ indexStart++;
+ break;
+ } else if (ch == _CXML('/')) {
// If we find a slash then this maybe text or a short hand end tag
// Peek at the next character to see it we have short hand end tag
ch = pXML->lpXML[pXML->nIndex];
@@ -2193,15 +2191,15 @@ int XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker,
nResult++;
}
} else
- // If there are child nodes we need to terminate the start tag
- if (nElementI) {
- if (lpszMarker) lpszMarker[nResult - 1] = _CXML('>');
- if (nFormat >= 0) {
- if (lpszMarker) lpszMarker[nResult] = _CXML('\n');
- nResult++;
- }
- } else
- nResult--;
+ // If there are child nodes we need to terminate the start tag
+ if (nElementI) {
+ if (lpszMarker) lpszMarker[nResult - 1] = _CXML('>');
+ if (nFormat >= 0) {
+ if (lpszMarker) lpszMarker[nResult] = _CXML('\n');
+ nResult++;
+ }
+ } else
+ nResult--;
}
// Calculate the child format for when we recurse. This is used to
diff --git a/src/cuda-sim/CMakeLists.txt b/src/cuda-sim/CMakeLists.txt
new file mode 100644
index 0000000..3378b77
--- /dev/null
+++ b/src/cuda-sim/CMakeLists.txt
@@ -0,0 +1,78 @@
+# Specify Flex and Bison target
+BISON_TARGET(ptx_parser ptx.y ${CMAKE_CURRENT_BINARY_DIR}/ptx.tab.c
+ COMPILE_FLAGS "--name-prefix=ptx_ -v -d --file-prefix=${CMAKE_CURRENT_BINARY_DIR}/ptx")
+BISON_TARGET(ptxinfo_parser ptxinfo.y ${CMAKE_CURRENT_BINARY_DIR}/ptxinfo.tab.c
+ COMPILE_FLAGS "--name-prefix=ptxinfo_ -v -d --file-prefix=${CMAKE_CURRENT_BINARY_DIR}/ptxinfo")
+FLEX_TARGET(ptx_lexer ptx.l ${CMAKE_CURRENT_BINARY_DIR}/lex.ptx_.c)
+FLEX_TARGET(ptxinfo_lexer ptxinfo.l ${CMAKE_CURRENT_BINARY_DIR}/lex.ptxinfo_.c)
+ADD_FLEX_BISON_DEPENDENCY(ptx_lexer ptx_parser)
+ADD_FLEX_BISON_DEPENDENCY(ptxinfo_lexer ptxinfo_parser)
+
+# The flex and bison are using CXX, need to set their generated files to CXX so that
+# they can be compiled and linked
+set_source_files_properties(${BISON_ptx_parser_OUTPUT_SOURCE}
+ ${FLEX_ptx_lexer_OUTPUTS}
+ ${BISON_ptxinfo_parser_OUTPUT_SOURCE}
+ ${FLEX_ptxinfo_lexer_OUTPUTS}
+ PROPERTIES LANGUAGE CXX)
+# Create libptxsim.a
+add_library(ptxsim STATIC
+ cuda_device_printf.cc
+ cuda_device_runtime.cc
+ cuda-sim.cc
+ instructions.cc
+ memory.cc
+ ptx_ir.cc
+ ptx_loader.cc
+ ptx_parser.cc
+ ptx_sim.cc
+ ptx-stats.cc
+ decuda_pred_table/decuda_pred_table.cc
+ ${BISON_ptx_parser_OUTPUT_SOURCE} ${FLEX_ptx_lexer_OUTPUTS}
+ ${BISON_ptxinfo_parser_OUTPUT_SOURCE} ${FLEX_ptxinfo_lexer_OUTPUTS})
+
+# Define this for all source files, though we just need it for parser
+target_compile_definitions(ptxsim PRIVATE YYDEBUG)
+target_include_directories(ptxsim PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/decuda_pred_table)
+target_include_directories(ptxsim PUBLIC ${CUDAToolkit_INCLUDE_DIRS})
+target_include_directories(ptxsim PRIVATE ${CMAKE_BINARY_DIR})
+
+# ptxsim need buildstring
+add_dependencies(ptxsim gen_build_string)
+
+# Create instructions.h using custom command
+add_custom_target(gen_instructions_h DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/instructions.h)
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/instructions.h
+ COMMAND touch ${CMAKE_CURRENT_BINARY_DIR}/instructions.h
+ COMMAND chmod +w ${CMAKE_CURRENT_BINARY_DIR}/instructions.h
+ COMMAND echo "// DO NOT EDIT THIS FILE! IT IS AUTOMATICALLY GENERATED BY THE MAKEFILE (see target for instructions.h)" > ${CMAKE_CURRENT_BINARY_DIR}/instructions.h
+ COMMAND echo "#include \"ptx_ir.h\"" >> ${CMAKE_CURRENT_BINARY_DIR}/instructions.h
+ COMMAND echo "#ifndef instructions_h_included" >> ${CMAKE_CURRENT_BINARY_DIR}/instructions.h
+ COMMAND echo "#define instructions_h_included" >> ${CMAKE_CURRENT_BINARY_DIR}/instructions.h
+ COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/instructions.cc | grep "_impl(" | sed "s/{.*//" | sed "s/$/;/" >> ${CMAKE_CURRENT_BINARY_DIR}/instructions.h
+ COMMAND echo "#endif" >> ${CMAKE_CURRENT_BINARY_DIR}/instructions.h
+ # COMMAND chmod -w ${CMAKE_CURRENT_BINARY_DIR}/instructions.h
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/instructions.cc
+ VERBATIM
+)
+add_dependencies(ptxsim gen_instructions_h)
+
+# Create ptx_parser_decode.def using custom command
+add_custom_target(gen_ptx_parser_decode DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ptx_parser_decode.def)
+if(UNIX)
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ptx_parser_decode.def
+ COMMAND cat ${CMAKE_CURRENT_BINARY_DIR}/ptx.tab.h | grep "=" | sed "s/^[ ]\\+//" | sed -E "s/\\s+\\/\\*.+\\*\\///" | sed "s/[=,]//g" | sed "s/\\([_A-Z1-9]\\+\\)[ ]\\+\\([0-9]\\+\\)/\\1 \\1/" | sed "s/^/DEF(/" | sed "s/ /,\"/" | sed "s/$/\")/" | sed "/YYerror/d;/YYEOF/d;/YYEMPTY/d;/YYUNDEF/d;" > ${CMAKE_CURRENT_BINARY_DIR}/ptx_parser_decode.def
+ DEPENDS ${BISON_ptx_parser_OUTPUTS}
+ VERBATIM
+ )
+else()
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ptx_parser_decode.def
+ COMMAND cat ${CMAKE_CURRENT_BINARY_DIR}/ptx.tab.h | grep "=" | sed -E "s/^ +//" | sed -E "s/\\s+\\/\\*.+\\*\\///" | sed "s/[=,]//g" | sed -E "s/([_A-Z1-9]+).*/\\1 \\1/" | sed "s/^/DEF(/" | sed "s/ /,\"/" | sed "s/$/\")/" | sed "/YYerror/d;/YYEOF/d;/YYEMPTY/d;/YYUNDEF/d;" > ${CMAKE_CURRENT_BINARY_DIR}/ptx_parser_decode.def
+ DEPENDS ${BISON_ptx_parser_OUTPUTS}
+ VERBATIM
+ )
+endif()
+add_dependencies(ptxsim gen_ptx_parser_decode)
diff --git a/src/cuda-sim/Makefile b/src/cuda-sim/Makefile
index 85d1c8c..541cf8f 100644
--- a/src/cuda-sim/Makefile
+++ b/src/cuda-sim/Makefile
@@ -91,16 +91,16 @@ $(OUTPUT_DIR)/lex.ptxinfo_.o: $(OUTPUT_DIR)/lex.ptxinfo_.c $(OUTPUT_DIR)/ptxinfo
$(CPP) -c $(CXX_OPT) $(OUTPUT_DIR)/lex.ptxinfo_.c -o $(OUTPUT_DIR)/lex.ptxinfo_.o
$(OUTPUT_DIR)/ptx.tab.c: ptx.y
- bison --name-prefix=ptx_ -v -d ptx.y --file-prefix=$(OUTPUT_DIR)/ptx
+ bison --name-prefix=ptx_ -v -d ptx.y --file-prefix=$(OUTPUT_DIR)/ptx 2> /dev/null
$(OUTPUT_DIR)/ptxinfo.tab.c: ptxinfo.y
- bison --name-prefix=ptxinfo_ -v -d ptxinfo.y --file-prefix=$(OUTPUT_DIR)/ptxinfo
+ bison --name-prefix=ptxinfo_ -v -d ptxinfo.y --file-prefix=$(OUTPUT_DIR)/ptxinfo 2> /dev/null
$(OUTPUT_DIR)/lex.ptx_.c: ptx.l
- flex --outfile=$(OUTPUT_DIR)/lex.ptx_.c ptx.l
+ flex --outfile=$(OUTPUT_DIR)/lex.ptx_.c ptx.l 2> /dev/null
$(OUTPUT_DIR)/lex.ptxinfo_.c: ptxinfo.l
- flex --outfile=$(OUTPUT_DIR)/lex.ptxinfo_.c ptxinfo.l
+ flex --outfile=$(OUTPUT_DIR)/lex.ptxinfo_.c ptxinfo.l 2> /dev/null
clean:
rm -f *~ *.o *.gcda *.gcno *.gcov libgpgpu_ptx_sim.a \
@@ -129,9 +129,9 @@ $(OUTPUT_DIR)/instructions.h: instructions.cc
$(OUTPUT_DIR)/ptx_parser_decode.def: $(OUTPUT_DIR)/ptx.tab.c
ifeq ($(shell uname),Linux)
- cat $(OUTPUT_DIR)/ptx.tab.h | grep "=" | sed 's/^[ ]\+//' | sed 's/[=,]//g' | sed 's/\([_A-Z1-9]\+\)[ ]\+\([0-9]\+\)/\1 \1/' | sed 's/^/DEF(/' | sed 's/ /,"/' | sed 's/$$/")/' > $(OUTPUT_DIR)/ptx_parser_decode.def
+ cat $(OUTPUT_DIR)/ptx.tab.h | grep "=" | sed 's/^[ ]\+//' | sed -E 's/\s+\/\*.+\*\///' | sed 's/[=,]//g' | sed 's/\([_A-Z1-9]\+\)[ ]\+\([0-9]\+\)/\1 \1/' | sed 's/^/DEF(/' | sed 's/ /,"/' | sed 's/$$/")/' | sed '/YYerror/d;/YYEOF/d;/YYEMPTY/d;/YYUNDEF/d;'> $(OUTPUT_DIR)/ptx_parser_decode.def
else
- cat $(OUTPUT_DIR)/ptx.tab.h | grep "=" | sed -E 's/^ +//' | sed 's/[=,]//g' | sed -E 's/([_A-Z1-9]+).*/\1 \1/' | sed 's/^/DEF(/' | sed 's/ /,"/' | sed 's/$$/")/' > $(OUTPUT_DIR)/ptx_parser_decode.def
+ cat $(OUTPUT_DIR)/ptx.tab.h | grep "=" | sed -E 's/^ +//' | sed -E 's/\s+\/\*.+\*\///' | sed 's/[=,]//g' | sed -E 's/([_A-Z1-9]+).*/\1 \1/' | sed 's/^/DEF(/' | sed 's/ /,"/' | sed 's/$$/")/' | sed '/YYerror/d;/YYEOF/d;/YYEMPTY/d;/YYUNDEF/d;' > $(OUTPUT_DIR)/ptx_parser_decode.def
endif
$(OUTPUT_DIR)/instructions.o: $(OUTPUT_DIR)/instructions.h $(OUTPUT_DIR)/ptx.tab.c
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc
index f9e5db3..2fd90c0 100644
--- a/src/cuda-sim/cuda-sim.cc
+++ b/src/cuda-sim/cuda-sim.cc
@@ -1,17 +1,19 @@
// Copyright (c) 2009-2021, Tor M. Aamodt, Ali Bakhoda, Wilson W.L. Fung,
-// George L. Yuan, Jimmy Kwa, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// George L. Yuan, Jimmy Kwa, 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.
@@ -544,7 +546,7 @@ void gpgpu_t::gpu_memset(size_t dst_start_addr, int c, size_t count) {
void cuda_sim::ptx_print_insn(address_type pc, FILE *fp) {
std::map<unsigned, function_info *>::iterator f = g_pc_to_finfo.find(pc);
if (f == g_pc_to_finfo.end()) {
- fprintf(fp, "<no instruction at address 0x%x>", pc);
+ fprintf(fp, "<no instruction at address 0x%llx>", pc);
return;
}
function_info *finfo = f->second;
@@ -558,7 +560,7 @@ std::string cuda_sim::ptx_get_insn_str(address_type pc) {
#define STR_SIZE 255
char buff[STR_SIZE];
buff[STR_SIZE - 1] = '\0';
- snprintf(buff, STR_SIZE, "<no instruction at address 0x%x>", pc);
+ snprintf(buff, STR_SIZE, "<no instruction at address 0x%llx>", pc);
return std::string(buff);
}
function_info *finfo = f->second;
@@ -590,118 +592,118 @@ void ptx_instruction::set_fp_or_int_archop() {
}
}
-void ptx_instruction::set_mul_div_or_other_archop(){
- sp_op=OTHER_OP;
- if((m_opcode != MEMBAR_OP) && (m_opcode != SSY_OP) && (m_opcode != BRA_OP) && (m_opcode != BAR_OP) && (m_opcode != EXIT_OP) && (m_opcode != NOP_OP) && (m_opcode != RETP_OP) && (m_opcode != RET_OP) && (m_opcode != CALLP_OP) && (m_opcode != CALL_OP)){
- if(get_type() == F64_TYPE || get_type() == FF64_TYPE){
- switch(get_opcode()){
- case MUL_OP:
- case MAD_OP:
- case FMA_OP:
- sp_op=DP_MUL_OP;
- break;
- case DIV_OP:
- case REM_OP:
- sp_op=DP_DIV_OP;
- break;
- case RCP_OP:
- sp_op=DP_DIV_OP;
- break;
- case LG2_OP:
- sp_op=FP_LG_OP;
- break;
- case RSQRT_OP:
- case SQRT_OP:
- sp_op=FP_SQRT_OP;
- break;
- case SIN_OP:
- case COS_OP:
- sp_op=FP_SIN_OP;
- break;
- case EX2_OP:
- sp_op=FP_EXP_OP;
- break;
- case MMA_OP:
- sp_op=TENSOR__OP;
- break;
- case TEX_OP:
- sp_op=TEX__OP;
- break;
- default:
- if((op==DP_OP) || (op==ALU_OP))
- sp_op=DP___OP;
- break;
- }
+void ptx_instruction::set_mul_div_or_other_archop() {
+ sp_op = OTHER_OP;
+ if ((m_opcode != MEMBAR_OP) && (m_opcode != SSY_OP) && (m_opcode != BRA_OP) &&
+ (m_opcode != BAR_OP) && (m_opcode != EXIT_OP) && (m_opcode != NOP_OP) &&
+ (m_opcode != RETP_OP) && (m_opcode != RET_OP) && (m_opcode != CALLP_OP) &&
+ (m_opcode != CALL_OP)) {
+ if (get_type() == F64_TYPE || get_type() == FF64_TYPE) {
+ switch (get_opcode()) {
+ case MUL_OP:
+ case MAD_OP:
+ case FMA_OP:
+ sp_op = DP_MUL_OP;
+ break;
+ case DIV_OP:
+ case REM_OP:
+ sp_op = DP_DIV_OP;
+ break;
+ case RCP_OP:
+ sp_op = DP_DIV_OP;
+ break;
+ case LG2_OP:
+ sp_op = FP_LG_OP;
+ break;
+ case RSQRT_OP:
+ case SQRT_OP:
+ sp_op = FP_SQRT_OP;
+ break;
+ case SIN_OP:
+ case COS_OP:
+ sp_op = FP_SIN_OP;
+ break;
+ case EX2_OP:
+ sp_op = FP_EXP_OP;
+ break;
+ case MMA_OP:
+ sp_op = TENSOR__OP;
+ break;
+ case TEX_OP:
+ sp_op = TEX__OP;
+ break;
+ default:
+ if ((op == DP_OP) || (op == ALU_OP)) sp_op = DP___OP;
+ break;
}
- else if(get_type()==F16_TYPE || get_type()==F32_TYPE){
- switch(get_opcode()){
- case MUL_OP:
- case MAD_OP:
- case FMA_OP:
- sp_op=FP_MUL_OP;
- break;
- case DIV_OP:
- case REM_OP:
- sp_op=FP_DIV_OP;
- break;
- case RCP_OP:
- sp_op=FP_DIV_OP;
- break;
- case LG2_OP:
- sp_op=FP_LG_OP;
- break;
- case RSQRT_OP:
- case SQRT_OP:
- sp_op=FP_SQRT_OP;
- break;
- case SIN_OP:
- case COS_OP:
- sp_op=FP_SIN_OP;
- break;
- case EX2_OP:
- sp_op=FP_EXP_OP;
- break;
- case MMA_OP:
- sp_op=TENSOR__OP;
- break;
- case TEX_OP:
- sp_op=TEX__OP;
- break;
- default:
- if((op==SP_OP) || (op==ALU_OP))
- sp_op=FP__OP;
- break;
- }
- }else {
- switch(get_opcode()){
- case MUL24_OP:
- case MAD24_OP:
- sp_op=INT_MUL24_OP;
- break;
- case MUL_OP:
- case MAD_OP:
- case FMA_OP:
- if(get_type()==U32_TYPE || get_type()==S32_TYPE || get_type()==B32_TYPE)
- sp_op=INT_MUL32_OP;
- else
- sp_op=INT_MUL_OP;
- break;
- case DIV_OP:
- case REM_OP:
- sp_op=INT_DIV_OP;
- break;
- case MMA_OP:
- sp_op=TENSOR__OP;
- break;
- case TEX_OP:
- sp_op=TEX__OP;
- break;
- default:
- if((op==INTP_OP) || (op==ALU_OP))
- sp_op=INT__OP;
- break;
- }
+ } else if (get_type() == F16_TYPE || get_type() == F32_TYPE) {
+ switch (get_opcode()) {
+ case MUL_OP:
+ case MAD_OP:
+ case FMA_OP:
+ sp_op = FP_MUL_OP;
+ break;
+ case DIV_OP:
+ case REM_OP:
+ sp_op = FP_DIV_OP;
+ break;
+ case RCP_OP:
+ sp_op = FP_DIV_OP;
+ break;
+ case LG2_OP:
+ sp_op = FP_LG_OP;
+ break;
+ case RSQRT_OP:
+ case SQRT_OP:
+ sp_op = FP_SQRT_OP;
+ break;
+ case SIN_OP:
+ case COS_OP:
+ sp_op = FP_SIN_OP;
+ break;
+ case EX2_OP:
+ sp_op = FP_EXP_OP;
+ break;
+ case MMA_OP:
+ sp_op = TENSOR__OP;
+ break;
+ case TEX_OP:
+ sp_op = TEX__OP;
+ break;
+ default:
+ if ((op == SP_OP) || (op == ALU_OP)) sp_op = FP__OP;
+ break;
+ }
+ } else {
+ switch (get_opcode()) {
+ case MUL24_OP:
+ case MAD24_OP:
+ sp_op = INT_MUL24_OP;
+ break;
+ case MUL_OP:
+ case MAD_OP:
+ case FMA_OP:
+ if (get_type() == U32_TYPE || get_type() == S32_TYPE ||
+ get_type() == B32_TYPE)
+ sp_op = INT_MUL32_OP;
+ else
+ sp_op = INT_MUL_OP;
+ break;
+ case DIV_OP:
+ case REM_OP:
+ sp_op = INT_DIV_OP;
+ break;
+ case MMA_OP:
+ sp_op = TENSOR__OP;
+ break;
+ case TEX_OP:
+ sp_op = TEX__OP;
+ break;
+ default:
+ if ((op == INTP_OP) || (op == ALU_OP)) sp_op = INT__OP;
+ break;
}
+ }
}
}
@@ -959,14 +961,16 @@ void ptx_instruction::set_opcode_and_latency() {
break;
}
break;
- case MUL24_OP: //MUL24 is performed on mul32 units (with additional instructions for bitmasking) on devices with compute capability >1.x
- latency = int_latency[2]+1;
- initiation_interval = int_init[2]+1;
+ case MUL24_OP: // MUL24 is performed on mul32 units (with additional
+ // instructions for bitmasking) on devices with compute
+ // capability >1.x
+ latency = int_latency[2] + 1;
+ initiation_interval = int_init[2] + 1;
op = INTP_OP;
break;
case MAD24_OP:
- latency = int_latency[3]+1;
- initiation_interval = int_init[3]+1;
+ latency = int_latency[3] + 1;
+ initiation_interval = int_init[3] + 1;
op = INTP_OP;
break;
case DIV_OP:
@@ -1301,7 +1305,12 @@ void function_info::add_param_name_type_size(unsigned index, std::string name,
void function_info::add_param_data(unsigned argn,
struct gpgpu_ptx_sim_arg *args) {
const void *data = args->m_start;
-
+ if (g_debug_execution >= 3) {
+ if (args->m_nbytes == 4)
+ printf("ADD_PARAM_DATA %d\n", *((uint32_t *)data));
+ else
+ printf("ADD_PARAM_DATA %p\n", *((void **)data));
+ }
bool scratchpad_memory_param =
false; // Is this parameter in CUDA shared memory or OpenCL local memory
@@ -1371,7 +1380,7 @@ void function_info::add_param_data(unsigned argn,
unsigned num_bits = 8 * args->m_nbytes;
printf(
"GPGPU-Sim PTX: deferred allocation of shared region for \"%s\" from "
- "0x%x to 0x%x (shared memory space)\n",
+ "0x%llx to 0x%llx (shared memory space)\n",
p->name().c_str(), m_symtab->get_shared_next(),
m_symtab->get_shared_next() + num_bits / 8);
fflush(stdout);
@@ -1502,7 +1511,7 @@ void function_info::list_param(FILE *fout) const {
std::string name = p.get_name();
symbol *param = m_symtab->lookup(name.c_str());
addr_t param_addr = param->get_address();
- fprintf(fout, "%s: %#08x\n", name.c_str(), param_addr);
+ fprintf(fout, "%s: %#08llx\n", name.c_str(), param_addr);
}
fflush(fout);
}
@@ -1530,9 +1539,13 @@ void function_info::ptx_jit_config(
std::string filename_c(filename + "_c");
snprintf(buff, 1024, "c++filt %s > %s", get_name().c_str(),
filename_c.c_str());
- assert(system(buff) != NULL);
+ assert(system(buff) != 0);
FILE *fp = fopen(filename_c.c_str(), "r");
- fgets(buff, 1024, fp);
+ char *ptr = fgets(buff, 1024, fp);
+ if (ptr == NULL) {
+ printf("can't read file %s \n", filename_c.c_str());
+ assert(0);
+ }
fclose(fp);
std::string fn(buff);
size_t pos1, pos2;
@@ -1738,6 +1751,17 @@ static unsigned get_tex_datasize(const ptx_instruction *pI,
ptx_thread_info *thread) {
const operand_info &src1 = pI->src1(); // the name of the texture
std::string texname = src1.name();
+ // If indirect access, use register's value as address
+ // to find the symbol
+ if (src1.is_reg()) {
+ const operand_info &dst = pI->dst();
+ ptx_reg_t src1_data =
+ thread->get_operand_value(src1, dst, pI->get_type(), thread, 1);
+ addr_t sym_addr = src1_data.u64;
+ symbol *texRef = thread->get_symbol_table()->lookup_by_addr(sym_addr);
+ assert(texRef != NULL);
+ texname = texRef->name();
+ }
/*
For programs with many streams, textures can be bound and unbound
@@ -1876,7 +1900,7 @@ void ptx_thread_info::ptx_exec_inst(warp_inst_t &inst, unsigned lane_id) {
dim3 tid = get_tid();
printf(
"%u [thd=%u][i=%u] : ctaid=(%u,%u,%u) tid=(%u,%u,%u) icount=%u "
- "[pc=%u] (%s:%u - %s) [0x%llx]\n",
+ "[pc=%llu] (%s:%u - %s) [0x%llx]\n",
m_gpu->gpgpu_ctx->func_sim->g_ptx_sim_num_insn, get_uid(), pI->uid(),
ctaid.x, ctaid.y, ctaid.z, tid.x, tid.y, tid.z, get_icount(), pc,
pI->source_file(), pI->source_line(), pI->get_source(),
@@ -2277,15 +2301,24 @@ void cuda_sim::gpgpu_ptx_sim_memcpy_symbol(const char *hostVar, const void *src,
sym_name = g->second;
mem_region = global_space;
}
- if (g_globals.find(hostVar) != g_globals.end()) {
- found_sym = true;
- sym_name = hostVar;
- mem_region = global_space;
- }
- if (g_constants.find(hostVar) != g_constants.end()) {
- found_sym = true;
- sym_name = hostVar;
- mem_region = const_space;
+
+ // Weili: Only attempt to find symbol as it is a string
+ // if we could not find it in previously registered variable.
+ // This will avoid constructing std::string() from hostVar address
+ // where it is not a string as
+ // Use of a string naming a variable as the symbol parameter was deprecated in
+ // CUDA 4.1 and removed in CUDA 5.0.
+ if (!found_sym) {
+ if (g_globals.find(hostVar) != g_globals.end()) {
+ found_sym = true;
+ sym_name = hostVar;
+ mem_region = global_space;
+ }
+ if (g_constants.find(hostVar) != g_constants.end()) {
+ found_sym = true;
+ sym_name = hostVar;
+ mem_region = const_space;
+ }
}
if (!found_sym) {
@@ -2375,7 +2408,7 @@ void cuda_sim::read_sim_environment_variables() {
"%s\n",
dbg_pc);
fflush(stdout);
- sscanf(dbg_pc, "%d", &g_debug_pc);
+ sscanf(dbg_pc, "%llu", &g_debug_pc);
}
#if CUDART_VERSION > 1010
diff --git a/src/cuda-sim/cuda_device_runtime.cc b/src/cuda-sim/cuda_device_runtime.cc
index 4a99c1c..8ed90bc 100644
--- a/src/cuda-sim/cuda_device_runtime.cc
+++ b/src/cuda-sim/cuda_device_runtime.cc
@@ -36,7 +36,7 @@ void cuda_device_runtime::gpgpusim_cuda_getParameterBufferV2(
unsigned n_args = target_func->num_args();
assert(n_args == 4);
- function_info *child_kernel_entry;
+ function_info *child_kernel_entry = NULL;
struct dim3 grid_dim, block_dim;
unsigned int shared_mem;
@@ -258,7 +258,7 @@ void cuda_device_runtime::gpgpusim_cuda_streamCreateWithFlags(
assert(n_args == 2);
size_t generic_pStream_addr;
- addr_t pStream_addr;
+ addr_t pStream_addr = 0;
unsigned int flags;
for (unsigned arg = 0; arg < n_args; arg++) {
const operand_info &actual_param_op =
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc
index 44afbe5..843bf0b 100644
--- a/src/cuda-sim/instructions.cc
+++ b/src/cuda-sim/instructions.cc
@@ -1,17 +1,19 @@
// Copyright (c) 2009-2021, Tor M. Aamodt, Wilson W.L. Fung, Ali Bakhoda,
-// Jimmy Kwa, George L. Yuan, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// Jimmy Kwa, 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.
@@ -1947,7 +1949,7 @@ void mma_impl(const ptx_instruction *pI, core_t *core, warp_inst_t inst) {
hex_val = (v[k / 2].s64 & 0xffff);
else
hex_val = ((v[k / 2].s64 & 0xffff0000) >> 16);
- nw_v[k].f16 = *((half *)&hex_val);
+ nw_v[k].f16 = *(reinterpret_cast<half *>(hex_val));
}
}
if (!((operand_num == 3) && (type2 == F32_TYPE))) {
@@ -3979,7 +3981,7 @@ void mad_def(const ptx_instruction *pI, ptx_thread_info *thread,
fesetround(FE_TOWARDZERO);
break;
default:
- //assert(0);
+ // assert(0);
break;
}
d.f32 = a.f32 * b.f32 + c.f32;
@@ -4325,7 +4327,7 @@ void mul_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
case S64_TYPE:
t.s64 = a.s64 * b.s64;
assert(!pI->is_wide());
- //assert(!pI->is_hi());
+ // assert(!pI->is_hi());
d.s64 = t.s64;
break;
case U16_TYPE:
@@ -5439,6 +5441,38 @@ void shfl_impl(const ptx_instruction *pI, core_t *core, warp_inst_t inst) {
}
}
+void shf_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
+ ptx_reg_t a, b, c, d;
+ const operand_info &dst = pI->dst();
+ const operand_info &src1 = pI->src1();
+ const operand_info &src2 = pI->src2();
+ const operand_info &src3 = pI->src3();
+
+ // Only b32 is allowed
+ unsigned i_type = pI->get_type();
+ a = thread->get_operand_value(src1, dst, i_type, thread, 1);
+ b = thread->get_operand_value(src2, dst, i_type, thread, 1);
+ c = thread->get_operand_value(src3, dst, i_type, thread, 1);
+
+ if (i_type != B32_TYPE)
+ printf("Only the b32 data_type is allowed per the ISA\n");
+
+ unsigned clamp_mode = pI->clamp_mode();
+ unsigned n = c.u32 & 0x1f;
+ if (clamp_mode) {
+ if (c.u32 < 32)
+ n = c;
+ else
+ n = 32;
+ }
+ if (pI->left_mode())
+ d.u32 = (b.u32 << n) | (a.u32 >> (32 - n));
+ else
+ d.u32 = (b.u32 << (32 - n)) | (a.u32 >> n);
+
+ thread->set_operand_value(dst, d, i_type, thread, pI);
+}
+
void shl_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
ptx_reg_t a, b, d;
const operand_info &dst = pI->dst();
@@ -6021,6 +6055,17 @@ void tex_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
// to be fetched
std::string texname = src1.name();
+ // If indirect access, use register's value as address
+ // to find the symbol
+ if (src1.is_reg()) {
+ ptx_reg_t src1_data =
+ thread->get_operand_value(src1, dst, pI->get_type(), thread, 1);
+ addr_t sym_addr = src1_data.u64;
+ symbol *texRef = thread->get_symbol_table()->lookup_by_addr(sym_addr);
+ assert(texRef != NULL);
+ texname = texRef->name();
+ }
+
unsigned to_type = pI->get_type();
unsigned c_type = pI->get_type2();
fflush(stdout);
diff --git a/src/cuda-sim/memory.cc b/src/cuda-sim/memory.cc
index 1323837..036bada 100644
--- a/src/cuda-sim/memory.cc
+++ b/src/cuda-sim/memory.cc
@@ -109,11 +109,11 @@ void memory_space_impl<BSIZE>::read_single_block(mem_addr_t blk_idx,
if ((addr + length) > (blk_idx + 1) * BSIZE) {
printf(
"GPGPU-Sim PTX: ERROR * access to memory \'%s\' is unaligned : "
- "addr=0x%x, length=%zu\n",
+ "addr=0x%llx, length=%zu\n",
m_name.c_str(), addr, length);
printf(
- "GPGPU-Sim PTX: (addr+length)=0x%lx > 0x%x=(index+1)*BSIZE, "
- "index=0x%x, BSIZE=0x%x\n",
+ "GPGPU-Sim PTX: (addr+length)=0x%llx > 0x%llx=(index+1)*BSIZE, "
+ "index=0x%llx, BSIZE=0x%x\n",
(addr + length), (blk_idx + 1) * BSIZE, blk_idx, BSIZE);
throw 1;
}
@@ -169,7 +169,7 @@ void memory_space_impl<BSIZE>::print(const char *format, FILE *fout) const {
typename map_t::const_iterator i_page;
for (i_page = m_data.begin(); i_page != m_data.end(); ++i_page) {
- fprintf(fout, "%s %08x:", m_name.c_str(), i_page->first);
+ fprintf(fout, "%s %08llx:", m_name.c_str(), i_page->first);
i_page->second.print(format, fout);
}
}
diff --git a/src/cuda-sim/opcodes.def b/src/cuda-sim/opcodes.def
index f5bf156..83a23ea 100644
--- a/src/cuda-sim/opcodes.def
+++ b/src/cuda-sim/opcodes.def
@@ -103,6 +103,7 @@ OP_DEF(SELP_OP,selp_impl,"selp",1,1)
OP_DEF(SETP_OP,setp_impl,"setp",1,1)
OP_DEF(SET_OP,set_impl,"set",1,1)
OP_W_DEF(SHFL_OP,shfl_impl,"shfl",1,10)
+OP_DEF(SHF_OP,shf_impl,"shf",1,1)
OP_DEF(SHL_OP,shl_impl,"shl",1,1)
OP_DEF(SHR_OP,shr_impl,"shr",1,1)
OP_DEF(SIN_OP,sin_impl,"sin",1,4)
diff --git a/src/cuda-sim/ptx.l b/src/cuda-sim/ptx.l
index 7706f0b..0810ef6 100644
--- a/src/cuda-sim/ptx.l
+++ b/src/cuda-sim/ptx.l
@@ -1,6 +1,7 @@
/*
-Copyright (c) 2009-2021, Tor M. Aamodt, Vijay Kandiah, Nikos Hardavellas
-The University of British Columbia, Northwestern University
+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:
@@ -133,6 +134,7 @@ selp TC; yylval->int_value = SELP_OP; return OPCODE;
setp TC; yylval->int_value = SETP_OP; return OPCODE;
set TC; yylval->int_value = SET_OP; return OPCODE;
shfl TC; yylval->int_value = SHFL_OP; return OPCODE;
+shf TC; yylval->int_value = SHF_OP; return OPCODE;
shl TC; yylval->int_value = SHL_OP; return OPCODE;
shr TC; yylval->int_value = SHR_OP; return OPCODE;
sin TC; yylval->int_value = SIN_OP; return OPCODE;
@@ -316,6 +318,9 @@ breakaddr TC; yylval->int_value = BREAKADDR_OP; return OPCODE;
\.sat TC; return SAT_OPTION;
+\.l TC; return LEFT_OPTION;
+\.r TC; return RIGHT_OPTION;
+
\.eq TC; return EQ_OPTION;
\.ne TC; return NE_OPTION;
\.lt TC; return LT_OPTION;
@@ -353,6 +358,8 @@ breakaddr TC; yylval->int_value = BREAKADDR_OP; return OPCODE;
\.arrive TC; return ARRIVE_OPTION;
\.red TC; return RED_OPTION;
+\.clamp TC; return CLAMP_OPTION;
+\.wrap TC; return WRAP_OPTION;
\.approx TC; return APPROX_OPTION;
\.full TC; return FULL_OPTION;
@@ -487,4 +494,4 @@ int ptx_error( yyscan_t yyscanner, ptx_recognizer* recognizer, const char *s )
fflush(stdout);
//exit(1);
return 0;
-} \ No newline at end of file
+}
diff --git a/src/cuda-sim/ptx.y b/src/cuda-sim/ptx.y
index b38f783..61183e8 100644
--- a/src/cuda-sim/ptx.y
+++ b/src/cuda-sim/ptx.y
@@ -220,6 +220,10 @@ class ptx_recognizer;
%token PRMT_RC16_MODE;
%token PRMT_ECL_MODE;
%token PRMT_ECR_MODE;
+%token WRAP_OPTION;
+%token CLAMP_OPTION;
+%token LEFT_OPTION;
+%token RIGHT_OPTION;
%type <int_value> function_decl_header
%type <ptr_value> function_decl
@@ -507,6 +511,10 @@ option: type_spec
| DOWN_OPTION { recognizer->add_option(DOWN_OPTION); }
| BFLY_OPTION { recognizer->add_option(BFLY_OPTION); }
| IDX_OPTION { recognizer->add_option(IDX_OPTION); }
+ | WRAP_OPTION { recognizer->add_option(WRAP_OPTION); }
+ | CLAMP_OPTION { recognizer->add_option(CLAMP_OPTION); }
+ | LEFT_OPTION { recognizer->add_option(LEFT_OPTION); }
+ | RIGHT_OPTION { recognizer->add_option(RIGHT_OPTION); }
;
atomic_operation_spec: ATOMIC_AND { recognizer->add_option(ATOMIC_AND); }
diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc
index 2edc1ed..4e500cc 100644
--- a/src/cuda-sim/ptx_ir.cc
+++ b/src/cuda-sim/ptx_ir.cc
@@ -1,17 +1,19 @@
// Copyright (c) 2009-2021, Tor M. Aamodt, Ali Bakhoda, Wilson W.L. Fung,
-// George L. Yuan, Vijay Kandiah, Nikos Hardavellas
-// The University of British Columbia, Northwestern University
-// All rights reserved.
+// 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.
@@ -137,6 +139,22 @@ symbol *symbol_table::lookup(const char *identifier) {
return NULL;
}
+symbol *symbol_table::lookup_by_addr(addr_t addr) {
+ for (auto it = m_symbols.begin(); it != m_symbols.end(); ++it) {
+ symbol *sym = it->second;
+
+ // check if symbol has the addr to be found
+ if ((!sym->is_reg()) && (sym->has_valid_address()) &&
+ (sym->get_address() == addr)) {
+ return sym;
+ }
+ }
+ if (m_parent) {
+ return m_parent->lookup_by_addr(addr);
+ }
+ return NULL;
+}
+
symbol *symbol_table::add_variable(const char *identifier,
const type_info *type, unsigned size,
const char *filename, unsigned line) {
@@ -1225,6 +1243,8 @@ ptx_instruction::ptx_instruction(
m_rounding_mode = RN_OPTION;
m_compare_op = -1;
m_saturation_mode = 0;
+ m_clamp_mode = 0;
+ m_left_mode = 0;
m_geom_spec = 0;
m_vector_spec = 0;
m_atomic_spec = 0;
@@ -1291,6 +1311,18 @@ ptx_instruction::ptx_instruction(
case SAT_OPTION:
m_saturation_mode = 1;
break;
+ case WRAP_OPTION:
+ m_clamp_mode = 0;
+ break;
+ case CLAMP_OPTION:
+ m_clamp_mode = 1;
+ break;
+ case LEFT_OPTION:
+ m_left_mode = 1;
+ break;
+ case RIGHT_OPTION:
+ m_left_mode = 0;
+ break;
case RNI_OPTION:
case RZI_OPTION:
case RMI_OPTION:
@@ -1385,7 +1417,7 @@ ptx_instruction::ptx_instruction(
case CS_OPTION:
case LU_OPTION:
case CV_OPTION:
- case WB_OPTION:
+ case WB_OPTION:
case WT_OPTION:
m_cache_option = last_ptx_inst_option;
break;
@@ -1468,8 +1500,8 @@ std::string ptx_instruction::to_string() const {
char buf[STR_SIZE];
unsigned used_bytes = 0;
if (!is_label()) {
- used_bytes +=
- snprintf(buf + used_bytes, STR_SIZE - used_bytes, " PC=0x%03x ", m_PC);
+ used_bytes += snprintf(buf + used_bytes, STR_SIZE - used_bytes,
+ " PC=0x%03llx ", m_PC);
} else {
used_bytes +=
snprintf(buf + used_bytes, STR_SIZE - used_bytes, " ");
diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h
index 8251759..b08a692 100644
--- a/src/cuda-sim/ptx_ir.h
+++ b/src/cuda-sim/ptx_ir.h
@@ -205,6 +205,7 @@ class symbol {
const std::string &name() const { return m_name; }
const std::string &decl_location() const { return m_decl_location; }
const type_info *type() const { return m_type; }
+ bool has_valid_address() const { return m_address_valid; }
addr_t get_address() const {
assert(m_is_label ||
!m_type->get_key().is_reg()); // todo : other assertions
@@ -310,6 +311,7 @@ class symbol_table {
void set_ptx_version(float ver, unsigned ext);
void set_sm_target(const char *target, const char *ext, const char *ext2);
symbol *lookup(const char *identifier);
+ symbol *lookup_by_addr(addr_t addr);
std::string get_scope_name() const { return m_scope_name; }
symbol *add_variable(const char *identifier, const type_info *type,
unsigned size, const char *filename, unsigned line);
@@ -1085,6 +1087,8 @@ class ptx_instruction : public warp_inst_t {
unsigned cache_option() const { return m_cache_option; }
unsigned rounding_mode() const { return m_rounding_mode; }
unsigned saturation_mode() const { return m_saturation_mode; }
+ unsigned clamp_mode() const { return m_clamp_mode; }
+ unsigned left_mode() const { return m_left_mode; }
unsigned dimension() const { return m_geom_spec; }
unsigned barrier_op() const { return m_barrier_op; }
unsigned shfl_op() const { return m_shfl_op; }
@@ -1159,6 +1163,8 @@ class ptx_instruction : public warp_inst_t {
unsigned m_rounding_mode;
unsigned m_compare_op;
unsigned m_saturation_mode;
+ unsigned m_clamp_mode;
+ unsigned m_left_mode;
unsigned m_barrier_op;
unsigned m_shfl_op;
unsigned m_prmt_op;
@@ -1248,6 +1254,7 @@ class function_info {
const ptx_version &get_ptx_version() const {
return m_symtab->get_ptx_version();
}
+ virtual ~function_info() {}
unsigned get_sm_target() const { return m_symtab->get_sm_target(); }
bool is_extern() const { return m_extern; }
void set_name(const char *name) { m_name = name; }
diff --git a/src/cuda-sim/ptx_loader.cc b/src/cuda-sim/ptx_loader.cc
index 4e91763..df35498 100644
--- a/src/cuda-sim/ptx_loader.cc
+++ b/src/cuda-sim/ptx_loader.cc
@@ -95,7 +95,7 @@ void gpgpu_context::print_ptx_file(const char *p, unsigned source_num,
const ptx_instruction *pI = ptx_parser->ptx_instruction_lookup(filename, n);
char pc[64];
if (pI && pI->get_PC())
- snprintf(pc, 64, "%4u", pI->get_PC());
+ snprintf(pc, 64, "%4llu", pI->get_PC());
else
snprintf(pc, 64, " ");
printf(" _%u.ptx %4u (pc=%s): %s\n", source_num, n, pc, t);
@@ -240,7 +240,7 @@ void fix_duplicate_errors(char fname2[1024]) {
unsigned oldlinenum = 1;
unsigned linenum;
char *startptr = ptxdata;
- char *funcptr;
+ char *funcptr = NULL;
char *tempptr = ptxdata - 1;
char *lineptr = ptxdata - 1;
@@ -320,7 +320,7 @@ void fix_duplicate_errors(char fname2[1024]) {
// we need the application name here too.
char *get_app_binary_name() {
char exe_path[1025];
- char *self_exe_path;
+ char *self_exe_path = NULL;
#ifdef __APPLE__
// AMRUTH: get apple device and check the result.
printf("WARNING: not tested for Apple-mac devices \n");
diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc
index 86a33c2..a80eeae 100644
--- a/src/cuda-sim/ptx_parser.cc
+++ b/src/cuda-sim/ptx_parser.cc
@@ -206,7 +206,7 @@ void ptx_recognizer::end_function() {
gpgpu_ptx_assemble(g_func_info->get_name(), g_func_info);
g_current_symbol_table = g_global_symbol_table;
- PTX_PARSE_DPRINTF("function %s, PC = %d\n", g_func_info->get_name().c_str(),
+ PTX_PARSE_DPRINTF("function %s, PC = %llu\n", g_func_info->get_name().c_str(),
g_func_info->get_start_PC());
}
@@ -486,7 +486,7 @@ void ptx_recognizer::add_identifier(const char *identifier, int array_dim,
case param_space_local:
printf(
"GPGPU-Sim PTX: allocating stack frame region for .param \"%s\" from "
- "0x%x to 0x%lx\n",
+ "0x%llx to 0x%llx\n",
identifier, g_current_symbol_table->get_local_next(),
g_current_symbol_table->get_local_next() + num_bits / 8);
fflush(stdout);
@@ -521,7 +521,7 @@ void ptx_recognizer::add_constptr(const char *identifier1,
unsigned addr = s2->get_address();
- printf("GPGPU-Sim PTX: moving \"%s\" from 0x%x to 0x%x (%s+%x)\n",
+ printf("GPGPU-Sim PTX: moving \"%s\" from 0x%llx to 0x%x (%s+%d)\n",
identifier1, s1->get_address(), addr + offset, identifier2, offset);
s1->set_address(addr + offset);
diff --git a/src/cuda-sim/ptx_sim.cc b/src/cuda-sim/ptx_sim.cc
index dc801f8..2a548ee 100644
--- a/src/cuda-sim/ptx_sim.cc
+++ b/src/cuda-sim/ptx_sim.cc
@@ -369,7 +369,8 @@ static void print_reg(FILE *fp, std::string name, ptx_reg_t value,
fprintf(fp, ".u64 %llu [0x%llx]\n", value.u64, value.u64);
break;
case F16_TYPE:
- fprintf(fp, ".f16 %f [0x%04x]\n", value.f16, (unsigned)value.u16);
+ fprintf(fp, ".f16 %f [0x%04x]\n", static_cast<float>(value.f16),
+ (unsigned)value.u16);
break;
case F32_TYPE:
fprintf(fp, ".f32 %.15lf [0x%08x]\n", value.f32, value.u32);
diff --git a/src/cuda-sim/ptx_sim.h b/src/cuda-sim/ptx_sim.h
index f0c26ef..8eec922 100644
--- a/src/cuda-sim/ptx_sim.h
+++ b/src/cuda-sim/ptx_sim.h
@@ -459,6 +459,9 @@ class ptx_thread_info {
// Jin: get corresponding kernel grid for CDP purpose
kernel_info_t &get_kernel() { return m_kernel; }
+ // Weili: access symbol_table
+ symbol_table *get_symbol_table() { return m_symbol_table; }
+
public:
addr_t m_last_effective_address;
bool m_branch_taken;
diff --git a/src/debug.cc b/src/debug.cc
index 29506bd..8cc5e1f 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -124,7 +124,7 @@ void gpgpu_sim::gpgpu_debug() {
fflush(stdout);
char line[1024];
- fgets(line, 1024, stdin);
+ char *ptr = fgets(line, 1024, stdin);
char *tok = strtok(line, " \t\n");
if (!strcmp(tok, "dp")) {
@@ -136,7 +136,11 @@ void gpgpu_sim::gpgpu_debug() {
fflush(stdout);
} else if (!strcmp(tok, "q") || !strcmp(tok, "quit")) {
printf("\nreally quit GPGPU-Sim (y/n)?\n");
- fgets(line, 1024, stdin);
+ ptr = fgets(line, 1024, stdin);
+ if (ptr == NULL) {
+ printf("can't read input\n");
+ exit(0);
+ }
tok = strtok(line, " \t\n");
if (!strcmp(tok, "y")) {
exit(0);
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");
}
diff --git a/src/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc
index f4287d8..e2b711e 100644
--- a/src/gpgpusim_entrypoint.cc
+++ b/src/gpgpusim_entrypoint.cc
@@ -43,6 +43,21 @@
static int sg_argc = 3;
static const char *sg_argv[] = {"", "-config", "gpgpusim.config"};
+// Help funcs to avoid multiple '->' for SST
+GPGPUsim_ctx *GPGPUsim_ctx_ptr() { return GPGPU_Context()->the_gpgpusim; }
+
+class sst_gpgpu_sim *g_the_gpu() {
+ return static_cast<sst_gpgpu_sim *>(GPGPUsim_ctx_ptr()->g_the_gpu);
+}
+
+class stream_manager *g_stream_manager() {
+ return GPGPUsim_ctx_ptr()->g_stream_manager;
+}
+
+// SST callback
+extern void SST_callback_cudaThreadSynchronize_done();
+__attribute__((weak)) void SST_callback_cudaThreadSynchronize_done() {}
+
void *gpgpu_sim_thread_sequential(void *ctx_ptr) {
gpgpu_context *ctx = (gpgpu_context *)ctx_ptr;
// at most one kernel running at a time
@@ -57,7 +72,8 @@ void *gpgpu_sim_thread_sequential(void *ctx_ptr) {
ctx->the_gpgpusim->g_the_gpu->cycle();
ctx->the_gpgpusim->g_the_gpu->deadlock_check();
}
- ctx->the_gpgpusim->g_the_gpu->print_stats();
+ ctx->the_gpgpusim->g_the_gpu->print_stats(
+ ctx->the_gpgpusim->g_the_gpu->last_streamID);
ctx->the_gpgpusim->g_the_gpu->update_stats();
ctx->print_simulation_time();
}
@@ -144,7 +160,8 @@ void *gpgpu_sim_thread_concurrent(void *ctx_ptr) {
fflush(stdout);
}
if (sim_cycles) {
- ctx->the_gpgpusim->g_the_gpu->print_stats();
+ ctx->the_gpgpusim->g_the_gpu->print_stats(
+ ctx->the_gpgpusim->g_the_gpu->last_streamID);
ctx->the_gpgpusim->g_the_gpu->update_stats();
ctx->print_simulation_time();
}
@@ -167,6 +184,75 @@ void *gpgpu_sim_thread_concurrent(void *ctx_ptr) {
return NULL;
}
+bool sst_sim_cycles = false;
+
+bool SST_Cycle() {
+ // Check if Synchronize is done when SST previously requested
+ // cudaThreadSynchronize
+ if (GPGPU_Context()->requested_synchronize &&
+ ((g_stream_manager()->empty() && !GPGPUsim_ctx_ptr()->g_sim_active) ||
+ GPGPUsim_ctx_ptr()->g_sim_done)) {
+ SST_callback_cudaThreadSynchronize_done();
+ GPGPU_Context()->requested_synchronize = false;
+ }
+
+ if (g_stream_manager()->empty_protected() &&
+ !GPGPUsim_ctx_ptr()->g_sim_done && !g_the_gpu()->active()) {
+ GPGPUsim_ctx_ptr()->g_sim_active = false;
+ // printf("stream is empty %d \n", g_stream_manager->empty());
+ return false;
+ }
+
+ if (g_stream_manager()->operation(&sst_sim_cycles) &&
+ !g_the_gpu()->active()) {
+ if (sst_sim_cycles) {
+ sst_sim_cycles = false;
+ }
+ return false;
+ }
+
+ // printf("GPGPU-Sim: Give GPU Cycle\n");
+ GPGPUsim_ctx_ptr()->g_sim_active = true;
+
+ // functional simulation
+ if (g_the_gpu()->is_functional_sim()) {
+ kernel_info_t *kernel = g_the_gpu()->get_functional_kernel();
+ assert(kernel);
+ GPGPUsim_ctx_ptr()->gpgpu_ctx->func_sim->gpgpu_cuda_ptx_sim_main_func(
+ *kernel);
+ g_the_gpu()->finish_functional_sim(kernel);
+ }
+
+ // performance simulation
+ if (g_the_gpu()->active()) {
+ g_the_gpu()->SST_cycle();
+ sst_sim_cycles = true;
+ g_the_gpu()->deadlock_check();
+ } else {
+ if (g_the_gpu()->cycle_insn_cta_max_hit()) {
+ g_stream_manager()->stop_all_running_kernels();
+ GPGPUsim_ctx_ptr()->g_sim_done = true;
+ GPGPUsim_ctx_ptr()->g_sim_active = false;
+ GPGPUsim_ctx_ptr()->break_limit = true;
+ }
+ }
+
+ if (!g_the_gpu()->active()) {
+ g_the_gpu()->print_stats(GPGPUsim_ctx_ptr()->g_the_gpu->last_streamID);
+ g_the_gpu()->update_stats();
+ GPGPU_Context()->print_simulation_time();
+ }
+
+ if (GPGPUsim_ctx_ptr()->break_limit) {
+ printf(
+ "GPGPU-Sim: ** break due to reaching the maximum cycles (or "
+ "instructions) **\n");
+ return true;
+ }
+
+ return false;
+}
+
void gpgpu_context::synchronize() {
printf("GPGPU-Sim: synchronize waiting for inactive GPU simulation\n");
the_gpgpusim->g_stream_manager->print(stdout);
@@ -185,6 +271,27 @@ void gpgpu_context::synchronize() {
// sem_post(&g_sim_signal_start);
}
+bool gpgpu_context::synchronize_check() {
+ // printf("GPGPU-Sim: synchronize checking for inactive GPU simulation\n");
+ requested_synchronize = true;
+ the_gpgpusim->g_stream_manager->print(stdout);
+ fflush(stdout);
+ // sem_wait(&g_sim_signal_finish);
+ bool done = false;
+ pthread_mutex_lock(&(the_gpgpusim->g_sim_lock));
+ done = (the_gpgpusim->g_stream_manager->empty() &&
+ !the_gpgpusim->g_sim_active) ||
+ the_gpgpusim->g_sim_done;
+ pthread_mutex_unlock(&(the_gpgpusim->g_sim_lock));
+ if (done) {
+ printf(
+ "GPGPU-Sim: synchronize checking: detected inactive GPU simulation "
+ "thread\n");
+ }
+ fflush(stdout);
+ return done;
+}
+
void gpgpu_context::exit_simulation() {
the_gpgpusim->g_sim_done = true;
printf("GPGPU-Sim: exit_simulation called\n");
@@ -218,8 +325,14 @@ gpgpu_sim *gpgpu_context::gpgpu_ptx_sim_init_perf() {
assert(setlocale(LC_NUMERIC, "C"));
the_gpgpusim->g_the_gpu_config->init();
- the_gpgpusim->g_the_gpu =
- new exec_gpgpu_sim(*(the_gpgpusim->g_the_gpu_config), this);
+ if (the_gpgpusim->g_the_gpu_config->is_SST_mode()) {
+ // Create SST specific GPGPUSim
+ the_gpgpusim->g_the_gpu =
+ new sst_gpgpu_sim(*(the_gpgpusim->g_the_gpu_config), this);
+ } else {
+ the_gpgpusim->g_the_gpu =
+ new exec_gpgpu_sim(*(the_gpgpusim->g_the_gpu_config), this);
+ }
the_gpgpusim->g_stream_manager = new stream_manager(
(the_gpgpusim->g_the_gpu), func_sim->g_cuda_launch_blocking);
@@ -235,12 +348,17 @@ gpgpu_sim *gpgpu_context::gpgpu_ptx_sim_init_perf() {
void gpgpu_context::start_sim_thread(int api) {
if (the_gpgpusim->g_sim_done) {
the_gpgpusim->g_sim_done = false;
- if (api == 1) {
- pthread_create(&(the_gpgpusim->g_simulation_thread), NULL,
- gpgpu_sim_thread_concurrent, (void *)this);
+ if (the_gpgpusim->g_the_gpu_config->is_SST_mode()) {
+ // Do not create concurrent thread in SST mode
+ g_the_gpu()->init();
} else {
- pthread_create(&(the_gpgpusim->g_simulation_thread), NULL,
- gpgpu_sim_thread_sequential, (void *)this);
+ if (api == 1) {
+ pthread_create(&(the_gpgpusim->g_simulation_thread), NULL,
+ gpgpu_sim_thread_concurrent, (void *)this);
+ } else {
+ pthread_create(&(the_gpgpusim->g_simulation_thread), NULL,
+ gpgpu_sim_thread_sequential, (void *)this);
+ }
}
}
}
@@ -264,8 +382,13 @@ void gpgpu_context::print_simulation_time() {
const unsigned cycles_per_sec =
(unsigned)(the_gpgpusim->g_the_gpu->gpu_tot_sim_cycle / difference);
printf("gpgpu_simulation_rate = %u (cycle/sec)\n", cycles_per_sec);
- printf("gpgpu_silicon_slowdown = %ux\n",
- the_gpgpusim->g_the_gpu->shader_clock() * 1000 / cycles_per_sec);
+
+ if (cycles_per_sec == 0) {
+ printf("gpgpu_silicon_slowdown = Nan\n");
+ } else {
+ printf("gpgpu_silicon_slowdown = %ux\n",
+ the_gpgpusim->g_the_gpu->shader_clock() * 1000 / cycles_per_sec);
+ }
fflush(stdout);
}
diff --git a/src/intersim2/CMakeLists.txt b/src/intersim2/CMakeLists.txt
new file mode 100644
index 0000000..c3da1b1
--- /dev/null
+++ b/src/intersim2/CMakeLists.txt
@@ -0,0 +1,106 @@
+option(GPGPUSIM_INTERSIM_STANDALONE "Whether to also build intersim in standalone mode" OFF)
+
+# Specify Flex and Bison target
+BISON_TARGET(intersim_config_parser config.y ${CMAKE_CURRENT_BINARY_DIR}/y.tab.c
+ COMPILE_FLAGS "-y -d --file-prefix=${CMAKE_CURRENT_BINARY_DIR}/y")
+FLEX_TARGET(intersim_config_lexer config.l ${CMAKE_CURRENT_BINARY_DIR}/lex.yy.c)
+ADD_FLEX_BISON_DEPENDENCY(intersim_config_lexer intersim_config_parser)
+
+# Set generated source files to CXX
+set_source_files_properties(${BISON_intersim_config_parser_OUTPUT_SOURCE}
+ ${FLEX_intersim_config_lexer_OUTPUTS}
+ PROPERTIES LANGUAGE CXX)
+
+# Create booksim or libintersim.a
+# Shared include path
+list(APPEND intersim_INC ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/allocators
+ ${CMAKE_CURRENT_SOURCE_DIR}/arbiters
+ ${CMAKE_CURRENT_SOURCE_DIR}/networks
+ ${CMAKE_CURRENT_SOURCE_DIR}/power
+ ${CMAKE_CURRENT_SOURCE_DIR}/routers
+ ${PROJECT_SOURCE_DIR}/src)
+
+# Shared source files
+list(APPEND intersim_SRC
+ ${BISON_intersim_config_parser_OUTPUT_SOURCE}
+ ${FLEX_intersim_config_lexer_OUTPUTS}
+ allocators/allocator.cpp
+ allocators/islip.cpp
+ allocators/loa.cpp
+ allocators/maxsize.cpp
+ allocators/pim.cpp
+ allocators/selalloc.cpp
+ allocators/separable.cpp
+ allocators/separable_input_first.cpp
+ allocators/separable_output_first.cpp
+ allocators/wavefront.cpp
+ arbiters/arbiter.cpp
+ arbiters/matrix_arb.cpp
+ arbiters/prio_arb.cpp
+ arbiters/roundrobin_arb.cpp
+ arbiters/tree_arb.cpp
+ batchtrafficmanager.cpp
+ booksim_config.cpp
+ buffer.cpp
+ buffer_state.cpp
+ config_utils.cpp
+ credit.cpp
+ flitchannel.cpp
+ flit.cpp
+ gputrafficmanager.cpp
+ injection.cpp
+ interconnect_interface.cpp
+ intersim_config.cpp
+ main.cpp
+ misc_utils.cpp
+ module.cpp
+ networks/anynet.cpp
+ networks/cmesh.cpp
+ networks/dragonfly.cpp
+ networks/fattree.cpp
+ networks/flatfly_onchip.cpp
+ networks/fly.cpp
+ networks/kncube.cpp
+ networks/network.cpp
+ networks/qtree.cpp
+ networks/tree4.cpp
+ outputset.cpp
+ packet_reply_info.cpp
+ power/buffer_monitor.cpp
+ power/power_module.cpp
+ power/switch_monitor.cpp
+ rng_double_wrapper.cpp
+ rng_wrapper.cpp
+ routefunc.cpp
+ routers/chaos_router.cpp
+ routers/event_router.cpp
+ routers/iq_router.cpp
+ routers/router.cpp
+ stats.cpp
+ traffic.cpp
+ trafficmanager.cpp
+ vc.cpp)
+
+# If standalone, also build for it
+if(GPGPUSIM_INTERSIM_STANDALONE)
+ list(REMOVE_ITEM ${intersim_SRC} interconnect_interface.cpp)
+ add_executable(booksim ${intersim_SRC})
+ target_include_directories(booksim PUBLIC
+ ${intersim_INC})
+ target_include_directories(booksim PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+ target_include_directories(booksim PUBLIC ${CUDAToolkit_INCLUDE_DIRS})
+ # Remove globally set TRACING_ON flag
+ target_compile_options(booksim PRIVATE -UTRACING_ON)
+endif()
+
+# Specify sources for libintersim.a
+add_library(intersim STATIC ${intersim_SRC})
+target_include_directories(intersim PUBLIC
+ ${intersim_INC}
+ ${PROJECT_SOURCE_DIR}/src/gpgpu-sim)
+target_include_directories(intersim PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+target_include_directories(intersim PUBLIC ${CUDAToolkit_INCLUDE_DIRS})
+target_compile_definitions(intersim PRIVATE CREATE_LIBRARY)
+# Remove globally set TRACING_ON flag
+target_compile_options(intersim PRIVATE -UTRACING_ON)
diff --git a/src/intersim2/Makefile b/src/intersim2/Makefile
index 3eeeb70..a7485e2 100644
--- a/src/intersim2/Makefile
+++ b/src/intersim2/Makefile
@@ -28,7 +28,7 @@
# Makefile
#
CXX = g++
-CC = gcc
+CC = g++
CREATE_LIBRARY ?= 0
INTERFACE = interconnect_interface.cpp
DEBUG ?= 0
@@ -136,10 +136,10 @@ depend:
makedepend -f$(OBJDIR)/Makefile.makedepend -I$(INCPATH) -p$(OBJDIR)/ $(ALL_SRCS) 2> /dev/null
${LEX_OBJS}: $(OBJDIR)/lex.yy.c $(OBJDIR)/y.tab.h
- $(CC) $(CPPFLAGS) -c $< -o $@
+ $(CC) -Wno-unused-function $(CPPFLAGS) -c $< -o $@
${YACC_OBJS}: $(OBJDIR)/y.tab.c $(OBJDIR)/y.tab.h
- $(CC) $(CPPFLAGS) -c $< -o $@
+ $(CC) -Wno-unused-function $(CPPFLAGS) -c $< -o $@
${OBJDIR}/%.o: %.cpp
$(CXX) $(CPPFLAGS) -c $< -o $@
diff --git a/src/intersim2/config_utils.cpp b/src/intersim2/config_utils.cpp
index fad5fce..a896a93 100644
--- a/src/intersim2/config_utils.cpp
+++ b/src/intersim2/config_utils.cpp
@@ -199,27 +199,27 @@ Configuration * Configuration::GetTheConfig()
//============================================================
-extern "C" void config_error( char const * msg, int lineno )
+void config_error( char * msg, int lineno )
{
Configuration::GetTheConfig( )->ParseError( msg, lineno );
}
-extern "C" void config_assign_string( char const * field, char const * value )
+ void config_assign_string( char const * field, char const * value )
{
Configuration::GetTheConfig()->Assign(field, value);
}
-extern "C" void config_assign_int( char const * field, int value )
+void config_assign_int( char const * field, int value )
{
Configuration::GetTheConfig()->Assign(field, value);
}
-extern "C" void config_assign_float( char const * field, double value )
+void config_assign_float( char const * field, double value )
{
Configuration::GetTheConfig()->Assign(field, value);
}
-extern "C" int config_input(char * line, int max_size)
+int config_input(char * line, int max_size)
{
return Configuration::GetTheConfig()->Input(line, max_size);
}
diff --git a/src/intersim2/config_utils.hpp b/src/intersim2/config_utils.hpp
index de3343b..1d960b6 100644
--- a/src/intersim2/config_utils.hpp
+++ b/src/intersim2/config_utils.hpp
@@ -35,7 +35,7 @@
#include<map>
#include<vector>
-extern "C" int yyparse();
+int yyparse();
class Configuration {
static Configuration * theConfig;
diff --git a/src/intersim2/interconnect_interface.cpp b/src/intersim2/interconnect_interface.cpp
index 1e1a2d7..438852e 100644
--- a/src/intersim2/interconnect_interface.cpp
+++ b/src/intersim2/interconnect_interface.cpp
@@ -200,7 +200,7 @@ void InterconnectInterface::Push(unsigned input_deviceID, unsigned output_device
void* InterconnectInterface::Pop(unsigned deviceID)
{
int icntID = _node_map[deviceID];
-#if DEBUG
+#if 0
cout<<"Call interconnect POP " << output<<endl;
#endif
diff --git a/src/intersim2/networks/anynet.cpp b/src/intersim2/networks/anynet.cpp
index 4db1dfb..d7c6f22 100644
--- a/src/intersim2/networks/anynet.cpp
+++ b/src/intersim2/networks/anynet.cpp
@@ -491,7 +491,7 @@ void AnyNet::readFile(){
}
sort(node_check.begin(), node_check.end());
for(size_t i = 0; i<node_check.size(); i++){
- if(node_check[i] != i){
+ if(node_check[i] != (int)i){
cout<<"Anynet:booksim trafficmanager assumes sequential node numbering starting at 0\n";
assert(false);
}
diff --git a/src/intersim2/networks/dragonfly.cpp b/src/intersim2/networks/dragonfly.cpp
index 01a2281..f5b637e 100644
--- a/src/intersim2/networks/dragonfly.cpp
+++ b/src/intersim2/networks/dragonfly.cpp
@@ -111,7 +111,7 @@ int dragonfly_port(int rID, int source, int dest){
int dest_grp_ID = int(dest/_grp_num_nodes);
int grp_output=-1;
int grp_RID=-1;
- int group_dest=-1;
+ // int group_dest=-1;
//which router within this group the packet needs to go to
if (dest_grp_ID == grp_ID) {
@@ -123,7 +123,7 @@ int dragonfly_port(int rID, int source, int dest){
grp_output = dest_grp_ID - 1;
}
grp_RID = int(grp_output /gP) + grp_ID * _grp_num_routers;
- group_dest = grp_RID * gP;
+ // group_dest = grp_RID * gP;
}
//At the last hop
@@ -221,7 +221,7 @@ void DragonFlyNew::_BuildNet( const Configuration &config )
int _input=-1;
int _dim_ID=-1;
int _num_ports_per_switch=-1;
- int _dim_size=-1;
+ // int _dim_size=-1;
int c;
ostringstream router_name;
@@ -314,7 +314,7 @@ void DragonFlyNew::_BuildNet( const Configuration &config )
// intra-group GROUP channels
for ( int dim = 0; dim < _n; ++dim ) {
- _dim_size = powi(_k,dim);
+ // _dim_size = powi(_k,dim);
_dim_ID = ((int) (node / ( powi(_p, dim))));
@@ -356,16 +356,16 @@ void DragonFlyNew::_BuildNet( const Configuration &config )
// add INPUT channels -- "optical" channels connecting the groups
- int _grp_num_routers;
+ // int _grp_num_routers;
int grp_output;
- int grp_ID2;
+ // int grp_ID2;
for ( int cnt = 0; cnt < _p; ++cnt ) {
// _dim_ID
grp_output = _dim_ID* _p + cnt;
- _grp_num_routers = powi(_k, _n-1);
- grp_ID2 = (int) ((grp_ID - 1) / (_k - 1));
+ // _grp_num_routers = powi(_k, _n-1);
+ // grp_ID2 = (int) ((grp_ID - 1) / (_k - 1));
if ( grp_ID > grp_output) {
@@ -495,8 +495,8 @@ void ugal_dragonflynew( const Router *r, const Flit *f, int in_channel,
int debug = f->watch;
int out_port = -1;
int out_vc = 0;
- int min_queue_size, min_hopcnt;
- int nonmin_queue_size, nonmin_hopcnt;
+ int min_queue_size; //, min_hopcnt;
+ int nonmin_queue_size; //, nonmin_hopcnt;
int intm_grp_ID;
int intm_rID;
@@ -523,13 +523,13 @@ void ugal_dragonflynew( const Router *r, const Flit *f, int in_channel,
f->ph = 1;
} else {
//congestion metrics using queue length, obtained by GetUsedCredit()
- min_hopcnt = dragonflynew_hopcnt(f->src, f->dest);
+ // min_hopcnt = dragonflynew_hopcnt(f->src, f->dest);
min_router_output = dragonfly_port(rID, f->src, f->dest);
min_queue_size = max(r->GetUsedCredit(min_router_output), 0) ;
- nonmin_hopcnt = dragonflynew_hopcnt(f->src, f->intm) +
- dragonflynew_hopcnt(f->intm,f->dest);
+ // nonmin_hopcnt = dragonflynew_hopcnt(f->src, f->intm) +
+ // dragonflynew_hopcnt(f->intm,f->dest);
nonmin_router_output = dragonfly_port(rID, f->src, f->intm);
nonmin_queue_size = max(r->GetUsedCredit(nonmin_router_output), 0);
diff --git a/src/intersim2/networks/flatfly_onchip.cpp b/src/intersim2/networks/flatfly_onchip.cpp
index fd17c1a..df43371 100644
--- a/src/intersim2/networks/flatfly_onchip.cpp
+++ b/src/intersim2/networks/flatfly_onchip.cpp
@@ -1204,7 +1204,7 @@ void ugal_pni_flatfly_onchip( const Router *r, const Flit *f, int in_channel,
int find_distance (int src, int dest) {
int dist = 0;
int _dim = gN;
- int _dim_size;
+ // int _dim_size;
int src_tmp= (int) src / gC;
int dest_tmp = (int) dest / gC;
@@ -1212,7 +1212,7 @@ int find_distance (int src, int dest) {
// cout << " HOP CNT between src: " << src << " dest: " << dest;
for (int d=0;d < _dim; d++) {
- _dim_size = powi(gK, d )*gC;
+ // _dim_size = powi(gK, d )*gC;
//if ((int)(src / _dim_size) != (int)(dest / _dim_size))
// dist++;
src_id = src_tmp % gK;
diff --git a/src/intersim2/networks/kncube.cpp b/src/intersim2/networks/kncube.cpp
index 03e13e7..178c905 100644
--- a/src/intersim2/networks/kncube.cpp
+++ b/src/intersim2/networks/kncube.cpp
@@ -231,7 +231,7 @@ void KNCube::InsertRandomFaults( const Configuration &config )
int num_fails;
unsigned long prev_seed;
- int node, chan;
+ int node, chan = 0;
int i, j, t, n, c;
bool available;
diff --git a/src/intersim2/networks/qtree.cpp b/src/intersim2/networks/qtree.cpp
index 7214947..37d3d7c 100644
--- a/src/intersim2/networks/qtree.cpp
+++ b/src/intersim2/networks/qtree.cpp
@@ -84,7 +84,7 @@ void QTree::_BuildNet( const Configuration& config )
{
ostringstream routerName;
- int h, r, pos, port;
+ int h, r = 0 , pos, port;
for (h = 0; h < _n; h++) {
for (pos = 0 ; pos < powi( _k, h ) ; ++pos ) {
diff --git a/src/intersim2/vc.cpp b/src/intersim2/vc.cpp
index 94e8c6b..4c94445 100644
--- a/src/intersim2/vc.cpp
+++ b/src/intersim2/vc.cpp
@@ -82,7 +82,7 @@ void VC::AddFlit( Flit *f )
assert(f);
if(_expected_pid >= 0) {
- if(f->pid != _expected_pid) {
+ if((long long int)f->pid != _expected_pid) {
ostringstream err;
err << "Received flit " << f->id << " with unexpected packet ID: " << f->pid
<< " (expected: " << _expected_pid << ")";
diff --git a/src/stream_manager.cc b/src/stream_manager.cc
index e99bf87..58c2ec4 100644
--- a/src/stream_manager.cc
+++ b/src/stream_manager.cc
@@ -34,6 +34,16 @@
unsigned CUstream_st::sm_next_stream_uid = 0;
+// SST memcpy callbacks
+extern void SST_callback_memcpy_H2D_done();
+extern void SST_callback_memcpy_D2H_done();
+extern void SST_callback_memcpy_to_symbol_done();
+extern void SST_callback_memcpy_from_symbol_done();
+__attribute__((weak)) void SST_callback_memcpy_H2D_done() {}
+__attribute__((weak)) void SST_callback_memcpy_D2H_done() {}
+__attribute__((weak)) void SST_callback_memcpy_to_symbol_done() {}
+__attribute__((weak)) void SST_callback_memcpy_from_symbol_done() {}
+
CUstream_st::CUstream_st() {
m_pending = false;
m_uid = sm_next_stream_uid++;
@@ -122,11 +132,13 @@ bool stream_operation::do_operation(gpgpu_sim *gpu) {
if (g_debug_execution >= 3) printf("memcpy host-to-device\n");
gpu->memcpy_to_gpu(m_device_address_dst, m_host_address_src, m_cnt);
m_stream->record_next_done();
+ if (gpu->is_SST_mode()) SST_callback_memcpy_H2D_done();
break;
case stream_memcpy_device_to_host:
if (g_debug_execution >= 3) printf("memcpy device-to-host\n");
gpu->memcpy_from_gpu(m_host_address_dst, m_device_address_src, m_cnt);
m_stream->record_next_done();
+ if (gpu->is_SST_mode()) SST_callback_memcpy_D2H_done();
break;
case stream_memcpy_device_to_device:
if (g_debug_execution >= 3) printf("memcpy device-to-device\n");
@@ -138,12 +150,14 @@ bool stream_operation::do_operation(gpgpu_sim *gpu) {
gpu->gpgpu_ctx->func_sim->gpgpu_ptx_sim_memcpy_symbol(
m_symbol, m_host_address_src, m_cnt, m_offset, 1, gpu);
m_stream->record_next_done();
+ if (gpu->is_SST_mode()) SST_callback_memcpy_to_symbol_done();
break;
case stream_memcpy_from_symbol:
if (g_debug_execution >= 3) printf("memcpy from symbol\n");
gpu->gpgpu_ctx->func_sim->gpgpu_ptx_sim_memcpy_symbol(
m_symbol, m_host_address_dst, m_cnt, m_offset, 0, gpu);
m_stream->record_next_done();
+ if (gpu->is_SST_mode()) SST_callback_memcpy_from_symbol_done();
break;
case stream_kernel_launch:
if (m_sim_mode) { // Functional Sim
@@ -227,6 +241,8 @@ void stream_operation::print(FILE *fp) const {
case stream_no_op:
fprintf(fp, "no-op");
break;
+ default:
+ break;
}
}
@@ -300,6 +316,14 @@ bool stream_manager::register_finished_kernel(unsigned grid_uid) {
void stream_manager::stop_all_running_kernels() {
pthread_mutex_lock(&m_lock);
+ std::vector<unsigned long long> finished_streams;
+ std::vector<kernel_info_t *> running_kernels = m_gpu->get_running_kernels();
+ for (kernel_info_t *k : running_kernels) {
+ if (k != NULL) {
+ finished_streams.push_back(k->get_streamID());
+ }
+ }
+
// Signal m_gpu to stop all running kernels
m_gpu->stop_all_running_kernels();
@@ -310,7 +334,9 @@ void stream_manager::stop_all_running_kernels() {
}
// If any kernels completed, print out the current stats
- if (count > 0) m_gpu->print_stats();
+ for (unsigned long long streamID : finished_streams) {
+ m_gpu->print_stats(streamID);
+ }
pthread_mutex_unlock(&m_lock);
}
@@ -460,7 +486,7 @@ void stream_manager::push(stream_operation op) {
}
if (g_debug_execution >= 3) print_impl(stdout);
pthread_mutex_unlock(&m_lock);
- if (m_cuda_launch_blocking || stream == NULL) {
+ if (!m_gpu->is_SST_mode() && (m_cuda_launch_blocking || stream == NULL)) {
unsigned int wait_amount = 100;
unsigned int wait_cap = 100000; // 100ms
while (!empty()) {
diff --git a/src/stream_manager.h b/src/stream_manager.h
index afcbb0e..561f54b 100644
--- a/src/stream_manager.h
+++ b/src/stream_manager.h
@@ -73,7 +73,7 @@ struct CUevent_st {
int m_uid;
bool m_blocking;
bool m_done;
- int m_updates;
+ unsigned int m_updates;
unsigned int m_issued;
time_t m_wallclock;
double m_gpu_tot_sim_cycle;