summaryrefslogtreecommitdiff
path: root/src/abstract_hardware_model.h
diff options
context:
space:
mode:
authorMahmoud <[email protected]>2019-09-16 10:47:08 -0400
committerMahmoud <[email protected]>2019-09-16 10:47:08 -0400
commit0785ce7c9471bf1a0c70500eb60cb293fb5aa2fa (patch)
tree15dcaeaf1b1e0e9e3c04af74e72545854793d244 /src/abstract_hardware_model.h
parent688044e9f7a9aef0a63a9610b496baafd886c556 (diff)
parentdba877b45fe11187d56904bbd169f4e0a5ad0586 (diff)
Merge branch 'dev' of https://github.com/purdue-aalp/gpgpu-sim_distribution into dev-private
Diffstat (limited to 'src/abstract_hardware_model.h')
-rw-r--r--src/abstract_hardware_model.h2127
1 files changed, 1083 insertions, 1044 deletions
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index 341e44c..4a6e02a 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -7,23 +7,24 @@
//
// Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
-// 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.
-// Neither the name of The University of British Columbia nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
+// 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. Neither the name of
+// The University of British Columbia nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
#ifndef ABSTRACT_HARDWARE_MODEL_INCLUDED
#define ABSTRACT_HARDWARE_MODEL_INCLUDED
@@ -33,35 +34,32 @@ class gpgpu_sim;
class kernel_info_t;
class gpgpu_context;
-
-//Set a hard limit of 32 CTAs per shader [cuda only has 8]
+// Set a hard limit of 32 CTAs per shader [cuda only has 8]
#define MAX_CTA_PER_SHADER 32
#define MAX_BARRIERS_PER_CTA 16
-//After expanding the vector input and output operands
+// After expanding the vector input and output operands
#define MAX_INPUT_VALUES 24
#define MAX_OUTPUT_VALUES 8
enum _memory_space_t {
- undefined_space=0,
- reg_space,
- local_space,
- shared_space,
- sstarr_space,
- param_space_unclassified,
- param_space_kernel, /* global to all threads in a kernel : read-only */
- param_space_local, /* local to a thread : read-writable */
- const_space,
- tex_space,
- surf_space,
- global_space,
- generic_space,
- instruction_space
+ undefined_space = 0,
+ reg_space,
+ local_space,
+ shared_space,
+ sstarr_space,
+ param_space_unclassified,
+ param_space_kernel, /* global to all threads in a kernel : read-only */
+ param_space_local, /* local to a thread : read-writable */
+ const_space,
+ tex_space,
+ surf_space,
+ global_space,
+ generic_space,
+ instruction_space
};
-
-enum FuncCache
-{
+enum FuncCache {
FuncCachePreferNone = 0,
FuncCachePreferShared = 1,
FuncCachePreferL1 = 2
@@ -75,8 +73,8 @@ enum AdaptiveCache
#ifdef __cplusplus
-#include <string.h>
#include <stdio.h>
+#include <string.h>
#include <set>
typedef unsigned long long new_addr_type;
@@ -84,371 +82,357 @@ typedef unsigned long long cudaTextureObject_t;
typedef unsigned address_type;
typedef unsigned addr_t;
-// the following are operations the timing model can see
+// the following are operations the timing model can see
enum uarch_op_t {
- NO_OP=-1,
- ALU_OP=1,
- SFU_OP,
- TENSOR_CORE_OP,
- DP_OP,
- SP_OP,
- INTP_OP,
- ALU_SFU_OP,
- LOAD_OP,
- TENSOR_CORE_LOAD_OP,
- TENSOR_CORE_STORE_OP,
- STORE_OP,
- BRANCH_OP,
- BARRIER_OP,
- MEMORY_BARRIER_OP,
- CALL_OPS,
- RET_OPS
+ NO_OP = -1,
+ ALU_OP = 1,
+ SFU_OP,
+ TENSOR_CORE_OP,
+ DP_OP,
+ SP_OP,
+ INTP_OP,
+ ALU_SFU_OP,
+ LOAD_OP,
+ TENSOR_CORE_LOAD_OP,
+ TENSOR_CORE_STORE_OP,
+ STORE_OP,
+ BRANCH_OP,
+ BARRIER_OP,
+ MEMORY_BARRIER_OP,
+ CALL_OPS,
+ RET_OPS
};
typedef enum uarch_op_t op_type;
-
-enum uarch_bar_t {
- NOT_BAR=-1,
- SYNC=1,
- ARRIVE,
- RED
-};
+enum uarch_bar_t { NOT_BAR = -1, SYNC = 1, ARRIVE, RED };
typedef enum uarch_bar_t barrier_type;
-enum uarch_red_t {
- NOT_RED=-1,
- POPC_RED=1,
- AND_RED,
- OR_RED
-};
+enum uarch_red_t { NOT_RED = -1, POPC_RED = 1, AND_RED, OR_RED };
typedef enum uarch_red_t reduction_type;
-
-enum uarch_operand_type_t {
- UN_OP=-1,
- INT_OP,
- FP_OP
-};
+enum uarch_operand_type_t { UN_OP = -1, INT_OP, FP_OP };
typedef enum uarch_operand_type_t types_of_operands;
enum special_operations_t {
- OTHER_OP,
- INT__OP,
- INT_MUL24_OP,
- INT_MUL32_OP,
- INT_MUL_OP,
- INT_DIV_OP,
- FP_MUL_OP,
- FP_DIV_OP,
- FP__OP,
- FP_SQRT_OP,
- FP_LG_OP,
- FP_SIN_OP,
- FP_EXP_OP
+ OTHER_OP,
+ INT__OP,
+ INT_MUL24_OP,
+ INT_MUL32_OP,
+ INT_MUL_OP,
+ INT_DIV_OP,
+ FP_MUL_OP,
+ FP_DIV_OP,
+ FP__OP,
+ FP_SQRT_OP,
+ FP_LG_OP,
+ FP_SIN_OP,
+ FP_EXP_OP
};
-typedef enum special_operations_t special_ops; // Required to identify for the power model
+typedef enum special_operations_t
+ special_ops; // Required to identify for the power model
enum operation_pipeline_t {
- UNKOWN_OP,
- SP__OP,
- DP__OP,
- INTP__OP,
- SFU__OP,
- TENSOR_CORE__OP,
- MEM__OP
+ UNKOWN_OP,
+ SP__OP,
+ DP__OP,
+ INTP__OP,
+ SFU__OP,
+ TENSOR_CORE__OP,
+ MEM__OP
};
typedef enum operation_pipeline_t operation_pipeline;
-enum mem_operation_t {
- NOT_TEX,
- TEX
-};
+enum mem_operation_t { NOT_TEX, TEX };
typedef enum mem_operation_t mem_operation;
-enum _memory_op_t {
- no_memory_op = 0,
- memory_load,
- memory_store
-};
+enum _memory_op_t { no_memory_op = 0, memory_load, memory_store };
-#include <bitset>
-#include <list>
-#include <vector>
#include <assert.h>
#include <stdlib.h>
-#include <map>
-#include <deque>
#include <algorithm>
+#include <bitset>
+#include <deque>
+#include <list>
+#include <map>
+#include <vector>
#if !defined(__VECTOR_TYPES_H__)
#include "vector_types.h"
#endif
struct dim3comp {
- bool operator() (const dim3 & a, const dim3 & b) const
- {
- if(a.z < b.z)
- return true;
- else if(a.y < b.y)
- return true;
- else if (a.x < b.x)
- return true;
- else
- return false;
- }
+ bool operator()(const dim3 &a, const dim3 &b) const {
+ if (a.z < b.z)
+ return true;
+ else if (a.y < b.y)
+ return true;
+ else if (a.x < b.x)
+ return true;
+ else
+ return false;
+ }
};
-void increment_x_then_y_then_z( dim3 &i, const dim3 &bound);
+void increment_x_then_y_then_z(dim3 &i, const dim3 &bound);
-//Jin: child kernel information for CDP
+// Jin: child kernel information for CDP
#include "stream_manager.h"
class stream_manager;
struct CUstream_st;
-//extern stream_manager * g_stream_manager;
-//support for pinned memories added
-extern std::map<void *,void **> pinned_memory;
+// extern stream_manager * g_stream_manager;
+// support for pinned memories added
+extern std::map<void *, void **> pinned_memory;
extern std::map<void *, size_t> pinned_memory_size;
class kernel_info_t {
-public:
-// kernel_info_t()
-// {
-// m_valid=false;
-// m_kernel_entry=NULL;
-// m_uid=0;
-// 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, std::map<std::string, const struct cudaArray*> nameToCudaArray, std::map<std::string, const struct textureInfo*> nameToTextureInfo);
- ~kernel_info_t();
+ public:
+ // kernel_info_t()
+ // {
+ // m_valid=false;
+ // m_kernel_entry=NULL;
+ // m_uid=0;
+ // 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,
+ std::map<std::string, const struct cudaArray *> nameToCudaArray,
+ std::map<std::string, const struct textureInfo *> nameToTextureInfo);
+ ~kernel_info_t();
- void inc_running() { m_num_cores_running++; }
- void dec_running()
- {
- assert( m_num_cores_running > 0 );
- m_num_cores_running--;
- }
- bool running() const { return m_num_cores_running>0; }
- bool done() const
- {
- return no_more_ctas_to_run() && !running();
- }
- class function_info *entry() { return m_kernel_entry; }
- const class function_info *entry() const { return m_kernel_entry; }
+ void inc_running() { m_num_cores_running++; }
+ void dec_running() {
+ assert(m_num_cores_running > 0);
+ m_num_cores_running--;
+ }
+ bool running() const { return m_num_cores_running > 0; }
+ bool done() const { return no_more_ctas_to_run() && !running(); }
+ class function_info *entry() {
+ return m_kernel_entry;
+ }
+ const class function_info *entry() const { return m_kernel_entry; }
- size_t num_blocks() const
- {
- return m_grid_dim.x * m_grid_dim.y * m_grid_dim.z;
- }
+ size_t num_blocks() const {
+ return m_grid_dim.x * m_grid_dim.y * m_grid_dim.z;
+ }
- size_t threads_per_cta() const
- {
- return m_block_dim.x * m_block_dim.y * m_block_dim.z;
- }
+ size_t threads_per_cta() const {
+ return m_block_dim.x * m_block_dim.y * m_block_dim.z;
+ }
- dim3 get_grid_dim() const { return m_grid_dim; }
- dim3 get_cta_dim() const { return m_block_dim; }
+ dim3 get_grid_dim() const { return m_grid_dim; }
+ dim3 get_cta_dim() const { return m_block_dim; }
- void increment_cta_id()
- {
- increment_x_then_y_then_z(m_next_cta,m_grid_dim);
- m_next_tid.x=0;
- m_next_tid.y=0;
- m_next_tid.z=0;
- }
- dim3 get_next_cta_id() const { return m_next_cta; }
- unsigned get_next_cta_id_single() const
- {
- return m_next_cta.x + m_grid_dim.x*m_next_cta.y + m_grid_dim.x*m_grid_dim.y*m_next_cta.z;
- }
- bool no_more_ctas_to_run() const
- {
- return (m_next_cta.x >= m_grid_dim.x || m_next_cta.y >= m_grid_dim.y || m_next_cta.z >= m_grid_dim.z );
- }
+ void increment_cta_id() {
+ increment_x_then_y_then_z(m_next_cta, m_grid_dim);
+ m_next_tid.x = 0;
+ m_next_tid.y = 0;
+ m_next_tid.z = 0;
+ }
+ dim3 get_next_cta_id() const { return m_next_cta; }
+ unsigned get_next_cta_id_single() const {
+ return m_next_cta.x + m_grid_dim.x * m_next_cta.y +
+ m_grid_dim.x * m_grid_dim.y * m_next_cta.z;
+ }
+ bool no_more_ctas_to_run() const {
+ return (m_next_cta.x >= m_grid_dim.x || m_next_cta.y >= m_grid_dim.y ||
+ m_next_cta.z >= m_grid_dim.z);
+ }
- void increment_thread_id() { increment_x_then_y_then_z(m_next_tid,m_block_dim); }
- dim3 get_next_thread_id_3d() const { return m_next_tid; }
- unsigned get_next_thread_id() const
- {
- return m_next_tid.x + m_block_dim.x*m_next_tid.y + m_block_dim.x*m_block_dim.y*m_next_tid.z;
- }
- bool more_threads_in_cta() const
- {
- return m_next_tid.z < m_block_dim.z && m_next_tid.y < m_block_dim.y && m_next_tid.x < m_block_dim.x;
- }
- unsigned get_uid() const { return m_uid; }
- std::string name() const;
+ void increment_thread_id() {
+ increment_x_then_y_then_z(m_next_tid, m_block_dim);
+ }
+ dim3 get_next_thread_id_3d() const { return m_next_tid; }
+ unsigned get_next_thread_id() const {
+ return m_next_tid.x + m_block_dim.x * m_next_tid.y +
+ m_block_dim.x * m_block_dim.y * m_next_tid.z;
+ }
+ bool more_threads_in_cta() const {
+ return m_next_tid.z < m_block_dim.z && m_next_tid.y < m_block_dim.y &&
+ m_next_tid.x < m_block_dim.x;
+ }
+ unsigned get_uid() const { return m_uid; }
+ std::string name() const;
- std::list<class ptx_thread_info *> &active_threads() { return m_active_threads; }
- class memory_space *get_param_memory() { return m_param_mem; }
+ std::list<class ptx_thread_info *> &active_threads() {
+ return m_active_threads;
+ }
+ class memory_space *get_param_memory() {
+ return m_param_mem;
+ }
-
- //The following functions access texture bindings present at the kernel's launch
-
- const struct cudaArray* get_texarray( const std::string &texname ) const
- {
- std::map<std::string,const struct cudaArray*>::const_iterator t=m_NameToCudaArray.find(texname);
- assert(t != m_NameToCudaArray.end());
- return t->second;
- }
+ // The following functions access texture bindings present at the kernel's
+ // launch
- const struct textureInfo* get_texinfo( const std::string &texname ) const
- {
- std::map<std::string, const struct textureInfo*>::const_iterator t=m_NameToTextureInfo.find(texname);
- assert(t != m_NameToTextureInfo.end());
- return t->second;
- }
+ const struct cudaArray *get_texarray(const std::string &texname) const {
+ std::map<std::string, const struct cudaArray *>::const_iterator t =
+ m_NameToCudaArray.find(texname);
+ assert(t != m_NameToCudaArray.end());
+ return t->second;
+ }
-private:
- kernel_info_t( const kernel_info_t & ); // disable copy constructor
- void operator=( const kernel_info_t & ); // disable copy operator
+ const struct textureInfo *get_texinfo(const std::string &texname) const {
+ std::map<std::string, const struct textureInfo *>::const_iterator t =
+ m_NameToTextureInfo.find(texname);
+ assert(t != m_NameToTextureInfo.end());
+ return t->second;
+ }
- class function_info *m_kernel_entry;
+ private:
+ kernel_info_t(const kernel_info_t &); // disable copy constructor
+ void operator=(const kernel_info_t &); // disable copy operator
- unsigned m_uid;
-
- //These maps contain the snapshot of the texture mappings at kernel launch
- std::map<std::string, const struct cudaArray*> m_NameToCudaArray;
- std::map<std::string, const struct textureInfo*> m_NameToTextureInfo;
+ class function_info *m_kernel_entry;
- dim3 m_grid_dim;
- dim3 m_block_dim;
- dim3 m_next_cta;
- dim3 m_next_tid;
+ unsigned m_uid;
- unsigned m_num_cores_running;
+ // These maps contain the snapshot of the texture mappings at kernel launch
+ std::map<std::string, const struct cudaArray *> m_NameToCudaArray;
+ std::map<std::string, const struct textureInfo *> m_NameToTextureInfo;
- std::list<class ptx_thread_info *> m_active_threads;
- class memory_space *m_param_mem;
+ dim3 m_grid_dim;
+ dim3 m_block_dim;
+ dim3 m_next_cta;
+ dim3 m_next_tid;
-public:
- //Jin: parent and child kernel management for CDP
- void set_parent(kernel_info_t * parent, dim3 parent_ctaid, dim3 parent_tid);
- void set_child(kernel_info_t * child);
- void remove_child(kernel_info_t * child);
- bool is_finished();
- bool children_all_finished();
- void notify_parent_finished();
- CUstream_st * create_stream_cta(dim3 ctaid);
- CUstream_st * get_default_stream_cta(dim3 ctaid);
- bool cta_has_stream(dim3 ctaid, CUstream_st* stream);
- void destroy_cta_streams();
- void print_parent_info();
- kernel_info_t * get_parent() { return m_parent_kernel; }
+ unsigned m_num_cores_running;
-private:
- kernel_info_t * m_parent_kernel;
- dim3 m_parent_ctaid;
- dim3 m_parent_tid;
- std::list<kernel_info_t *> m_child_kernels; //child kernel launched
- std::map< dim3, std::list<CUstream_st *>, dim3comp > m_cta_streams; //streams created in each CTA
+ std::list<class ptx_thread_info *> m_active_threads;
+ class memory_space *m_param_mem;
-//Jin: kernel timing
-public:
- unsigned long long launch_cycle;
- unsigned long long start_cycle;
- unsigned long long end_cycle;
- unsigned m_launch_latency;
+ public:
+ // Jin: parent and child kernel management for CDP
+ void set_parent(kernel_info_t *parent, dim3 parent_ctaid, dim3 parent_tid);
+ void set_child(kernel_info_t *child);
+ void remove_child(kernel_info_t *child);
+ bool is_finished();
+ bool children_all_finished();
+ void notify_parent_finished();
+ CUstream_st *create_stream_cta(dim3 ctaid);
+ CUstream_st *get_default_stream_cta(dim3 ctaid);
+ bool cta_has_stream(dim3 ctaid, CUstream_st *stream);
+ void destroy_cta_streams();
+ void print_parent_info();
+ kernel_info_t *get_parent() { return m_parent_kernel; }
- mutable bool cache_config_set;
+ private:
+ kernel_info_t *m_parent_kernel;
+ dim3 m_parent_ctaid;
+ dim3 m_parent_tid;
+ std::list<kernel_info_t *> m_child_kernels; // child kernel launched
+ std::map<dim3, std::list<CUstream_st *>, dim3comp>
+ m_cta_streams; // streams created in each CTA
+
+ // Jin: kernel timing
+ public:
+ unsigned long long launch_cycle;
+ unsigned long long start_cycle;
+ unsigned long long end_cycle;
+ unsigned m_launch_latency;
+
+ mutable bool cache_config_set;
};
class core_config {
- public:
- core_config(gpgpu_context* ctx)
- {
- gpgpu_ctx = ctx;
- m_valid = false;
- num_shmem_bank=16;
- shmem_limited_broadcast = false;
- gpgpu_shmem_sizeDefault=(unsigned)-1;
- gpgpu_shmem_sizePrefL1=(unsigned)-1;
- gpgpu_shmem_sizePrefShared=(unsigned)-1;
- }
- virtual void init() = 0;
+ public:
+ core_config(gpgpu_context *ctx) {
+ gpgpu_ctx = ctx;
+ m_valid = false;
+ num_shmem_bank = 16;
+ shmem_limited_broadcast = false;
+ gpgpu_shmem_sizeDefault = (unsigned)-1;
+ gpgpu_shmem_sizePrefL1 = (unsigned)-1;
+ gpgpu_shmem_sizePrefShared = (unsigned)-1;
+ }
+ virtual void init() = 0;
- bool m_valid;
- unsigned warp_size;
- // backward pointer
- class gpgpu_context* gpgpu_ctx;
+ bool m_valid;
+ unsigned warp_size;
+ // backward pointer
+ class gpgpu_context *gpgpu_ctx;
- // off-chip memory request architecture parameters
- int gpgpu_coalesce_arch;
+ // off-chip memory request architecture parameters
+ int gpgpu_coalesce_arch;
- // shared memory bank conflict checking parameters
- bool shmem_limited_broadcast;
- static const address_type WORD_SIZE=4;
- unsigned num_shmem_bank;
- unsigned shmem_bank_func(address_type addr) const
- {
- return ((addr/WORD_SIZE) % num_shmem_bank);
- }
- unsigned mem_warp_parts;
- mutable unsigned gpgpu_shmem_size;
- unsigned gpgpu_shmem_sizeDefault;
- unsigned gpgpu_shmem_sizePrefL1;
- unsigned gpgpu_shmem_sizePrefShared;
- unsigned mem_unit_ports;
+ // shared memory bank conflict checking parameters
+ bool shmem_limited_broadcast;
+ static const address_type WORD_SIZE = 4;
+ unsigned num_shmem_bank;
+ unsigned shmem_bank_func(address_type addr) const {
+ return ((addr / WORD_SIZE) % num_shmem_bank);
+ }
+ unsigned mem_warp_parts;
+ mutable unsigned gpgpu_shmem_size;
+ unsigned gpgpu_shmem_sizeDefault;
+ unsigned gpgpu_shmem_sizePrefL1;
+ unsigned gpgpu_shmem_sizePrefShared;
+ unsigned mem_unit_ports;
- // texture and constant cache line sizes (used to determine number of memory accesses)
- unsigned gpgpu_cache_texl1_linesize;
- unsigned gpgpu_cache_constl1_linesize;
+ // texture and constant cache line sizes (used to determine number of memory
+ // accesses)
+ unsigned gpgpu_cache_texl1_linesize;
+ unsigned gpgpu_cache_constl1_linesize;
- unsigned gpgpu_max_insn_issue_per_warp;
- bool gmem_skip_L1D; // on = global memory access always skip the L1 cache
+ unsigned gpgpu_max_insn_issue_per_warp;
+ bool gmem_skip_L1D; // on = global memory access always skip the L1 cache
- unsigned adaptive_cache_config;
+ bool adaptive_cache_config;
};
-// bounded stack that implements simt reconvergence using pdom mechanism from MICRO'07 paper
+// bounded stack that implements simt reconvergence using pdom mechanism from
+// MICRO'07 paper
const unsigned MAX_WARP_SIZE = 32;
typedef std::bitset<MAX_WARP_SIZE> active_mask_t;
-#define MAX_WARP_SIZE_SIMT_STACK MAX_WARP_SIZE
+#define MAX_WARP_SIZE_SIMT_STACK MAX_WARP_SIZE
typedef std::bitset<MAX_WARP_SIZE_SIMT_STACK> simt_mask_t;
typedef std::vector<address_type> addr_vector_t;
class simt_stack {
-public:
- simt_stack( unsigned wid, unsigned warpSize, class gpgpu_sim * gpu);
-
- void reset();
- void launch( address_type start_pc, const simt_mask_t &active_mask );
- void update( simt_mask_t &thread_done, addr_vector_t &next_pc, address_type recvg_pc, op_type next_inst_op,unsigned next_inst_size, address_type next_inst_pc );
+ public:
+ simt_stack(unsigned wid, unsigned warpSize, class gpgpu_sim *gpu);
- const simt_mask_t &get_active_mask() const;
- void get_pdom_stack_top_info( unsigned *pc, unsigned *rpc ) const;
- unsigned get_rp() const;
- void print(FILE *fp) const;
- void resume(char * fname) ;
- void print_checkpoint (FILE *fout) const;
+ void reset();
+ void launch(address_type start_pc, const simt_mask_t &active_mask);
+ void update(simt_mask_t &thread_done, addr_vector_t &next_pc,
+ address_type recvg_pc, op_type next_inst_op,
+ unsigned next_inst_size, address_type next_inst_pc);
-protected:
- unsigned m_warp_id;
- unsigned m_warp_size;
+ const simt_mask_t &get_active_mask() const;
+ void get_pdom_stack_top_info(unsigned *pc, unsigned *rpc) const;
+ unsigned get_rp() const;
+ void print(FILE *fp) const;
+ void resume(char *fname);
+ void print_checkpoint(FILE *fout) const;
+ protected:
+ unsigned m_warp_id;
+ unsigned m_warp_size;
- enum stack_entry_type {
- STACK_ENTRY_TYPE_NORMAL = 0,
- STACK_ENTRY_TYPE_CALL
- };
+ enum stack_entry_type { STACK_ENTRY_TYPE_NORMAL = 0, STACK_ENTRY_TYPE_CALL };
- struct simt_stack_entry {
- address_type m_pc;
- unsigned int m_calldepth;
- simt_mask_t m_active_mask;
- address_type m_recvg_pc;
- unsigned long long m_branch_div_cycle;
- stack_entry_type m_type;
- simt_stack_entry() :
- m_pc(-1), m_calldepth(0), m_active_mask(), m_recvg_pc(-1), m_branch_div_cycle(0), m_type(STACK_ENTRY_TYPE_NORMAL) { };
- };
+ struct simt_stack_entry {
+ address_type m_pc;
+ unsigned int m_calldepth;
+ simt_mask_t m_active_mask;
+ address_type m_recvg_pc;
+ unsigned long long m_branch_div_cycle;
+ stack_entry_type m_type;
+ simt_stack_entry()
+ : m_pc(-1),
+ m_calldepth(0),
+ m_active_mask(),
+ m_recvg_pc(-1),
+ m_branch_div_cycle(0),
+ m_type(STACK_ENTRY_TYPE_NORMAL){};
+ };
- std::deque<simt_stack_entry> m_stack;
+ std::deque<simt_stack_entry> m_stack;
- class gpgpu_sim * m_gpu;
+ class gpgpu_sim *m_gpu;
};
// Let's just upgrade to C++11 so we can use constexpr here...
-// start allocating from this address (lower values used for allocating globals in .ptx file)
+// start allocating from this address (lower values used for allocating globals
+// in .ptx file)
const unsigned long long GLOBAL_HEAP_START = 0xC0000000;
// Volta max shmem size is 96kB
const unsigned long long SHARED_MEM_SIZE_MAX = 96 * (1 << 10);
@@ -460,873 +444,928 @@ const unsigned MAX_STREAMING_MULTIPROCESSORS = 80;
const unsigned MAX_THREAD_PER_SM = 1 << 11;
// MAX 64 warps / SM
const unsigned MAX_WARP_PER_SM = 1 << 6;
-const unsigned long long TOTAL_LOCAL_MEM_PER_SM = MAX_THREAD_PER_SM * LOCAL_MEM_SIZE_MAX;
-const unsigned long long TOTAL_SHARED_MEM = MAX_STREAMING_MULTIPROCESSORS * SHARED_MEM_SIZE_MAX;
-const unsigned long long TOTAL_LOCAL_MEM = MAX_STREAMING_MULTIPROCESSORS * MAX_THREAD_PER_SM * LOCAL_MEM_SIZE_MAX;
-const unsigned long long SHARED_GENERIC_START = GLOBAL_HEAP_START - TOTAL_SHARED_MEM;
-const unsigned long long LOCAL_GENERIC_START = SHARED_GENERIC_START - TOTAL_LOCAL_MEM;
-const unsigned long long STATIC_ALLOC_LIMIT = GLOBAL_HEAP_START - (TOTAL_LOCAL_MEM + TOTAL_SHARED_MEM);
+const unsigned long long TOTAL_LOCAL_MEM_PER_SM =
+ MAX_THREAD_PER_SM * LOCAL_MEM_SIZE_MAX;
+const unsigned long long TOTAL_SHARED_MEM =
+ MAX_STREAMING_MULTIPROCESSORS * SHARED_MEM_SIZE_MAX;
+const unsigned long long TOTAL_LOCAL_MEM =
+ MAX_STREAMING_MULTIPROCESSORS * MAX_THREAD_PER_SM * LOCAL_MEM_SIZE_MAX;
+const unsigned long long SHARED_GENERIC_START =
+ GLOBAL_HEAP_START - TOTAL_SHARED_MEM;
+const unsigned long long LOCAL_GENERIC_START =
+ SHARED_GENERIC_START - TOTAL_LOCAL_MEM;
+const unsigned long long STATIC_ALLOC_LIMIT =
+ GLOBAL_HEAP_START - (TOTAL_LOCAL_MEM + TOTAL_SHARED_MEM);
#if !defined(__CUDA_RUNTIME_API_H__)
#include "builtin_types.h"
struct cudaArray {
- void *devPtr;
- int devPtr32;
- struct cudaChannelFormatDesc desc;
- int width;
- int height;
- int size; //in bytes
- unsigned dimensions;
+ void *devPtr;
+ int devPtr32;
+ struct cudaChannelFormatDesc desc;
+ int width;
+ int height;
+ int size; // in bytes
+ unsigned dimensions;
};
#endif
-// Struct that record other attributes in the textureReference declaration
+// Struct that record other attributes in the textureReference declaration
// - These attributes are passed thru __cudaRegisterTexture()
struct textureReferenceAttr {
- const struct textureReference *m_texref;
- int m_dim;
- enum cudaTextureReadMode m_readmode;
- int m_ext;
- textureReferenceAttr(const struct textureReference *texref,
- int dim,
- enum cudaTextureReadMode readmode,
- int ext)
- : m_texref(texref), m_dim(dim), m_readmode(readmode), m_ext(ext)
- { }
+ const struct textureReference *m_texref;
+ int m_dim;
+ enum cudaTextureReadMode m_readmode;
+ int m_ext;
+ textureReferenceAttr(const struct textureReference *texref, int dim,
+ enum cudaTextureReadMode readmode, int ext)
+ : m_texref(texref), m_dim(dim), m_readmode(readmode), m_ext(ext) {}
};
-class gpgpu_functional_sim_config
-{
-public:
- void reg_options(class OptionParser * opp);
+class gpgpu_functional_sim_config {
+ public:
+ void reg_options(class OptionParser *opp);
- void ptx_set_tex_cache_linesize(unsigned linesize);
+ void ptx_set_tex_cache_linesize(unsigned linesize);
- unsigned get_forced_max_capability() const { return m_ptx_force_max_capability; }
- bool convert_to_ptxplus() const { return m_ptx_convert_to_ptxplus; }
- bool use_cuobjdump() const { return m_ptx_use_cuobjdump; }
- bool experimental_lib_support() const { return m_experimental_lib_support; }
+ unsigned get_forced_max_capability() const {
+ return m_ptx_force_max_capability;
+ }
+ bool convert_to_ptxplus() const { return m_ptx_convert_to_ptxplus; }
+ bool use_cuobjdump() const { return m_ptx_use_cuobjdump; }
+ bool experimental_lib_support() const { return m_experimental_lib_support; }
- int get_ptx_inst_debug_to_file() const { return g_ptx_inst_debug_to_file; }
- const char* get_ptx_inst_debug_file() const { return g_ptx_inst_debug_file; }
- int get_ptx_inst_debug_thread_uid() const { return g_ptx_inst_debug_thread_uid; }
- unsigned get_texcache_linesize() const { return m_texcache_linesize; }
- int get_checkpoint_option() const {return checkpoint_option; }
- int get_checkpoint_kernel() const {return checkpoint_kernel; }
- int get_checkpoint_CTA() const {return checkpoint_CTA; }
- int get_resume_option() const {return resume_option; }
- int get_resume_kernel() const {return resume_kernel; }
- int get_resume_CTA() const {return resume_CTA; }
- int get_checkpoint_CTA_t() const {return checkpoint_CTA_t; }
- int get_checkpoint_insn_Y() const {return checkpoint_insn_Y; }
-private:
- // PTX options
- int m_ptx_convert_to_ptxplus;
- int m_ptx_use_cuobjdump;
- int m_experimental_lib_support;
- unsigned m_ptx_force_max_capability;
- int checkpoint_option;
- int checkpoint_kernel;
- int checkpoint_CTA;
- unsigned resume_option;
- unsigned resume_kernel;
- unsigned resume_CTA;
- unsigned checkpoint_CTA_t;
- int checkpoint_insn_Y;
- int g_ptx_inst_debug_to_file;
- char* g_ptx_inst_debug_file;
- int g_ptx_inst_debug_thread_uid;
+ int get_ptx_inst_debug_to_file() const { return g_ptx_inst_debug_to_file; }
+ const char *get_ptx_inst_debug_file() const { return g_ptx_inst_debug_file; }
+ int get_ptx_inst_debug_thread_uid() const {
+ return g_ptx_inst_debug_thread_uid;
+ }
+ unsigned get_texcache_linesize() const { return m_texcache_linesize; }
+ int get_checkpoint_option() const { return checkpoint_option; }
+ int get_checkpoint_kernel() const { return checkpoint_kernel; }
+ int get_checkpoint_CTA() const { return checkpoint_CTA; }
+ int get_resume_option() const { return resume_option; }
+ int get_resume_kernel() const { return resume_kernel; }
+ int get_resume_CTA() const { return resume_CTA; }
+ int get_checkpoint_CTA_t() const { return checkpoint_CTA_t; }
+ int get_checkpoint_insn_Y() const { return checkpoint_insn_Y; }
- unsigned m_texcache_linesize;
-};
+ private:
+ // PTX options
+ int m_ptx_convert_to_ptxplus;
+ int m_ptx_use_cuobjdump;
+ int m_experimental_lib_support;
+ unsigned m_ptx_force_max_capability;
+ int checkpoint_option;
+ int checkpoint_kernel;
+ int checkpoint_CTA;
+ unsigned resume_option;
+ unsigned resume_kernel;
+ unsigned resume_CTA;
+ unsigned checkpoint_CTA_t;
+ int checkpoint_insn_Y;
+ int g_ptx_inst_debug_to_file;
+ char *g_ptx_inst_debug_file;
+ int g_ptx_inst_debug_thread_uid;
+ unsigned m_texcache_linesize;
+};
class gpgpu_t {
-public:
- gpgpu_t( const gpgpu_functional_sim_config &config, gpgpu_context* ctx );
- // backward pointer
- class gpgpu_context* gpgpu_ctx;
- int checkpoint_option;
- int checkpoint_kernel;
- int checkpoint_CTA;
- unsigned resume_option;
- unsigned resume_kernel;
- unsigned resume_CTA;
- unsigned checkpoint_CTA_t;
- int checkpoint_insn_Y;
+ public:
+ gpgpu_t(const gpgpu_functional_sim_config &config, gpgpu_context *ctx);
+ // backward pointer
+ class gpgpu_context *gpgpu_ctx;
+ int checkpoint_option;
+ int checkpoint_kernel;
+ int checkpoint_CTA;
+ unsigned resume_option;
+ unsigned resume_kernel;
+ unsigned resume_CTA;
+ unsigned checkpoint_CTA_t;
+ int checkpoint_insn_Y;
- //Move some cycle core stats here instead of being global
- unsigned long long gpu_sim_cycle;
- unsigned long long gpu_tot_sim_cycle;
+ // Move some cycle core stats here instead of being global
+ unsigned long long gpu_sim_cycle;
+ unsigned long long gpu_tot_sim_cycle;
+ void *gpu_malloc(size_t size);
+ void *gpu_mallocarray(size_t count);
+ void gpu_memset(size_t dst_start_addr, int c, size_t count);
+ void memcpy_to_gpu(size_t dst_start_addr, const void *src, size_t count);
+ void memcpy_from_gpu(void *dst, size_t src_start_addr, size_t count);
+ void memcpy_gpu_to_gpu(size_t dst, size_t src, size_t count);
- void* gpu_malloc( size_t size );
- void* gpu_mallocarray( size_t count );
- void gpu_memset( size_t dst_start_addr, int c, size_t count );
- void memcpy_to_gpu( size_t dst_start_addr, const void *src, size_t count );
- void memcpy_from_gpu( void *dst, size_t src_start_addr, size_t count );
- void memcpy_gpu_to_gpu( size_t dst, size_t src, size_t count );
-
- class memory_space *get_global_memory() { return m_global_mem; }
- class memory_space *get_tex_memory() { return m_tex_mem; }
- class memory_space *get_surf_memory() { return m_surf_mem; }
+ class memory_space *get_global_memory() {
+ return m_global_mem;
+ }
+ class memory_space *get_tex_memory() {
+ return m_tex_mem;
+ }
+ class memory_space *get_surf_memory() {
+ return m_surf_mem;
+ }
- void gpgpu_ptx_sim_bindTextureToArray(const struct textureReference* texref, const struct cudaArray* array);
- void gpgpu_ptx_sim_bindNameToTexture(const char* name, const struct textureReference* texref, int dim, int readmode, int ext);
- void gpgpu_ptx_sim_unbindTexture(const struct textureReference* texref);
- const char* gpgpu_ptx_sim_findNamefromTexture(const struct textureReference* texref);
+ void gpgpu_ptx_sim_bindTextureToArray(const struct textureReference *texref,
+ const struct cudaArray *array);
+ void gpgpu_ptx_sim_bindNameToTexture(const char *name,
+ const struct textureReference *texref,
+ int dim, int readmode, int ext);
+ void gpgpu_ptx_sim_unbindTexture(const struct textureReference *texref);
+ const char *gpgpu_ptx_sim_findNamefromTexture(
+ const struct textureReference *texref);
- const struct textureReference* get_texref( const std::string &texname ) const
- {
- std::map<std::string, std::set<const struct textureReference*> >::const_iterator t=m_NameToTextureRef.find(texname);
- assert( t != m_NameToTextureRef.end() );
- return *(t->second.begin());
- }
+ const struct textureReference *get_texref(const std::string &texname) const {
+ std::map<std::string,
+ std::set<const struct textureReference *> >::const_iterator t =
+ m_NameToTextureRef.find(texname);
+ assert(t != m_NameToTextureRef.end());
+ return *(t->second.begin());
+ }
- const struct cudaArray* get_texarray( const std::string &texname ) const
- {
- std::map<std::string,const struct cudaArray*>::const_iterator t=m_NameToCudaArray.find(texname);
- assert(t != m_NameToCudaArray.end());
- return t->second;
- }
+ const struct cudaArray *get_texarray(const std::string &texname) const {
+ std::map<std::string, const struct cudaArray *>::const_iterator t =
+ m_NameToCudaArray.find(texname);
+ assert(t != m_NameToCudaArray.end());
+ return t->second;
+ }
- const struct textureInfo* get_texinfo( const std::string &texname ) const
- {
- std::map<std::string, const struct textureInfo*>::const_iterator t=m_NameToTextureInfo.find(texname);
- assert(t != m_NameToTextureInfo.end());
- return t->second;
- }
+ const struct textureInfo *get_texinfo(const std::string &texname) const {
+ std::map<std::string, const struct textureInfo *>::const_iterator t =
+ m_NameToTextureInfo.find(texname);
+ assert(t != m_NameToTextureInfo.end());
+ return t->second;
+ }
- const struct textureReferenceAttr* get_texattr( const std::string &texname ) const
- {
- std::map<std::string, const struct textureReferenceAttr*>::const_iterator t=m_NameToAttribute.find(texname);
- assert(t != m_NameToAttribute.end());
- return t->second;
- }
+ const struct textureReferenceAttr *get_texattr(
+ const std::string &texname) const {
+ std::map<std::string, const struct textureReferenceAttr *>::const_iterator
+ t = m_NameToAttribute.find(texname);
+ assert(t != m_NameToAttribute.end());
+ return t->second;
+ }
- const gpgpu_functional_sim_config &get_config() const { return m_function_model_config; }
- FILE* get_ptx_inst_debug_file() { return ptx_inst_debug_file; }
-
- // These maps return the current texture mappings for the GPU at any given time.
- std::map<std::string, const struct cudaArray*> getNameArrayMapping() {return m_NameToCudaArray;}
- std::map<std::string, const struct textureInfo*> getNameInfoMapping() {return m_NameToTextureInfo;}
+ const gpgpu_functional_sim_config &get_config() const {
+ return m_function_model_config;
+ }
+ FILE *get_ptx_inst_debug_file() { return ptx_inst_debug_file; }
-protected:
- const gpgpu_functional_sim_config &m_function_model_config;
- FILE* ptx_inst_debug_file;
+ // These maps return the current texture mappings for the GPU at any given
+ // time.
+ std::map<std::string, const struct cudaArray *> getNameArrayMapping() {
+ return m_NameToCudaArray;
+ }
+ std::map<std::string, const struct textureInfo *> getNameInfoMapping() {
+ return m_NameToTextureInfo;
+ }
- class memory_space *m_global_mem;
- class memory_space *m_tex_mem;
- class memory_space *m_surf_mem;
+ protected:
+ const gpgpu_functional_sim_config &m_function_model_config;
+ FILE *ptx_inst_debug_file;
- unsigned long long m_dev_malloc;
- // These maps contain the current texture mappings for the GPU at any given time.
- std::map<std::string, std::set<const struct textureReference*> > m_NameToTextureRef;
- std::map<const struct textureReference*, std::string> m_TextureRefToName;
- std::map<std::string, const struct cudaArray*> m_NameToCudaArray;
- std::map<std::string, const struct textureInfo*> m_NameToTextureInfo;
- std::map<std::string, const struct textureReferenceAttr*> m_NameToAttribute;
-};
+ class memory_space *m_global_mem;
+ class memory_space *m_tex_mem;
+ class memory_space *m_surf_mem;
-struct gpgpu_ptx_sim_info
-{
- // Holds properties of the kernel (Kernel's resource use).
- // These will be set to zero if a ptxinfo file is not present.
- int lmem;
- int smem;
- int cmem;
- int gmem;
- int regs;
- unsigned maxthreads;
- unsigned ptx_version;
- unsigned sm_target;
+ unsigned long long m_dev_malloc;
+ // These maps contain the current texture mappings for the GPU at any given
+ // time.
+ std::map<std::string, std::set<const struct textureReference *> >
+ m_NameToTextureRef;
+ std::map<const struct textureReference *, std::string> m_TextureRefToName;
+ std::map<std::string, const struct cudaArray *> m_NameToCudaArray;
+ std::map<std::string, const struct textureInfo *> m_NameToTextureInfo;
+ std::map<std::string, const struct textureReferenceAttr *> m_NameToAttribute;
};
+struct gpgpu_ptx_sim_info {
+ // Holds properties of the kernel (Kernel's resource use).
+ // These will be set to zero if a ptxinfo file is not present.
+ int lmem;
+ int smem;
+ int cmem;
+ int gmem;
+ int regs;
+ unsigned maxthreads;
+ unsigned ptx_version;
+ unsigned sm_target;
+};
struct gpgpu_ptx_sim_arg {
- gpgpu_ptx_sim_arg() { m_start=NULL; }
- gpgpu_ptx_sim_arg(const void *arg, size_t size, size_t offset)
- {
- m_start=arg;
- m_nbytes=size;
- m_offset=offset;
- }
- const void *m_start;
- size_t m_nbytes;
- size_t m_offset;
+ gpgpu_ptx_sim_arg() { m_start = NULL; }
+ gpgpu_ptx_sim_arg(const void *arg, size_t size, size_t offset) {
+ m_start = arg;
+ m_nbytes = size;
+ m_offset = offset;
+ }
+ const void *m_start;
+ size_t m_nbytes;
+ size_t m_offset;
};
typedef std::list<gpgpu_ptx_sim_arg> gpgpu_ptx_sim_arg_list_t;
class memory_space_t {
-public:
- memory_space_t() { m_type = undefined_space; m_bank=0; }
- memory_space_t( const enum _memory_space_t &from ) { m_type = from; m_bank = 0; }
- bool operator==( const memory_space_t &x ) const { return (m_bank == x.m_bank) && (m_type == x.m_type); }
- bool operator!=( const memory_space_t &x ) const { return !(*this == x); }
- bool operator<( const memory_space_t &x ) const
- {
- if(m_type < x.m_type)
- return true;
- else if(m_type > x.m_type)
- return false;
- else if( m_bank < x.m_bank )
- return true;
+ public:
+ memory_space_t() {
+ m_type = undefined_space;
+ m_bank = 0;
+ }
+ memory_space_t(const enum _memory_space_t &from) {
+ m_type = from;
+ m_bank = 0;
+ }
+ bool operator==(const memory_space_t &x) const {
+ return (m_bank == x.m_bank) && (m_type == x.m_type);
+ }
+ bool operator!=(const memory_space_t &x) const { return !(*this == x); }
+ bool operator<(const memory_space_t &x) const {
+ if (m_type < x.m_type)
+ return true;
+ else if (m_type > x.m_type)
return false;
- }
- enum _memory_space_t get_type() const { return m_type; }
- void set_type( enum _memory_space_t t ) { m_type = t; }
- unsigned get_bank() const { return m_bank; }
- void set_bank( unsigned b ) { m_bank = b; }
- bool is_const() const { return (m_type == const_space) || (m_type == param_space_kernel); }
- bool is_local() const { return (m_type == local_space) || (m_type == param_space_local); }
- bool is_global() const { return (m_type == global_space); }
+ else if (m_bank < x.m_bank)
+ return true;
+ return false;
+ }
+ enum _memory_space_t get_type() const { return m_type; }
+ void set_type(enum _memory_space_t t) { m_type = t; }
+ unsigned get_bank() const { return m_bank; }
+ void set_bank(unsigned b) { m_bank = b; }
+ bool is_const() const {
+ return (m_type == const_space) || (m_type == param_space_kernel);
+ }
+ bool is_local() const {
+ return (m_type == local_space) || (m_type == param_space_local);
+ }
+ bool is_global() const { return (m_type == global_space); }
-private:
- enum _memory_space_t m_type;
- unsigned m_bank; // n in ".const[n]"; note .const == .const[0] (see PTX 2.1 manual, sec. 5.1.3)
+ private:
+ enum _memory_space_t m_type;
+ unsigned m_bank; // n in ".const[n]"; note .const == .const[0] (see PTX 2.1
+ // manual, sec. 5.1.3)
};
const unsigned MAX_MEMORY_ACCESS_SIZE = 128;
typedef std::bitset<MAX_MEMORY_ACCESS_SIZE> mem_access_byte_mask_t;
-const unsigned SECTOR_CHUNCK_SIZE = 4; //four sectors
-const unsigned SECTOR_SIZE = 32 ; //sector is 32 bytes width
+const unsigned SECTOR_CHUNCK_SIZE = 4; // four sectors
+const unsigned SECTOR_SIZE = 32; // sector is 32 bytes width
typedef std::bitset<SECTOR_CHUNCK_SIZE> mem_access_sector_mask_t;
#define NO_PARTIAL_WRITE (mem_access_byte_mask_t())
-#define MEM_ACCESS_TYPE_TUP_DEF \
-MA_TUP_BEGIN( mem_access_type ) \
- MA_TUP( GLOBAL_ACC_R ), \
- MA_TUP( LOCAL_ACC_R ), \
- MA_TUP( CONST_ACC_R ), \
- MA_TUP( TEXTURE_ACC_R ), \
- MA_TUP( GLOBAL_ACC_W ), \
- MA_TUP( LOCAL_ACC_W ), \
- MA_TUP( L1_WRBK_ACC ), \
- MA_TUP( L2_WRBK_ACC ), \
- MA_TUP( INST_ACC_R ), \
- MA_TUP( L1_WR_ALLOC_R ), \
- MA_TUP( L2_WR_ALLOC_R ), \
- MA_TUP( NUM_MEM_ACCESS_TYPE ) \
-MA_TUP_END( mem_access_type )
+#define MEM_ACCESS_TYPE_TUP_DEF \
+ MA_TUP_BEGIN(mem_access_type) \
+ MA_TUP(GLOBAL_ACC_R), MA_TUP(LOCAL_ACC_R), MA_TUP(CONST_ACC_R), \
+ MA_TUP(TEXTURE_ACC_R), MA_TUP(GLOBAL_ACC_W), MA_TUP(LOCAL_ACC_W), \
+ MA_TUP(L1_WRBK_ACC), MA_TUP(L2_WRBK_ACC), MA_TUP(INST_ACC_R), \
+ MA_TUP(L1_WR_ALLOC_R), MA_TUP(L2_WR_ALLOC_R), \
+ MA_TUP(NUM_MEM_ACCESS_TYPE) MA_TUP_END(mem_access_type)
#define MA_TUP_BEGIN(X) enum X {
#define MA_TUP(X) X
-#define MA_TUP_END(X) };
+#define MA_TUP_END(X) \
+ } \
+ ;
MEM_ACCESS_TYPE_TUP_DEF
#undef MA_TUP_BEGIN
#undef MA_TUP
#undef MA_TUP_END
-const char * mem_access_type_str(enum mem_access_type access_type);
+const char *mem_access_type_str(enum mem_access_type access_type);
enum cache_operator_type {
- CACHE_UNDEFINED,
+ CACHE_UNDEFINED,
+
+ // loads
+ CACHE_ALL, // .ca
+ CACHE_LAST_USE, // .lu
+ CACHE_VOLATILE, // .cv
+ CACHE_L1, // .nc
- // loads
- CACHE_ALL, // .ca
- CACHE_LAST_USE, // .lu
- CACHE_VOLATILE, // .cv
- CACHE_L1, // .nc
-
- // loads and stores
- CACHE_STREAMING, // .cs
- CACHE_GLOBAL, // .cg
+ // loads and stores
+ CACHE_STREAMING, // .cs
+ CACHE_GLOBAL, // .cg
- // stores
- CACHE_WRITE_BACK, // .wb
- CACHE_WRITE_THROUGH // .wt
+ // stores
+ CACHE_WRITE_BACK, // .wb
+ CACHE_WRITE_THROUGH // .wt
};
class mem_access_t {
-public:
- mem_access_t(gpgpu_context* ctx) { init(ctx); }
- mem_access_t( mem_access_type type,
- new_addr_type address,
- unsigned size,
- bool wr,
- gpgpu_context* ctx)
- {
- init(ctx);
- m_type = type;
- m_addr = address;
- m_req_size = size;
- m_write = wr;
- }
- mem_access_t( mem_access_type type,
- new_addr_type address,
- unsigned size,
- bool wr,
- const active_mask_t &active_mask,
- const mem_access_byte_mask_t &byte_mask,
- const mem_access_sector_mask_t &sector_mask,
- gpgpu_context* ctx)
- : m_warp_mask(active_mask), m_byte_mask(byte_mask), m_sector_mask(sector_mask)
- {
- init(ctx);
- m_type = type;
- m_addr = address;
- m_req_size = size;
- m_write = wr;
- }
+ public:
+ mem_access_t(gpgpu_context *ctx) { init(ctx); }
+ mem_access_t(mem_access_type type, new_addr_type address, unsigned size,
+ bool wr, gpgpu_context *ctx) {
+ init(ctx);
+ m_type = type;
+ m_addr = address;
+ m_req_size = size;
+ m_write = wr;
+ }
+ mem_access_t(mem_access_type type, new_addr_type address, unsigned size,
+ bool wr, const active_mask_t &active_mask,
+ const mem_access_byte_mask_t &byte_mask,
+ const mem_access_sector_mask_t &sector_mask, gpgpu_context *ctx)
+ : m_warp_mask(active_mask),
+ m_byte_mask(byte_mask),
+ m_sector_mask(sector_mask) {
+ init(ctx);
+ m_type = type;
+ m_addr = address;
+ m_req_size = size;
+ m_write = wr;
+ }
- new_addr_type get_addr() const { return m_addr; }
- void set_addr(new_addr_type addr) {m_addr=addr;}
- unsigned get_size() const { return m_req_size; }
- const active_mask_t &get_warp_mask() const { return m_warp_mask; }
- bool is_write() const { return m_write; }
- enum mem_access_type get_type() const { return m_type; }
- mem_access_byte_mask_t get_byte_mask() const { return m_byte_mask; }
- mem_access_sector_mask_t get_sector_mask() const { return m_sector_mask; }
+ new_addr_type get_addr() const { return m_addr; }
+ void set_addr(new_addr_type addr) { m_addr = addr; }
+ unsigned get_size() const { return m_req_size; }
+ const active_mask_t &get_warp_mask() const { return m_warp_mask; }
+ bool is_write() const { return m_write; }
+ enum mem_access_type get_type() const { return m_type; }
+ mem_access_byte_mask_t get_byte_mask() const { return m_byte_mask; }
+ mem_access_sector_mask_t get_sector_mask() const { return m_sector_mask; }
+
+ void print(FILE *fp) const {
+ fprintf(fp, "addr=0x%llx, %s, size=%u, ", m_addr,
+ m_write ? "store" : "load ", m_req_size);
+ switch (m_type) {
+ case GLOBAL_ACC_R:
+ fprintf(fp, "GLOBAL_R");
+ break;
+ case LOCAL_ACC_R:
+ fprintf(fp, "LOCAL_R ");
+ break;
+ case CONST_ACC_R:
+ fprintf(fp, "CONST ");
+ break;
+ case TEXTURE_ACC_R:
+ fprintf(fp, "TEXTURE ");
+ break;
+ case GLOBAL_ACC_W:
+ fprintf(fp, "GLOBAL_W");
+ break;
+ case LOCAL_ACC_W:
+ fprintf(fp, "LOCAL_W ");
+ break;
+ case L2_WRBK_ACC:
+ fprintf(fp, "L2_WRBK ");
+ break;
+ case INST_ACC_R:
+ fprintf(fp, "INST ");
+ break;
+ case L1_WRBK_ACC:
+ fprintf(fp, "L1_WRBK ");
+ break;
+ default:
+ fprintf(fp, "unknown ");
+ break;
+ }
+ }
- void print(FILE *fp) const
- {
- fprintf(fp,"addr=0x%llx, %s, size=%u, ", m_addr, m_write?"store":"load ", m_req_size );
- switch(m_type) {
- case GLOBAL_ACC_R: fprintf(fp,"GLOBAL_R"); break;
- case LOCAL_ACC_R: fprintf(fp,"LOCAL_R "); break;
- case CONST_ACC_R: fprintf(fp,"CONST "); break;
- case TEXTURE_ACC_R: fprintf(fp,"TEXTURE "); break;
- case GLOBAL_ACC_W: fprintf(fp,"GLOBAL_W"); break;
- case LOCAL_ACC_W: fprintf(fp,"LOCAL_W "); break;
- case L2_WRBK_ACC: fprintf(fp,"L2_WRBK "); break;
- case INST_ACC_R: fprintf(fp,"INST "); break;
- case L1_WRBK_ACC: fprintf(fp,"L1_WRBK "); break;
- default: fprintf(fp,"unknown "); break;
- }
- }
+ gpgpu_context *gpgpu_ctx;
- gpgpu_context* gpgpu_ctx;
-private:
- void init(gpgpu_context* ctx);
+ private:
+ void init(gpgpu_context *ctx);
- unsigned m_uid;
- new_addr_type m_addr; // request address
- bool m_write;
- unsigned m_req_size; // bytes
- mem_access_type m_type;
- active_mask_t m_warp_mask;
- mem_access_byte_mask_t m_byte_mask;
- mem_access_sector_mask_t m_sector_mask;
+ unsigned m_uid;
+ new_addr_type m_addr; // request address
+ bool m_write;
+ unsigned m_req_size; // bytes
+ mem_access_type m_type;
+ active_mask_t m_warp_mask;
+ mem_access_byte_mask_t m_byte_mask;
+ mem_access_sector_mask_t m_sector_mask;
};
class mem_fetch;
class mem_fetch_interface {
-public:
- virtual bool full( unsigned size, bool write ) const = 0;
- virtual void push( mem_fetch *mf ) = 0;
+ public:
+ virtual bool full(unsigned size, bool write) const = 0;
+ virtual void push(mem_fetch *mf) = 0;
};
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;
- virtual mem_fetch *alloc( const class warp_inst_t &inst, const mem_access_t &access, unsigned long long cycle ) const = 0;
+ public:
+ virtual mem_fetch *alloc(new_addr_type addr, mem_access_type type,
+ unsigned size, bool wr,
+ unsigned long long cycle) const = 0;
+ virtual mem_fetch *alloc(const class warp_inst_t &inst,
+ const mem_access_t &access,
+ unsigned long long cycle) const = 0;
};
-// the maximum number of destination, source, or address uarch operands in a instruction
-#define MAX_REG_OPERANDS 32
+// the maximum number of destination, source, or address uarch operands in a
+// instruction
+#define MAX_REG_OPERANDS 32
struct dram_callback_t {
- dram_callback_t() { function=NULL; instruction=NULL; thread=NULL; }
- void (*function)(const class inst_t*, class ptx_thread_info*);
+ dram_callback_t() {
+ function = NULL;
+ instruction = NULL;
+ thread = NULL;
+ }
+ void (*function)(const class inst_t *, class ptx_thread_info *);
- const class inst_t* instruction;
- class ptx_thread_info *thread;
+ const class inst_t *instruction;
+ class ptx_thread_info *thread;
};
class inst_t {
-public:
- inst_t()
- {
- m_decoded=false;
- pc=(address_type)-1;
- reconvergence_pc=(address_type)-1;
- op=NO_OP;
- bar_type=NOT_BAR;
- red_type=NOT_RED;
- bar_id=(unsigned)-1;
- bar_count=(unsigned)-1;
- oprnd_type=UN_OP;
- sp_op=OTHER_OP;
- op_pipe=UNKOWN_OP;
- mem_op=NOT_TEX;
- num_operands=0;
- num_regs=0;
- memset(out, 0, sizeof(unsigned));
- memset(in, 0, sizeof(unsigned));
- is_vectorin=0;
- is_vectorout=0;
- space = memory_space_t();
- cache_op = CACHE_UNDEFINED;
- latency = 1;
- initiation_interval = 1;
- for( unsigned i=0; i < MAX_REG_OPERANDS; i++ ) {
- arch_reg.src[i] = -1;
- arch_reg.dst[i] = -1;
- }
- isize=0;
- }
- bool valid() const { return m_decoded; }
- virtual void print_insn( FILE *fp ) const
- {
- fprintf(fp," [inst @ pc=0x%04x] ", pc );
+ public:
+ inst_t() {
+ m_decoded = false;
+ pc = (address_type)-1;
+ reconvergence_pc = (address_type)-1;
+ op = NO_OP;
+ bar_type = NOT_BAR;
+ red_type = NOT_RED;
+ bar_id = (unsigned)-1;
+ bar_count = (unsigned)-1;
+ oprnd_type = UN_OP;
+ sp_op = OTHER_OP;
+ op_pipe = UNKOWN_OP;
+ mem_op = NOT_TEX;
+ num_operands = 0;
+ num_regs = 0;
+ memset(out, 0, sizeof(unsigned));
+ memset(in, 0, sizeof(unsigned));
+ is_vectorin = 0;
+ is_vectorout = 0;
+ space = memory_space_t();
+ cache_op = CACHE_UNDEFINED;
+ latency = 1;
+ initiation_interval = 1;
+ for (unsigned i = 0; i < MAX_REG_OPERANDS; i++) {
+ arch_reg.src[i] = -1;
+ arch_reg.dst[i] = -1;
}
- bool is_load() const { return (op == LOAD_OP ||op==TENSOR_CORE_LOAD_OP || memory_op == memory_load); }
- bool is_store() const { return (op == STORE_OP ||op==TENSOR_CORE_STORE_OP || memory_op == memory_store); }
- unsigned get_num_operands() const {return num_operands;}
- unsigned get_num_regs() const {return num_regs;}
- void set_num_regs(unsigned num) {num_regs=num;}
- void set_num_operands(unsigned num) {num_operands=num;}
- void set_bar_id(unsigned id) {bar_id=id;}
- void set_bar_count(unsigned count) {bar_count=count;}
+ isize = 0;
+ }
+ bool valid() const { return m_decoded; }
+ virtual void print_insn(FILE *fp) const {
+ fprintf(fp, " [inst @ pc=0x%04x] ", pc);
+ }
+ bool is_load() const {
+ return (op == LOAD_OP || op == TENSOR_CORE_LOAD_OP ||
+ memory_op == memory_load);
+ }
+ bool is_store() const {
+ return (op == STORE_OP || op == TENSOR_CORE_STORE_OP ||
+ memory_op == memory_store);
+ }
+ unsigned get_num_operands() const { return num_operands; }
+ unsigned get_num_regs() const { return num_regs; }
+ void set_num_regs(unsigned num) { num_regs = num; }
+ void set_num_operands(unsigned num) { num_operands = num; }
+ void set_bar_id(unsigned id) { bar_id = id; }
+ void set_bar_count(unsigned count) { bar_count = count; }
- address_type pc; // program counter address of instruction
- unsigned isize; // size of instruction in bytes
- op_type op; // opcode (uarch visible)
+ address_type pc; // program counter address of instruction
+ unsigned isize; // size of instruction in bytes
+ op_type op; // opcode (uarch visible)
- barrier_type bar_type;
- reduction_type red_type;
- unsigned bar_id;
- unsigned bar_count;
+ barrier_type bar_type;
+ reduction_type red_type;
+ unsigned bar_id;
+ unsigned bar_count;
- types_of_operands oprnd_type; // code (uarch visible) identify if the operation is an interger or a floating point
- special_ops sp_op; // code (uarch visible) identify if int_alu, fp_alu, int_mul ....
- 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
- _memory_op_t memory_op; // memory_op used by ptxplus
- unsigned num_operands;
- unsigned num_regs; // count vector operand as one register operand
+ types_of_operands oprnd_type; // code (uarch visible) identify if the
+ // operation is an interger or a floating point
+ special_ops
+ sp_op; // code (uarch visible) identify if int_alu, fp_alu, int_mul ....
+ 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
+ _memory_op_t memory_op; // memory_op used by ptxplus
+ unsigned num_operands;
+ unsigned num_regs; // count vector operand as one register operand
- address_type reconvergence_pc; // -1 => not a branch, -2 => use function return address
-
- unsigned out[8];
- unsigned outcount;
- unsigned in[24];
- unsigned incount;
- unsigned char is_vectorin;
- unsigned char is_vectorout;
- int pred; // predicate register number
- int ar1, ar2;
- // register number for bank conflict evaluation
- struct {
- int dst[MAX_REG_OPERANDS];
- int src[MAX_REG_OPERANDS];
- } arch_reg;
- //int arch_reg[MAX_REG_OPERANDS]; // register number for bank conflict evaluation
- unsigned latency; // operation latency
- unsigned initiation_interval;
+ address_type reconvergence_pc; // -1 => not a branch, -2 => use function
+ // return address
- unsigned data_size; // what is the size of the word being operated on?
- memory_space_t space;
- cache_operator_type cache_op;
+ unsigned out[8];
+ unsigned outcount;
+ unsigned in[24];
+ unsigned incount;
+ unsigned char is_vectorin;
+ unsigned char is_vectorout;
+ int pred; // predicate register number
+ int ar1, ar2;
+ // register number for bank conflict evaluation
+ struct {
+ int dst[MAX_REG_OPERANDS];
+ int src[MAX_REG_OPERANDS];
+ } arch_reg;
+ // int arch_reg[MAX_REG_OPERANDS]; // register number for bank conflict
+ // evaluation
+ unsigned latency; // operation latency
+ unsigned initiation_interval;
-protected:
- bool m_decoded;
- virtual void pre_decode() {}
-};
+ unsigned data_size; // what is the size of the word being operated on?
+ memory_space_t space;
+ cache_operator_type cache_op;
-enum divergence_support_t {
- POST_DOMINATOR = 1,
- NUM_SIMD_MODEL
+ protected:
+ bool m_decoded;
+ virtual void pre_decode() {}
};
+enum divergence_support_t { POST_DOMINATOR = 1, NUM_SIMD_MODEL };
+
const unsigned MAX_ACCESSES_PER_INSN_PER_THREAD = 8;
-class warp_inst_t: public inst_t {
-public:
- // constructors
- warp_inst_t()
- {
- m_uid=0;
- m_empty=true;
- m_config=NULL;
- }
- warp_inst_t( const core_config *config )
- {
- m_uid=0;
- assert(config->warp_size<=MAX_WARP_SIZE);
- m_config=config;
- m_empty=true;
- m_isatomic=false;
- m_per_scalar_thread_valid=false;
- m_mem_accesses_created=false;
- m_cache_hit=false;
- m_is_printf=false;
- m_is_cdp = 0;
- }
- virtual ~warp_inst_t(){
- }
+class warp_inst_t : public inst_t {
+ public:
+ // constructors
+ warp_inst_t() {
+ m_uid = 0;
+ m_empty = true;
+ m_config = NULL;
+ }
+ warp_inst_t(const core_config *config) {
+ m_uid = 0;
+ assert(config->warp_size <= MAX_WARP_SIZE);
+ m_config = config;
+ m_empty = true;
+ m_isatomic = false;
+ m_per_scalar_thread_valid = false;
+ m_mem_accesses_created = false;
+ m_cache_hit = false;
+ m_is_printf = false;
+ m_is_cdp = 0;
+ }
+ virtual ~warp_inst_t() {}
- // modifiers
- void broadcast_barrier_reduction( const active_mask_t& access_mask);
- void do_atomic(bool forceDo=false);
- void do_atomic( const active_mask_t& access_mask, bool forceDo=false );
- void clear()
- {
- m_empty=true;
- }
+ // modifiers
+ void broadcast_barrier_reduction(const active_mask_t &access_mask);
+ void do_atomic(bool forceDo = false);
+ void do_atomic(const active_mask_t &access_mask, bool forceDo = false);
+ 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 );
+ void issue(const active_mask_t &mask, unsigned warp_id,
+ unsigned long long cycle, int dynamic_warp_id, int sch_id);
- const active_mask_t & get_active_mask() const
- {
- return m_warp_active_mask;
- }
- void completed( unsigned long long cycle ) const; // stat collection: called when the instruction is completed
+ const active_mask_t &get_active_mask() const { return m_warp_active_mask; }
+ void completed(unsigned long long cycle)
+ const; // stat collection: called when the instruction is completed
- void set_addr( unsigned n, new_addr_type addr )
- {
- if( !m_per_scalar_thread_valid ) {
- m_per_scalar_thread.resize(m_config->warp_size);
- m_per_scalar_thread_valid=true;
- }
- m_per_scalar_thread[n].memreqaddr[0] = addr;
+ void set_addr(unsigned n, new_addr_type addr) {
+ if (!m_per_scalar_thread_valid) {
+ m_per_scalar_thread.resize(m_config->warp_size);
+ m_per_scalar_thread_valid = true;
}
- void set_addr( unsigned n, new_addr_type* addr, unsigned num_addrs )
- {
- if( !m_per_scalar_thread_valid ) {
- m_per_scalar_thread.resize(m_config->warp_size);
- m_per_scalar_thread_valid=true;
- }
- assert(num_addrs <= MAX_ACCESSES_PER_INSN_PER_THREAD);
- for(unsigned i=0; i<num_addrs; i++)
- m_per_scalar_thread[n].memreqaddr[i] = addr[i];
+ m_per_scalar_thread[n].memreqaddr[0] = addr;
+ }
+ void set_addr(unsigned n, new_addr_type *addr, unsigned num_addrs) {
+ if (!m_per_scalar_thread_valid) {
+ m_per_scalar_thread.resize(m_config->warp_size);
+ m_per_scalar_thread_valid = true;
}
- void print_m_accessq(){
-
- if(accessq_empty())
- return;
- else{
- printf("Printing mem access generated\n");
- std::list<mem_access_t>::iterator it;
- for (it = m_accessq.begin(); it != m_accessq.end(); ++it){
- printf("MEM_TXN_GEN:%s:%llx, Size:%d \n",mem_access_type_str(it->get_type()), it->get_addr(),it->get_size());
- }
- }
- }
- struct transaction_info {
- std::bitset<4> chunks; // bitmask: 32-byte chunks accessed
- mem_access_byte_mask_t bytes;
- active_mask_t active; // threads in this transaction
-
- bool test_bytes(unsigned start_bit, unsigned end_bit) {
- for( unsigned i=start_bit; i<=end_bit; i++ )
- if(bytes.test(i))
- return true;
- return false;
- }
- };
-
- void generate_mem_accesses();
- void memory_coalescing_arch( bool is_write, mem_access_type access_type );
- void memory_coalescing_arch_atomic( bool is_write, mem_access_type access_type );
- void memory_coalescing_arch_reduce_and_send( bool is_write, mem_access_type access_type, const transaction_info &info, new_addr_type addr, unsigned segment_size );
-
- void add_callback( unsigned lane_id,
- void (*function)(const class inst_t*, class ptx_thread_info*),
- const inst_t *inst,
- class ptx_thread_info *thread,
- bool atomic)
- {
- if( !m_per_scalar_thread_valid ) {
- m_per_scalar_thread.resize(m_config->warp_size);
- m_per_scalar_thread_valid=true;
- if(atomic) m_isatomic=true;
- }
- m_per_scalar_thread[lane_id].callback.function = function;
- m_per_scalar_thread[lane_id].callback.instruction = inst;
- m_per_scalar_thread[lane_id].callback.thread = thread;
+ assert(num_addrs <= MAX_ACCESSES_PER_INSN_PER_THREAD);
+ for (unsigned i = 0; i < num_addrs; i++)
+ m_per_scalar_thread[n].memreqaddr[i] = addr[i];
+ }
+ void print_m_accessq() {
+ if (accessq_empty())
+ return;
+ else {
+ printf("Printing mem access generated\n");
+ std::list<mem_access_t>::iterator it;
+ for (it = m_accessq.begin(); it != m_accessq.end(); ++it) {
+ printf("MEM_TXN_GEN:%s:%llx, Size:%d \n",
+ mem_access_type_str(it->get_type()), it->get_addr(),
+ it->get_size());
+ }
}
- void set_active( const active_mask_t &active );
-
- void clear_active( const active_mask_t &inactive );
- void set_not_active( unsigned lane_id );
+ }
+ struct transaction_info {
+ std::bitset<4> chunks; // bitmask: 32-byte chunks accessed
+ mem_access_byte_mask_t bytes;
+ active_mask_t active; // threads in this transaction
- // accessors
- virtual void print_insn(FILE *fp) const
- {
- fprintf(fp," [inst @ pc=0x%04x] ", pc );
- for (int i=(int)m_config->warp_size-1; i>=0; i--)
- fprintf(fp, "%c", ((m_warp_active_mask[i])?'1':'0') );
- }
- bool active( unsigned thread ) const { return m_warp_active_mask.test(thread); }
- unsigned active_count() const { return m_warp_active_mask.count(); }
- unsigned issued_count() const { assert(m_empty == false); return m_warp_issued_mask.count(); } // for instruction counting
- bool empty() const { return m_empty; }
- unsigned warp_id() const
- {
- assert( !m_empty );
- return m_warp_id;
- }
- unsigned warp_id_func() const // to be used in functional simulations only
- {
- return m_warp_id;
- }
- unsigned dynamic_warp_id() const
- {
- assert( !m_empty );
- return m_dynamic_warp_id;
- }
- bool has_callback( unsigned n ) const
- {
- return m_warp_active_mask[n] && m_per_scalar_thread_valid &&
- (m_per_scalar_thread[n].callback.function!=NULL);
- }
- new_addr_type get_addr( unsigned n ) const
- {
- assert( m_per_scalar_thread_valid );
- return m_per_scalar_thread[n].memreqaddr[0];
+ bool test_bytes(unsigned start_bit, unsigned end_bit) {
+ for (unsigned i = start_bit; i <= end_bit; i++)
+ if (bytes.test(i)) return true;
+ return false;
}
+ };
- bool isatomic() const { return m_isatomic; }
-
- unsigned warp_size() const { return m_config->warp_size; }
-
- bool accessq_empty() const { return m_accessq.empty(); }
- unsigned accessq_count() const { return m_accessq.size(); }
- const mem_access_t &accessq_back() { return m_accessq.back(); }
- void accessq_pop_back() { m_accessq.pop_back(); }
+ void generate_mem_accesses();
+ void memory_coalescing_arch(bool is_write, mem_access_type access_type);
+ void memory_coalescing_arch_atomic(bool is_write,
+ mem_access_type access_type);
+ void memory_coalescing_arch_reduce_and_send(bool is_write,
+ mem_access_type access_type,
+ const transaction_info &info,
+ new_addr_type addr,
+ unsigned segment_size);
- bool dispatch_delay()
- {
- if( cycles > 0 )
- cycles--;
- return cycles > 0;
+ void add_callback(unsigned lane_id,
+ void (*function)(const class inst_t *,
+ class ptx_thread_info *),
+ const inst_t *inst, class ptx_thread_info *thread,
+ bool atomic) {
+ if (!m_per_scalar_thread_valid) {
+ m_per_scalar_thread.resize(m_config->warp_size);
+ m_per_scalar_thread_valid = true;
+ if (atomic) m_isatomic = true;
}
+ m_per_scalar_thread[lane_id].callback.function = function;
+ m_per_scalar_thread[lane_id].callback.instruction = inst;
+ m_per_scalar_thread[lane_id].callback.thread = thread;
+ }
+ void set_active(const active_mask_t &active);
- bool has_dispatch_delay(){
- return cycles > 0;
- }
+ void clear_active(const active_mask_t &inactive);
+ void set_not_active(unsigned lane_id);
- void print( FILE *fout ) const;
- unsigned get_uid() const { return m_uid; }
- unsigned get_schd_id() const { return m_scheduler_id; }
+ // accessors
+ virtual void print_insn(FILE *fp) const {
+ fprintf(fp, " [inst @ pc=0x%04x] ", pc);
+ for (int i = (int)m_config->warp_size - 1; i >= 0; i--)
+ fprintf(fp, "%c", ((m_warp_active_mask[i]) ? '1' : '0'));
+ }
+ bool active(unsigned thread) const { return m_warp_active_mask.test(thread); }
+ unsigned active_count() const { return m_warp_active_mask.count(); }
+ unsigned issued_count() const {
+ assert(m_empty == false);
+ return m_warp_issued_mask.count();
+ } // for instruction counting
+ bool empty() const { return m_empty; }
+ unsigned warp_id() const {
+ assert(!m_empty);
+ return m_warp_id;
+ }
+ unsigned warp_id_func() const // to be used in functional simulations only
+ {
+ return m_warp_id;
+ }
+ unsigned dynamic_warp_id() const {
+ assert(!m_empty);
+ return m_dynamic_warp_id;
+ }
+ bool has_callback(unsigned n) const {
+ return m_warp_active_mask[n] && m_per_scalar_thread_valid &&
+ (m_per_scalar_thread[n].callback.function != NULL);
+ }
+ new_addr_type get_addr(unsigned n) const {
+ assert(m_per_scalar_thread_valid);
+ return m_per_scalar_thread[n].memreqaddr[0];
+ }
-protected:
+ bool isatomic() const { return m_isatomic; }
- unsigned m_uid;
- bool m_empty;
- bool m_cache_hit;
- unsigned long long issue_cycle;
- unsigned cycles; // used for implementing initiation interval delay
- bool m_isatomic;
- bool m_is_printf;
- unsigned m_warp_id;
- unsigned m_dynamic_warp_id;
- const core_config *m_config;
- active_mask_t m_warp_active_mask; // dynamic active mask for timing model (after predication)
- active_mask_t m_warp_issued_mask; // active mask at issue (prior to predication test) -- for instruction counting
+ unsigned warp_size() const { return m_config->warp_size; }
- struct per_thread_info {
- per_thread_info() {
- for(unsigned i=0; i<MAX_ACCESSES_PER_INSN_PER_THREAD; i++)
- memreqaddr[i] = 0;
- }
- dram_callback_t callback;
- new_addr_type memreqaddr[MAX_ACCESSES_PER_INSN_PER_THREAD]; // effective address, upto 8 different requests (to support 32B access in 8 chunks of 4B each)
- };
- bool m_per_scalar_thread_valid;
- std::vector<per_thread_info> m_per_scalar_thread;
- bool m_mem_accesses_created;
- std::list<mem_access_t> m_accessq;
+ bool accessq_empty() const { return m_accessq.empty(); }
+ unsigned accessq_count() const { return m_accessq.size(); }
+ const mem_access_t &accessq_back() { return m_accessq.back(); }
+ void accessq_pop_back() { m_accessq.pop_back(); }
- unsigned m_scheduler_id; //the scheduler that issues this inst
+ bool dispatch_delay() {
+ if (cycles > 0) cycles--;
+ return cycles > 0;
+ }
- //Jin: cdp support
-public:
- int m_is_cdp;
-
-};
+ bool has_dispatch_delay() { return cycles > 0; }
-void move_warp( warp_inst_t *&dst, warp_inst_t *&src );
+ void print(FILE *fout) const;
+ unsigned get_uid() const { return m_uid; }
+ unsigned get_schd_id() const { return m_scheduler_id; }
-size_t get_kernel_code_size( class function_info *entry );
-class checkpoint
-{
-public:
+ protected:
+ unsigned m_uid;
+ bool m_empty;
+ bool m_cache_hit;
+ unsigned long long issue_cycle;
+ unsigned cycles; // used for implementing initiation interval delay
+ bool m_isatomic;
+ bool m_is_printf;
+ unsigned m_warp_id;
+ unsigned m_dynamic_warp_id;
+ const core_config *m_config;
+ active_mask_t m_warp_active_mask; // dynamic active mask for timing model
+ // (after predication)
+ active_mask_t
+ m_warp_issued_mask; // active mask at issue (prior to predication test)
+ // -- for instruction counting
- checkpoint();
- ~checkpoint(){
- printf("clasfsfss destructed\n");
+ struct per_thread_info {
+ per_thread_info() {
+ for (unsigned i = 0; i < MAX_ACCESSES_PER_INSN_PER_THREAD; i++)
+ memreqaddr[i] = 0;
}
+ dram_callback_t callback;
+ new_addr_type
+ memreqaddr[MAX_ACCESSES_PER_INSN_PER_THREAD]; // effective address,
+ // upto 8 different
+ // requests (to support
+ // 32B access in 8 chunks
+ // of 4B each)
+ };
+ bool m_per_scalar_thread_valid;
+ std::vector<per_thread_info> m_per_scalar_thread;
+ bool m_mem_accesses_created;
+ std::list<mem_access_t> m_accessq;
- void load_global_mem(class memory_space *temp_mem, char * f1name);
- void store_global_mem(class memory_space *mem, char * fname , char * format);
- unsigned radnom;
+ unsigned m_scheduler_id; // the scheduler that issues this inst
+ // Jin: cdp support
+ public:
+ int m_is_cdp;
+};
+
+void move_warp(warp_inst_t *&dst, warp_inst_t *&src);
+
+size_t get_kernel_code_size(class function_info *entry);
+class checkpoint {
+ public:
+ checkpoint();
+ ~checkpoint() { printf("clasfsfss destructed\n"); }
+ void load_global_mem(class memory_space *temp_mem, char *f1name);
+ void store_global_mem(class memory_space *mem, char *fname, char *format);
+ unsigned radnom;
};
/*
- * This abstract class used as a base for functional and performance and simulation, it has basic functional simulation
- * data structures and procedures.
+ * This abstract class used as a base for functional and performance and
+ * simulation, it has basic functional simulation data structures and
+ * procedures.
*/
class core_t {
- public:
- core_t( gpgpu_sim *gpu,
- kernel_info_t *kernel,
- unsigned warp_size,
- unsigned threads_per_shader )
- : m_gpu( gpu ),
- m_kernel( kernel ),
- m_simt_stack( NULL ),
- m_thread( NULL ),
- m_warp_size( warp_size )
- {
- m_warp_count = threads_per_shader/m_warp_size;
- // Handle the case where the number of threads is not a
- // multiple of the warp size
- if ( threads_per_shader % m_warp_size != 0 ) {
- m_warp_count += 1;
- }
- assert( m_warp_count * m_warp_size > 0 );
- m_thread = ( ptx_thread_info** )
- calloc( m_warp_count * m_warp_size,
- sizeof( ptx_thread_info* ) );
- initilizeSIMTStack(m_warp_count,m_warp_size);
+ public:
+ core_t(gpgpu_sim *gpu, kernel_info_t *kernel, unsigned warp_size,
+ unsigned threads_per_shader)
+ : m_gpu(gpu),
+ m_kernel(kernel),
+ m_simt_stack(NULL),
+ m_thread(NULL),
+ m_warp_size(warp_size) {
+ m_warp_count = threads_per_shader / m_warp_size;
+ // Handle the case where the number of threads is not a
+ // multiple of the warp size
+ if (threads_per_shader % m_warp_size != 0) {
+ m_warp_count += 1;
+ }
+ assert(m_warp_count * m_warp_size > 0);
+ m_thread = (ptx_thread_info **)calloc(m_warp_count * m_warp_size,
+ sizeof(ptx_thread_info *));
+ initilizeSIMTStack(m_warp_count, m_warp_size);
- for(unsigned i=0; i<MAX_CTA_PER_SHADER; i++){
- for(unsigned j=0; j<MAX_BARRIERS_PER_CTA; j++){
- reduction_storage[i][j]=0;
- }
- }
+ for (unsigned i = 0; i < MAX_CTA_PER_SHADER; i++) {
+ for (unsigned j = 0; j < MAX_BARRIERS_PER_CTA; j++) {
+ reduction_storage[i][j] = 0;
+ }
+ }
+ }
+ virtual ~core_t() { free(m_thread); }
+ virtual void warp_exit(unsigned warp_id) = 0;
+ virtual bool warp_waiting_at_barrier(unsigned warp_id) const = 0;
+ virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t,
+ unsigned tid) = 0;
+ class gpgpu_sim *get_gpu() {
+ return m_gpu;
+ }
+ void execute_warp_inst_t(warp_inst_t &inst, unsigned warpId = (unsigned)-1);
+ bool ptx_thread_done(unsigned hw_thread_id) const;
+ void updateSIMTStack(unsigned warpId, warp_inst_t *inst);
+ void initilizeSIMTStack(unsigned warp_count, unsigned warps_size);
+ void deleteSIMTStack();
+ warp_inst_t getExecuteWarp(unsigned warpId);
+ void get_pdom_stack_top_info(unsigned warpId, unsigned *pc,
+ unsigned *rpc) const;
+ kernel_info_t *get_kernel_info() { return m_kernel; }
+ class ptx_thread_info **get_thread_info() {
+ return m_thread;
+ }
+ unsigned get_warp_size() const { return m_warp_size; }
+ void and_reduction(unsigned ctaid, unsigned barid, bool value) {
+ reduction_storage[ctaid][barid] &= value;
+ }
+ void or_reduction(unsigned ctaid, unsigned barid, bool value) {
+ reduction_storage[ctaid][barid] |= value;
+ }
+ void popc_reduction(unsigned ctaid, unsigned barid, bool value) {
+ reduction_storage[ctaid][barid] += value;
+ }
+ unsigned get_reduction_value(unsigned ctaid, unsigned barid) {
+ return reduction_storage[ctaid][barid];
+ }
- }
- virtual ~core_t() { free(m_thread); }
- virtual void warp_exit( unsigned warp_id ) = 0;
- virtual bool warp_waiting_at_barrier( unsigned warp_id ) const = 0;
- virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid)=0;
- class gpgpu_sim * get_gpu() {return m_gpu;}
- void execute_warp_inst_t(warp_inst_t &inst, unsigned warpId =(unsigned)-1);
- bool ptx_thread_done( unsigned hw_thread_id ) const ;
- void updateSIMTStack(unsigned warpId, warp_inst_t * inst);
- void initilizeSIMTStack(unsigned warp_count, unsigned warps_size);
- void deleteSIMTStack();
- warp_inst_t getExecuteWarp(unsigned warpId);
- void get_pdom_stack_top_info( unsigned warpId, unsigned *pc, unsigned *rpc ) const;
- kernel_info_t * get_kernel_info(){ return m_kernel;}
- class ptx_thread_info ** get_thread_info() { return m_thread; }
- unsigned get_warp_size() const { return m_warp_size; }
- void and_reduction(unsigned ctaid, unsigned barid, bool value) { reduction_storage[ctaid][barid] &= value; }
- void or_reduction(unsigned ctaid, unsigned barid, bool value) { reduction_storage[ctaid][barid] |= value; }
- void popc_reduction(unsigned ctaid, unsigned barid, bool value) { reduction_storage[ctaid][barid] += value;}
- unsigned get_reduction_value(unsigned ctaid, unsigned barid) {return reduction_storage[ctaid][barid];}
- protected:
- class gpgpu_sim *m_gpu;
- kernel_info_t *m_kernel;
- simt_stack **m_simt_stack; // pdom based reconvergence context for each warp
- class ptx_thread_info ** m_thread;
- unsigned m_warp_size;
- unsigned m_warp_count;
- unsigned reduction_storage[MAX_CTA_PER_SHADER][MAX_BARRIERS_PER_CTA];
+ protected:
+ class gpgpu_sim *m_gpu;
+ kernel_info_t *m_kernel;
+ simt_stack **m_simt_stack; // pdom based reconvergence context for each warp
+ class ptx_thread_info **m_thread;
+ unsigned m_warp_size;
+ unsigned m_warp_count;
+ unsigned reduction_storage[MAX_CTA_PER_SHADER][MAX_BARRIERS_PER_CTA];
};
-
-//register that can hold multiple instructions.
+// register that can hold multiple instructions.
class register_set {
-public:
- register_set(unsigned num, const char* name){
- for( unsigned i = 0; i < num; i++ ) {
- regs.push_back(new warp_inst_t());
- }
- m_name = name;
- }
- bool has_free(){
- for( unsigned i = 0; i < regs.size(); i++ ) {
- if( regs[i]->empty() ) {
- return true;
- }
- }
- return false;
- }
- bool has_free(bool sub_core_model, unsigned reg_id){
- //in subcore model, each sched has a one specific reg to use (based on sched id)
- if(!sub_core_model)
- return has_free();
+ public:
+ register_set(unsigned num, const char *name) {
+ for (unsigned i = 0; i < num; i++) {
+ regs.push_back(new warp_inst_t());
+ }
+ m_name = name;
+ }
+ bool has_free() {
+ for (unsigned i = 0; i < regs.size(); i++) {
+ if (regs[i]->empty()) {
+ return true;
+ }
+ }
+ return false;
+ }
+ bool has_free(bool sub_core_model, unsigned reg_id) {
+ // in subcore model, each sched has a one specific reg to use (based on
+ // sched id)
+ if (!sub_core_model) return has_free();
- assert(reg_id < regs.size());
- return regs[reg_id]->empty();
- }
- bool has_ready(){
- for( unsigned i = 0; i < regs.size(); i++ ) {
- if( not regs[i]->empty() ) {
- return true;
- }
- }
- return false;
- }
+ assert(reg_id < regs.size());
+ return regs[reg_id]->empty();
+ }
+ bool has_ready() {
+ for (unsigned i = 0; i < regs.size(); i++) {
+ if (not regs[i]->empty()) {
+ return true;
+ }
+ }
+ return false;
+ }
- void move_in( warp_inst_t *&src ){
- warp_inst_t** free = get_free();
- move_warp(*free, src);
- }
- //void copy_in( warp_inst_t* src ){
- // src->copy_contents_to(*get_free());
- //}
- void move_out_to( warp_inst_t *&dest ){
- warp_inst_t **ready=get_ready();
- move_warp(dest, *ready);
- }
+ void move_in(warp_inst_t *&src) {
+ warp_inst_t **free = get_free();
+ move_warp(*free, src);
+ }
+ // void copy_in( warp_inst_t* src ){
+ // src->copy_contents_to(*get_free());
+ //}
+ void move_out_to(warp_inst_t *&dest) {
+ warp_inst_t **ready = get_ready();
+ move_warp(dest, *ready);
+ }
- warp_inst_t** get_ready(){
- warp_inst_t** ready;
- ready = NULL;
- for( unsigned i = 0; i < regs.size(); i++ ) {
- if( not regs[i]->empty() ) {
- if( ready and (*ready)->get_uid() < regs[i]->get_uid() ) {
- // ready is oldest
- } else {
- ready = &regs[i];
- }
- }
- }
- return ready;
- }
+ warp_inst_t **get_ready() {
+ warp_inst_t **ready;
+ ready = NULL;
+ for (unsigned i = 0; i < regs.size(); i++) {
+ if (not regs[i]->empty()) {
+ if (ready and (*ready)->get_uid() < regs[i]->get_uid()) {
+ // ready is oldest
+ } else {
+ ready = &regs[i];
+ }
+ }
+ }
+ return ready;
+ }
- void print(FILE* fp) const{
- fprintf(fp, "%s : @%p\n", m_name, this);
- for( unsigned i = 0; i < regs.size(); i++ ) {
- fprintf(fp, " ");
- regs[i]->print(fp);
- fprintf(fp, "\n");
- }
- }
+ void print(FILE *fp) const {
+ fprintf(fp, "%s : @%p\n", m_name, this);
+ for (unsigned i = 0; i < regs.size(); i++) {
+ fprintf(fp, " ");
+ regs[i]->print(fp);
+ fprintf(fp, "\n");
+ }
+ }
- warp_inst_t ** get_free(){
- for( unsigned i = 0; i < regs.size(); i++ ) {
- if( regs[i]->empty() ) {
- return &regs[i];
- }
- }
- assert(0 && "No free registers found");
- return NULL;
- }
+ warp_inst_t **get_free() {
+ for (unsigned i = 0; i < regs.size(); i++) {
+ if (regs[i]->empty()) {
+ return &regs[i];
+ }
+ }
+ assert(0 && "No free registers found");
+ return NULL;
+ }
- warp_inst_t ** get_free(bool sub_core_model, unsigned reg_id){
- //in subcore model, each sched has a one specific reg to use (based on sched id)
- if(!sub_core_model)
- return get_free();
+ warp_inst_t **get_free(bool sub_core_model, unsigned reg_id) {
+ // in subcore model, each sched has a one specific reg to use (based on
+ // sched id)
+ if (!sub_core_model) return get_free();
- assert(reg_id < regs.size());
- if( regs[reg_id]->empty() ) {
- return &regs[reg_id];
- }
- assert(0 && "No free register found");
- return NULL;
- }
+ assert(reg_id < regs.size());
+ if (regs[reg_id]->empty()) {
+ return &regs[reg_id];
+ }
+ assert(0 && "No free register found");
+ return NULL;
+ }
- unsigned get_size(){
- return regs.size();
- }
+ unsigned get_size() { return regs.size(); }
-private:
- std::vector<warp_inst_t*> regs;
- const char* m_name;
+ private:
+ std::vector<warp_inst_t *> regs;
+ const char *m_name;
};
-#endif // #ifdef __cplusplus
+#endif // #ifdef __cplusplus
-#endif // #ifndef ABSTRACT_HARDWARE_MODEL_INCLUDED
+#endif // #ifndef ABSTRACT_HARDWARE_MODEL_INCLUDED