summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMahmoud <[email protected]>2017-07-17 22:32:30 -0400
committerMahmoud <[email protected]>2017-07-17 22:32:30 -0400
commitdcf7e6a8445a5d8e4383add44ca6f5d0d198ab02 (patch)
tree3a9e1b89918feead2cf00d4a56cfa58b40e5b383
parenta3120435ca0e2d51bc06278ee242e9fb850b7076 (diff)
Improving GPU core model. This commits contains:
1- round robin inst issue for warp multiple schedulers 2- add sector mask in the memory request (to bused later for L2 sector cache) 3- Adding Fermi coalescer 4- Ensure different exen units are used in dual_issue mode 5- Report how many dual_issue happened 6- Adding oldest_first scheduler
-rw-r--r--src/abstract_hardware_model.cc54
-rw-r--r--src/abstract_hardware_model.h18
-rw-r--r--src/gpgpu-sim/gpu-cache.cc3
-rw-r--r--src/gpgpu-sim/gpu-sim.cc20
-rw-r--r--src/gpgpu-sim/gpu-sim.h2
-rw-r--r--src/gpgpu-sim/mem_fetch.h1
-rw-r--r--src/gpgpu-sim/shader.cc73
-rw-r--r--src/gpgpu-sim/shader.h36
8 files changed, 173 insertions, 34 deletions
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index fe6f8ab..f75c525 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -314,12 +314,12 @@ void warp_inst_t::generate_mem_accesses()
break;
case global_space: case local_space: case param_space_local:
- if( m_config->gpgpu_coalesce_arch == 13 ) {
- if(isatomic())
- memory_coalescing_arch_13_atomic(is_write, access_type);
- else
- memory_coalescing_arch_13(is_write, access_type);
- } else abort();
+ if( m_config->gpgpu_coalesce_arch == 13 || m_config->gpgpu_coalesce_arch == 20) {
+ if(isatomic())
+ memory_coalescing_arch_atomic(is_write, access_type);
+ else
+ memory_coalescing_arch(is_write, access_type);
+ } else abort();
break;
@@ -343,7 +343,7 @@ void warp_inst_t::generate_mem_accesses()
byte_mask.set(idx+i);
}
for( a=accesses.begin(); a != accesses.end(); ++a )
- m_accessq.push_back( mem_access_t(access_type,a->first,cache_block_size,is_write,a->second,byte_mask) );
+ m_accessq.push_back( mem_access_t(access_type,a->first,cache_block_size,is_write,a->second, byte_mask, mem_access_sector_mask_t()));
}
if ( space.get_type() == global_space ) {
@@ -352,11 +352,37 @@ void warp_inst_t::generate_mem_accesses()
m_mem_accesses_created=true;
}
-void warp_inst_t::memory_coalescing_arch_13( bool is_write, mem_access_type access_type )
+void warp_inst_t::memory_coalescing_arch( bool is_write, mem_access_type access_type )
{
// see the CUDA manual where it discusses coalescing rules before reading this
unsigned segment_size = 0;
- unsigned warp_parts = m_config->mem_warp_parts;
+ unsigned warp_parts;
+
+ //TO DO: need to double check how double number are coalesced!
+ if(data_size == 1)
+ {
+ //If it is byte data, then coalesce on the whole 32 threads, regardless the arch version
+ warp_parts = 1;
+ }
+ else if(m_config->gpgpu_coalesce_arch == 13)
+ {
+ //mem_warp_parts should equal 2 for arch=13
+ //we still use the parameter mem_warp_parts for arch=13 to ensure it is backward compatibility with older gpgpu config files
+ warp_parts = m_config->mem_warp_parts;
+ }
+ else if(m_config->gpgpu_coalesce_arch == 20)
+ {
+ //It is expected that L1_warp_parts_non_cached = 4 and L1_warp_parts_cached = 1 for arch=20
+ //non cached, coalesce on 8 threads to generate 32 bytes accesses
+ //cached, coalesce on 32 threads to generate 128 bytes accesses
+ if(m_config->gmem_skip_L1D || cache_op == CACHE_GLOBAL)
+ warp_parts = m_config->L1_warp_parts_non_cached;
+ else
+ warp_parts = m_config->L1_warp_parts_cached;
+ }
+ else
+ abort();
+
switch( data_size ) {
case 1: segment_size = 32; break;
case 2: segment_size = 64; break;
@@ -410,13 +436,13 @@ void warp_inst_t::memory_coalescing_arch_13( bool is_write, mem_access_type acce
new_addr_type addr = t->first;
const transaction_info &info = t->second;
- memory_coalescing_arch_13_reduce_and_send(is_write, access_type, info, addr, segment_size);
+ memory_coalescing_arch_reduce_and_send(is_write, access_type, info, addr, segment_size);
}
}
}
-void warp_inst_t::memory_coalescing_arch_13_atomic( bool is_write, mem_access_type access_type )
+void warp_inst_t::memory_coalescing_arch_atomic( bool is_write, mem_access_type access_type )
{
assert(space.get_type() == global_space); // Atomics allowed only for global memory
@@ -485,13 +511,13 @@ void warp_inst_t::memory_coalescing_arch_13_atomic( bool is_write, mem_access_ty
for(t=transaction_list.begin(); t!=transaction_list.end(); t++) {
// For each transaction
const transaction_info &info = *t;
- memory_coalescing_arch_13_reduce_and_send(is_write, access_type, info, addr, segment_size);
+ memory_coalescing_arch_reduce_and_send(is_write, access_type, info, addr, segment_size);
}
}
}
}
-void warp_inst_t::memory_coalescing_arch_13_reduce_and_send( bool is_write, mem_access_type access_type, const transaction_info &info, new_addr_type addr, unsigned segment_size )
+void warp_inst_t::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 )
{
assert( (addr & (segment_size-1)) == 0 );
@@ -540,7 +566,7 @@ void warp_inst_t::memory_coalescing_arch_13_reduce_and_send( bool is_write, mem_
assert(lower_half_used && upper_half_used);
}
}
- m_accessq.push_back( mem_access_t(access_type,addr,size,is_write,info.active,info.bytes) );
+ m_accessq.push_back( mem_access_t(access_type,addr,size,is_write,info.active,info.bytes, info.chunks) );
}
void warp_inst_t::completed( unsigned long long cycle ) const
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index aaa4b00..cd185a1 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -332,12 +332,15 @@ struct core_config {
unsigned gpgpu_shmem_sizeDefault;
unsigned gpgpu_shmem_sizePrefL1;
unsigned gpgpu_shmem_sizePrefShared;
+ unsigned L1_warp_parts_cached;
+ unsigned L1_warp_parts_non_cached;
// 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
};
// bounded stack that implements simt reconvergence using pdom mechanism from MICRO'07 paper
@@ -615,6 +618,8 @@ private:
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;
+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 \
@@ -679,8 +684,9 @@ public:
unsigned size,
bool wr,
const active_mask_t &active_mask,
- const mem_access_byte_mask_t &byte_mask )
- : m_warp_mask(active_mask), m_byte_mask(byte_mask)
+ const mem_access_byte_mask_t &byte_mask,
+ const mem_access_sector_mask_t &sector_mask)
+ : m_warp_mask(active_mask), m_byte_mask(byte_mask), m_sector_mask(sector_mask)
{
init();
m_type = type;
@@ -696,6 +702,7 @@ public:
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
{
@@ -729,6 +736,7 @@ private:
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;
static unsigned sm_next_access_uid;
};
@@ -938,9 +946,9 @@ public:
};
void generate_mem_accesses();
- void memory_coalescing_arch_13( bool is_write, mem_access_type access_type );
- void memory_coalescing_arch_13_atomic( bool is_write, mem_access_type access_type );
- void memory_coalescing_arch_13_reduce_and_send( bool is_write, mem_access_type access_type, const transaction_info &info, new_addr_type addr, unsigned segment_size );
+ 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*),
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc
index 5ea4190..cfd0dc8 100644
--- a/src/gpgpu-sim/gpu-cache.cc
+++ b/src/gpgpu-sim/gpu-cache.cc
@@ -867,7 +867,8 @@ data_cache::wr_miss_wa( new_addr_type addr,
mf->get_data_size(),
false, // Now performing a read
mf->get_access_warp_mask(),
- mf->get_access_byte_mask() );
+ mf->get_access_byte_mask(),
+ mf->get_access_sector_mask());
mem_fetch *n_mf = new mem_fetch( *ma,
NULL,
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index 58a5d16..26432c4 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -285,6 +285,15 @@ void shader_core_config::reg_options(class OptionParser * opp)
option_parser_register(opp, "-gpgpu_shmem_warp_parts", OPT_INT32, &mem_warp_parts,
"Number of portions a warp is divided into for shared memory bank conflict check ",
"2");
+ option_parser_register(opp, "-gpgpu_L1_warp_parts_cached", OPT_INT32, &L1_warp_parts_cached,
+ "Number of portions a warp is divided into when the request is cached",
+ "2");
+ option_parser_register(opp, "-gpgpu_L1_warp_parts_cached", OPT_INT32, &L1_warp_parts_non_cached,
+ "Number of portions a warp is divided into when the request is not cached",
+ "4");
+ option_parser_register(opp, "-gpgpu_shmem_warp_parts", OPT_INT32, &mem_warp_parts,
+ "Number of portions a warp is divided into for shared memory bank conflict check ",
+ "2");
option_parser_register(opp, "-gpgpu_warpdistro_shader", OPT_INT32, &gpgpu_warpdistro_shader,
"Specify which shader core to collect the warp size distribution from",
"-1");
@@ -293,7 +302,7 @@ void shader_core_config::reg_options(class OptionParser * opp)
"0");
option_parser_register(opp, "-gpgpu_local_mem_map", OPT_BOOL, &gpgpu_local_mem_map,
"Mapping from local memory space address to simulated GPU physical address space (default = enabled)",
- "1");
+ "1");
option_parser_register(opp, "-gpgpu_num_reg_banks", OPT_INT32, &gpgpu_num_reg_banks,
"Number of register banks (default = 8)",
"8");
@@ -337,14 +346,17 @@ void shader_core_config::reg_options(class OptionParser * opp)
"number of collector unit in ports (default = 0)",
"0");
option_parser_register(opp, "-gpgpu_coalesce_arch", OPT_INT32, &gpgpu_coalesce_arch,
- "Coalescing arch (default = 13, anything else is off for now)",
+ "Coalescing arch (GT200 = 13, Fermi = 20)",
"13");
option_parser_register(opp, "-gpgpu_num_sched_per_core", OPT_INT32, &gpgpu_num_sched_per_core,
"Number of warp schedulers per core",
"1");
option_parser_register(opp, "-gpgpu_max_insn_issue_per_warp", OPT_INT32, &gpgpu_max_insn_issue_per_warp,
- "Max number of instructions that can be issued per warp in one cycle by scheduler",
- "2");
+ "Max number of instructions that can be issued per warp in one cycle by scheduler (either 1 or 2)",
+ "2");
+ option_parser_register(opp, "-gpgpu_dual_issue_diff_exec_units", OPT_BOOL, &gpgpu_dual_issue_diff_exec_units,
+ "should dual issue use two different execution unit resources",
+ "1");
option_parser_register(opp, "-gpgpu_simt_core_sim_order", OPT_INT32, &simt_core_sim_order,
"Select the simulation order of cores in a cluster (0=Fix, 1=Round-Robin)",
"1");
diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h
index 7d92c66..23e6144 100644
--- a/src/gpgpu-sim/gpu-sim.h
+++ b/src/gpgpu-sim/gpu-sim.h
@@ -314,6 +314,8 @@ public:
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; }
+ unsigned get_gpu_max_cycle_opt() const { return gpu_max_cycle_opt; }
+ unsigned get_gpu_max_insn_opt() const { return gpu_max_insn_opt; }
private:
void init_clock_domains(void );
diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h
index c89edbb..db4a8e9 100644
--- a/src/gpgpu-sim/mem_fetch.h
+++ b/src/gpgpu-sim/mem_fetch.h
@@ -104,6 +104,7 @@ public:
enum mem_access_type get_access_type() const { return m_access.get_type(); }
const active_mask_t& get_access_warp_mask() const { return m_access.get_warp_mask(); }
mem_access_byte_mask_t get_access_byte_mask() const { return m_access.get_byte_mask(); }
+ mem_access_sector_mask_t get_access_sector_mask() const { return m_access.get_sector_mask(); }
address_type get_pc() const { return m_inst.empty()?-1:m_inst.pc; }
const warp_inst_t &get_inst() { return m_inst; }
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index d17e51d..015995e 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -81,6 +81,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
m_memory_config = mem_config;
m_stats = stats;
unsigned warp_size=config->warp_size;
+ Issue_Prio = 0;
m_sid = shader_id;
m_tpc = tpc_id;
@@ -131,6 +132,8 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
CONCRETE_SCHEDULER_TWO_LEVEL_ACTIVE :
sched_config.find("gto") != std::string::npos ?
CONCRETE_SCHEDULER_GTO :
+ 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;
@@ -182,6 +185,20 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
)
);
break;
+ case CONCRETE_SCHEDULER_OLDEST_FIRST:
+ schedulers.push_back(
+ new oldest_scheduler( m_stats,
+ this,
+ m_scoreboard,
+ m_simt_stack,
+ &m_warp,
+ &m_pipeline_reg[ID_OC_SP],
+ &m_pipeline_reg[ID_OC_SFU],
+ &m_pipeline_reg[ID_OC_MEM],
+ i
+ )
+ );
+ break;
case CONCRETE_SCHEDULER_WARP_LIMITING:
schedulers.push_back(
new swl_scheduler( m_stats,
@@ -465,6 +482,14 @@ void shader_core_stats::print( FILE* fout ) const
for (unsigned i = 3; i < m_config->warp_size + 3; i++)
fprintf(fout, "\tW%d:%d", i-2, shader_cycle_distro[i]);
fprintf(fout, "\n");
+ fprintf(fout, "single_issue_nums:");
+ for (unsigned i = 0; i < m_config->gpgpu_num_sched_per_core; i++)
+ fprintf(fout, "WS%d:%d\t", i, single_issue_nums[i]);
+ fprintf(fout, "\n");
+ fprintf(fout, "dual_issue_nums:");
+ for (unsigned i = 0; i < m_config->gpgpu_num_sched_per_core; i++)
+ fprintf(fout, "WS%d:%d\t", i, dual_issue_nums[i]);
+ fprintf(fout, "\n");
m_outgoing_traffic_stats->print(fout);
m_incoming_traffic_stats->print(fout);
@@ -724,10 +749,18 @@ void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t*
}
void shader_core_ctx::issue(){
+
+ unsigned j;
+ for (unsigned i = 0; i < schedulers.size(); i++) {
+ j = (Issue_Prio + i) % schedulers.size();
+ schedulers[j]->cycle();
+ }
+ Issue_Prio = (Issue_Prio+1)% schedulers.size();
+
//really is issue;
- for (unsigned i = 0; i < schedulers.size(); i++) {
- schedulers[i]->cycle();
- }
+ //for (unsigned i = 0; i < schedulers.size(); i++) {
+ // schedulers[i]->cycle();
+ //}
}
shd_warp_t& scheduler_unit::warp(int i){
@@ -842,7 +875,9 @@ void scheduler_unit::cycle()
unsigned warp_id = (*iter)->get_warp_id();
unsigned checked=0;
unsigned issued=0;
- unsigned max_issue = m_shader->m_config->gpgpu_max_insn_issue_per_warp;
+ exec_unit_type_t previous_issued_inst_exec_type = exec_unit_type_t::NONE;
+ unsigned max_issue = m_shader->m_config->gpgpu_max_insn_issue_per_warp;
+ bool diff_exec_units = m_shader->m_config->gpgpu_dual_issue_diff_exec_units;
while( !warp(warp_id).waiting() && !warp(warp_id).ibuffer_empty() && (checked < max_issue) && (checked <= issued) && (issued < max_issue) ) {
const warp_inst_t *pI = warp(warp_id).ibuffer_next_inst();
//Jin: handle cdp latency;
@@ -875,17 +910,18 @@ void scheduler_unit::cycle()
ready_inst = true;
const active_mask_t &active_mask = m_simt_stack[warp_id]->get_active_mask();
assert( warp(warp_id).inst_in_pipeline() );
- if ( (pI->op == LOAD_OP) || (pI->op == STORE_OP) || (pI->op == MEMORY_BARRIER_OP) ) {
+ if( m_mem_out->has_free() && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::MEM)) {
if( m_mem_out->has_free() ) {
m_shader->issue_warp(*m_mem_out,pI,active_mask,warp_id);
issued++;
issued_inst=true;
warp_inst_issued = true;
+ previous_issued_inst_exec_type = exec_unit_type_t::MEM;
}
} else {
bool sp_pipe_avail = m_sp_out->has_free();
bool sfu_pipe_avail = m_sfu_out->has_free();
- if( sp_pipe_avail && (pI->op != SFU_OP) ) {
+ if( sp_pipe_avail && (pI->op != SFU_OP) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::SP)) {
//Jin: special for CDP api
if(pI->m_is_cdp && !warp(warp_id).m_cdp_dummy) {
@@ -910,14 +946,17 @@ void scheduler_unit::cycle()
issued++;
issued_inst=true;
warp_inst_issued = true;
- } else if ( (pI->op == SFU_OP) || (pI->op == ALU_SFU_OP) ) {
+ previous_issued_inst_exec_type = exec_unit_type_t::SP;
+ } else if ( (pI->op == SFU_OP) || (pI->op == ALU_SFU_OP) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::SFU)) {
if( sfu_pipe_avail ) {
m_shader->issue_warp(*m_sfu_out,pI,active_mask,warp_id);
issued++;
issued_inst=true;
warp_inst_issued = true;
+ previous_issued_inst_exec_type = exec_unit_type_t::SFU;
}
- } }
+ }
+ }
} else {
SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) fails scoreboard\n",
(*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id() );
@@ -952,6 +991,14 @@ void scheduler_unit::cycle()
m_last_supervised_issued = supervised_iter;
}
}
+
+ if(issued == 1)
+ m_stats->single_issue_nums[m_id]++;
+ else if(issued > 1)
+ m_stats->dual_issue_nums[m_id]++;
+ else
+ abort(); //issued should be > 0
+
break;
}
}
@@ -1009,6 +1056,16 @@ void gto_scheduler::order_warps()
scheduler_unit::sort_warps_by_oldest_dynamic_id );
}
+void oldest_scheduler::order_warps()
+{
+ order_by_priority( m_next_cycle_prioritized_warps,
+ m_supervised_warps,
+ m_last_supervised_issued,
+ m_supervised_warps.size(),
+ ORDERED_PRIORITY_FUNC_ONLY,
+ scheduler_unit::sort_warps_by_oldest_dynamic_id );
+}
+
void
two_level_active_scheduler::do_on_warp_issued( unsigned warp_id,
unsigned num_issued,
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index bdd8dbe..395c1ed 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -70,6 +70,14 @@
#define WRITE_MASK_SIZE 8
+enum exec_unit_type_t
+{
+ NONE = 0,
+ SP = 1,
+ SFU = 2,
+ MEM = 3,
+ DP = 4
+};
class thread_ctx_t {
public:
@@ -308,6 +316,7 @@ enum concrete_scheduler
CONCRETE_SCHEDULER_GTO,
CONCRETE_SCHEDULER_TWO_LEVEL_ACTIVE,
CONCRETE_SCHEDULER_WARP_LIMITING,
+ CONCRETE_SCHEDULER_OLDEST_FIRST,
NUM_CONCRETE_SCHEDULERS
};
@@ -435,6 +444,23 @@ public:
};
+class oldest_scheduler : public scheduler_unit {
+public:
+ oldest_scheduler ( shader_core_stats* stats, shader_core_ctx* shader,
+ Scoreboard* scoreboard, simt_stack** simt,
+ std::vector<shd_warp_t>* warp,
+ register_set* sp_out,
+ register_set* sfu_out,
+ register_set* mem_out,
+ int id )
+ : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, mem_out, id ){}
+ virtual ~oldest_scheduler () {}
+ virtual void order_warps ();
+ virtual void done_adding_supervised_warps() {
+ m_last_supervised_issued = m_supervised_warps.begin();
+ }
+
+};
class two_level_active_scheduler : public scheduler_unit {
public:
@@ -1294,12 +1320,11 @@ struct shader_core_config : public core_config
mutable cache_config m_L1C_config;
mutable l1d_cache_config m_L1D_config;
- bool gmem_skip_L1D; // on = global memory access always skip the L1 cache
-
bool gpgpu_dwf_reg_bankconflict;
int gpgpu_num_sched_per_core;
int gpgpu_max_insn_issue_per_warp;
+ bool gpgpu_dual_issue_diff_exec_units;
//op collector
int gpgpu_operand_collector_num_units_sp;
@@ -1401,6 +1426,8 @@ struct shader_core_stats_pod {
unsigned *last_shader_cycle_distro;
unsigned *num_warps_issuable;
unsigned gpgpu_n_stall_shd_mem;
+ unsigned* single_issue_nums;
+ unsigned* dual_issue_nums;
//memory access classification
int gpgpu_n_mem_read_local;
@@ -1469,6 +1496,8 @@ public:
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 = (unsigned*) calloc(m_config->warp_size+3, sizeof(unsigned));
+ single_issue_nums = (unsigned*) calloc(config->gpgpu_num_sched_per_core,sizeof(unsigned));
+ dual_issue_nums = (unsigned*) calloc(config->gpgpu_num_sched_per_core, sizeof(unsigned));
n_simt_to_mem = (long *)calloc(config->num_shader(), sizeof(long));
n_mem_to_simt = (long *)calloc(config->num_shader(), sizeof(long));
@@ -1830,6 +1859,9 @@ public:
//schedule
std::vector<scheduler_unit*> schedulers;
+ //issue
+ unsigned int Issue_Prio;
+
// execute
unsigned m_num_function_units;
std::vector<pipeline_stage_name_t> m_dispatch_port;