summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/tested-cfgs/SM7_TITANV/gpgpusim.config29
-rw-r--r--src/abstract_hardware_model.h20
-rw-r--r--src/gpgpu-sim/gpu-sim.cc11
-rw-r--r--src/gpgpu-sim/shader.cc161
-rw-r--r--src/gpgpu-sim/shader.h36
5 files changed, 168 insertions, 89 deletions
diff --git a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config
index 03ef5b9..2093cc0 100644
--- a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config
+++ b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config
@@ -42,9 +42,9 @@
# Pipeline widths and number of FUs
# ID_OC_SP,ID_OC_DP,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_SFU,OC_EX_MEM,EX_WB
-## Volta GV100 has 2 SP SIMD units, 2 SFU units, 2 DP units per core
+## Volta GV100 has 4 SP SIMD units, 4SFU units, 4 DP units per core
## we need to scale the number of pipeline registers to be equal to the number of SP units
--gpgpu_pipeline_widths 4,4,4,4,4,4,4,4,12
+-gpgpu_pipeline_widths 4,4,4,4,4,4,4,4,8
-gpgpu_num_sp_units 4
-gpgpu_num_sfu_units 4
-gpgpu_num_dp_units 4
@@ -72,6 +72,8 @@
# For more info, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x
# disable this mode in case of multi kernels/apps execution
-adpative_volta_cache_config 1
+# Volta unified cache has four ports
+-mem_unit_ports 4
-gpgpu_cache:dl1 S:4:128:64,L:L:s:N:L,A:256:8,16:0,32
-gpgpu_shmem_size 98304
-gmem_skip_L1D 0
@@ -96,20 +98,15 @@
# 64 KB Const
-gpgpu_const_cache:l1 N:128:64:8,L:R:f:N:L,S:2:64,4
-# enable operand collector
--gpgpu_operand_collector_num_units_sp 12
--gpgpu_operand_collector_num_units_sfu 6
--gpgpu_operand_collector_num_units_mem 8
--gpgpu_operand_collector_num_units_dp 6
--gpgpu_operand_collector_num_in_ports_sp 4
--gpgpu_operand_collector_num_out_ports_sp 4
--gpgpu_operand_collector_num_in_ports_sfu 1
--gpgpu_operand_collector_num_out_ports_sfu 1
--gpgpu_operand_collector_num_in_ports_mem 1
--gpgpu_operand_collector_num_out_ports_mem 1
--gpgpu_operand_collector_num_in_ports_dp 1
--gpgpu_operand_collector_num_out_ports_dp 1
-# two banks per scheduler
+# Volta has sub core model, in which each scheduler has its own reisiter file and EUs
+# i.e. schedulers are isolated
+-sub_core_model 1
+# disable specialized operand collectors and use generic operand collectors instead
+-enable_specialized_operand_collector 0
+-gpgpu_operand_collector_num_units_gen 8
+-gpgpu_operand_collector_num_in_ports_gen 8
+-gpgpu_operand_collector_num_out_ports_gen 8
+# volta has 8 banks, 4 schedulers, two banks per scheduler
-gpgpu_num_reg_banks 8
# shared memory bankconflict detection
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index 8333247..d0f7066 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -336,6 +336,7 @@ struct core_config {
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;
@@ -908,7 +909,7 @@ public:
{
m_empty=true;
}
- void issue( const active_mask_t &mask, unsigned warp_id, unsigned long long cycle, int dynamic_warp_id )
+ void issue( const active_mask_t &mask, unsigned warp_id, unsigned long long cycle, int dynamic_warp_id, int sch_id )
{
m_warp_active_mask = mask;
m_warp_issued_mask = mask;
@@ -919,6 +920,7 @@ public:
cycles = initiation_interval;
m_cache_hit=false;
m_empty=false;
+ m_scheduler_id=sch_id;
}
const active_mask_t & get_active_mask() const
{
@@ -1037,6 +1039,7 @@ public:
void print( FILE *fout ) const;
unsigned get_uid() const { return m_uid; }
+ unsigned get_schd_id() const { return m_scheduler_id; }
protected:
@@ -1069,6 +1072,8 @@ protected:
static unsigned sm_next_uid;
+ unsigned m_scheduler_id; //the scheduler that issues this inst
+
//Jin: cdp support
public:
int m_is_cdp;
@@ -1161,6 +1166,10 @@ public:
}
return false;
}
+ bool has_free(unsigned reg_id){
+ 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() ) {
@@ -1216,6 +1225,15 @@ public:
return NULL;
}
+ warp_inst_t ** get_free(unsigned reg_id){
+ assert(reg_id < regs.size());
+ if( regs[reg_id]->empty() ) {
+ return &regs[reg_id];
+ }
+ assert(0 && "No free register found");
+ return NULL;
+ }
+
private:
std::vector<warp_inst_t*> regs;
const char* m_name;
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index 8bbadf5..f318f7d 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -329,6 +329,9 @@ 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, "-mem_unit_ports", OPT_INT32, &mem_unit_ports,
+ "The number of memory transactions allowed per core cycle",
+ "1");
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");
@@ -347,8 +350,14 @@ void shader_core_config::reg_options(class OptionParser * opp)
option_parser_register(opp, "-gpgpu_reg_bank_use_warp_id", OPT_BOOL, &gpgpu_reg_bank_use_warp_id,
"Use warp ID in mapping registers to banks (default = off)",
"0");
+ option_parser_register(opp, "-sub_core_model", OPT_BOOL, &sub_core_model,
+ "Sub Core Volta/Pascal model (default = off)",
+ "0");
+ option_parser_register(opp, "-enable_specialized_operand_collector", OPT_BOOL, &enable_specialized_operand_collector,
+ "enable_specialized_operand_collector",
+ "1");
option_parser_register(opp, "-gpgpu_operand_collector_num_units_sp", OPT_INT32, &gpgpu_operand_collector_num_units_sp,
- "number of collector units (default = 4)",
+ "number of collector units (default = 4)",
"4");
option_parser_register(opp, "-gpgpu_operand_collector_num_units_dp", OPT_INT32, &gpgpu_operand_collector_num_units_dp,
"number of collector units (default = 0)",
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 8a84970..300871e 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -234,52 +234,12 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
//op collector configuration
enum { SP_CUS, DP_CUS, SFU_CUS, MEM_CUS, GEN_CUS };
- m_operand_collector.add_cu_set(SP_CUS, m_config->gpgpu_operand_collector_num_units_sp, m_config->gpgpu_operand_collector_num_out_ports_sp);
- m_operand_collector.add_cu_set(DP_CUS, m_config->gpgpu_operand_collector_num_units_dp, m_config->gpgpu_operand_collector_num_out_ports_dp);
- m_operand_collector.add_cu_set(SFU_CUS, m_config->gpgpu_operand_collector_num_units_sfu, m_config->gpgpu_operand_collector_num_out_ports_sfu);
- m_operand_collector.add_cu_set(MEM_CUS, m_config->gpgpu_operand_collector_num_units_mem, m_config->gpgpu_operand_collector_num_out_ports_mem);
- m_operand_collector.add_cu_set(GEN_CUS, m_config->gpgpu_operand_collector_num_units_gen, m_config->gpgpu_operand_collector_num_out_ports_gen);
-
opndcoll_rfu_t::port_vector_t in_ports;
opndcoll_rfu_t::port_vector_t out_ports;
opndcoll_rfu_t::uint_vector_t cu_sets;
- for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_sp; i++) {
- in_ports.push_back(&m_pipeline_reg[ID_OC_SP]);
- out_ports.push_back(&m_pipeline_reg[OC_EX_SP]);
- cu_sets.push_back((unsigned)SP_CUS);
- cu_sets.push_back((unsigned)GEN_CUS);
- m_operand_collector.add_port(in_ports,out_ports,cu_sets);
- in_ports.clear(),out_ports.clear(),cu_sets.clear();
- }
-
- for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_dp; i++) {
- in_ports.push_back(&m_pipeline_reg[ID_OC_DP]);
- out_ports.push_back(&m_pipeline_reg[OC_EX_DP]);
- cu_sets.push_back((unsigned)DP_CUS);
- cu_sets.push_back((unsigned)GEN_CUS);
- m_operand_collector.add_port(in_ports,out_ports,cu_sets);
- in_ports.clear(),out_ports.clear(),cu_sets.clear();
- }
- for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_sfu; i++) {
- in_ports.push_back(&m_pipeline_reg[ID_OC_SFU]);
- out_ports.push_back(&m_pipeline_reg[OC_EX_SFU]);
- cu_sets.push_back((unsigned)SFU_CUS);
- cu_sets.push_back((unsigned)GEN_CUS);
- m_operand_collector.add_port(in_ports,out_ports,cu_sets);
- in_ports.clear(),out_ports.clear(),cu_sets.clear();
- }
-
- for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_mem; i++) {
- in_ports.push_back(&m_pipeline_reg[ID_OC_MEM]);
- out_ports.push_back(&m_pipeline_reg[OC_EX_MEM]);
- cu_sets.push_back((unsigned)MEM_CUS);
- cu_sets.push_back((unsigned)GEN_CUS);
- m_operand_collector.add_port(in_ports,out_ports,cu_sets);
- in_ports.clear(),out_ports.clear(),cu_sets.clear();
- }
-
-
+ //configure generic collectors
+ m_operand_collector.add_cu_set(GEN_CUS, m_config->gpgpu_operand_collector_num_units_gen, m_config->gpgpu_operand_collector_num_out_ports_gen);
for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_gen; i++) {
in_ports.push_back(&m_pipeline_reg[ID_OC_SP]);
in_ports.push_back(&m_pipeline_reg[ID_OC_SFU]);
@@ -287,10 +247,57 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
out_ports.push_back(&m_pipeline_reg[OC_EX_SP]);
out_ports.push_back(&m_pipeline_reg[OC_EX_SFU]);
out_ports.push_back(&m_pipeline_reg[OC_EX_MEM]);
- cu_sets.push_back((unsigned)GEN_CUS);
+ if(m_config->gpgpu_num_dp_units > 0) {
+ in_ports.push_back(&m_pipeline_reg[ID_OC_DP]);
+ out_ports.push_back(&m_pipeline_reg[OC_EX_DP]);
+ }
+ cu_sets.push_back((unsigned)GEN_CUS);
m_operand_collector.add_port(in_ports,out_ports,cu_sets);
in_ports.clear(),out_ports.clear(),cu_sets.clear();
}
+
+ if(m_config->enable_specialized_operand_collector) {
+ m_operand_collector.add_cu_set(SP_CUS, m_config->gpgpu_operand_collector_num_units_sp, m_config->gpgpu_operand_collector_num_out_ports_sp);
+ m_operand_collector.add_cu_set(DP_CUS, m_config->gpgpu_operand_collector_num_units_dp, m_config->gpgpu_operand_collector_num_out_ports_dp);
+ m_operand_collector.add_cu_set(SFU_CUS, m_config->gpgpu_operand_collector_num_units_sfu, m_config->gpgpu_operand_collector_num_out_ports_sfu);
+ m_operand_collector.add_cu_set(MEM_CUS, m_config->gpgpu_operand_collector_num_units_mem, m_config->gpgpu_operand_collector_num_out_ports_mem);
+
+ for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_sp; i++) {
+ in_ports.push_back(&m_pipeline_reg[ID_OC_SP]);
+ out_ports.push_back(&m_pipeline_reg[OC_EX_SP]);
+ cu_sets.push_back((unsigned)SP_CUS);
+ cu_sets.push_back((unsigned)GEN_CUS);
+ m_operand_collector.add_port(in_ports,out_ports,cu_sets);
+ in_ports.clear(),out_ports.clear(),cu_sets.clear();
+ }
+
+ for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_dp; i++) {
+ in_ports.push_back(&m_pipeline_reg[ID_OC_DP]);
+ out_ports.push_back(&m_pipeline_reg[OC_EX_DP]);
+ cu_sets.push_back((unsigned)DP_CUS);
+ cu_sets.push_back((unsigned)GEN_CUS);
+ m_operand_collector.add_port(in_ports,out_ports,cu_sets);
+ in_ports.clear(),out_ports.clear(),cu_sets.clear();
+ }
+
+ for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_sfu; i++) {
+ in_ports.push_back(&m_pipeline_reg[ID_OC_SFU]);
+ out_ports.push_back(&m_pipeline_reg[OC_EX_SFU]);
+ cu_sets.push_back((unsigned)SFU_CUS);
+ cu_sets.push_back((unsigned)GEN_CUS);
+ m_operand_collector.add_port(in_ports,out_ports,cu_sets);
+ in_ports.clear(),out_ports.clear(),cu_sets.clear();
+ }
+
+ for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_mem; i++) {
+ in_ports.push_back(&m_pipeline_reg[ID_OC_MEM]);
+ out_ports.push_back(&m_pipeline_reg[OC_EX_MEM]);
+ cu_sets.push_back((unsigned)MEM_CUS);
+ cu_sets.push_back((unsigned)GEN_CUS);
+ m_operand_collector.add_port(in_ports,out_ports,cu_sets);
+ in_ports.clear(),out_ports.clear(),cu_sets.clear();
+ }
+ }
m_operand_collector.init( m_config->gpgpu_num_reg_banks, this );
@@ -761,15 +768,19 @@ void shader_core_ctx::func_exec_inst( warp_inst_t &inst )
inst.generate_mem_accesses();
}
-void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t* next_inst, const active_mask_t &active_mask, unsigned warp_id )
+void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t* next_inst, const active_mask_t &active_mask, unsigned warp_id, unsigned sch_id )
{
- warp_inst_t** pipe_reg = pipe_reg_set.get_free();
+ warp_inst_t** pipe_reg;
+ if(m_config->sub_core_model)
+ pipe_reg = pipe_reg_set.get_free(sch_id);
+ else
+ pipe_reg = pipe_reg_set.get_free();
assert(pipe_reg);
m_warp[warp_id].ibuffer_free();
assert(next_inst->valid());
**pipe_reg = *next_inst; // static instruction information
- (*pipe_reg)->issue( active_mask, warp_id, gpu_tot_sim_cycle + gpu_sim_cycle, m_warp[warp_id].get_dynamic_warp_id() ); // dynamic instruction information
+ (*pipe_reg)->issue( active_mask, warp_id, gpu_tot_sim_cycle + gpu_sim_cycle, m_warp[warp_id].get_dynamic_warp_id(), sch_id ); // dynamic instruction information
m_stats->shader_cycle_distro[2+(*pipe_reg)->active_count()]++;
func_exec_inst( **pipe_reg );
if( next_inst->op == BARRIER_OP ){
@@ -950,8 +961,8 @@ void scheduler_unit::cycle()
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)) {
- m_shader->issue_warp(*m_mem_out,pI,active_mask,warp_id);
+ if( m_mem_out->has_free(m_id) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::MEM)) {
+ m_shader->issue_warp(*m_mem_out,pI,active_mask,warp_id,m_id);
issued++;
issued_inst=true;
warp_inst_issued = true;
@@ -959,9 +970,9 @@ void scheduler_unit::cycle()
}
} else {
- bool sp_pipe_avail = m_sp_out->has_free();
- bool sfu_pipe_avail = m_sfu_out->has_free();
- bool dp_pipe_avail = m_dp_out->has_free();
+ bool sp_pipe_avail = m_sp_out->has_free(m_id);
+ bool sfu_pipe_avail = m_sfu_out->has_free(m_id);
+ bool dp_pipe_avail = m_dp_out->has_free(m_id);
if( sp_pipe_avail && (pI->op != SFU_OP && pI->op != DP_OP) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::SP)) {
//Jin: special for CDP api
@@ -983,14 +994,14 @@ void scheduler_unit::cycle()
}
// always prefer SP pipe for operations that can use both SP and SFU pipelines
- m_shader->issue_warp(*m_sp_out,pI,active_mask,warp_id);
+ m_shader->issue_warp(*m_sp_out,pI,active_mask,warp_id,m_id);
issued++;
issued_inst=true;
warp_inst_issued = true;
previous_issued_inst_exec_type = exec_unit_type_t::SP;
} else if ( (m_shader->m_config->gpgpu_num_dp_units != 0) && (pI->op == DP_OP) && (!diff_exec_units || previous_issued_inst_exec_type != exec_unit_type_t::DP)) {
if( dp_pipe_avail ) {
- m_shader->issue_warp(*m_dp_out,pI,active_mask,warp_id);
+ m_shader->issue_warp(*m_dp_out,pI,active_mask,warp_id,m_id);
issued++;
issued_inst=true;
warp_inst_issued = true;
@@ -999,7 +1010,7 @@ void scheduler_unit::cycle()
} //If the DP units = 0 (like in Fermi archi), then change DP inst to SFU inst
else if ( ((m_shader->m_config->gpgpu_num_dp_units == 0 && pI->op == DP_OP) || (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);
+ m_shader->issue_warp(*m_sfu_out,pI,active_mask,warp_id,m_id);
issued++;
issued_inst=true;
warp_inst_issued = true;
@@ -2068,7 +2079,11 @@ void ldst_unit::writeback()
unsigned ldst_unit::clock_multiplier() const
{
- return m_config->mem_warp_parts;
+ //to model multiple read port, we give multiple cycles for the memory units
+ if(m_config->mem_unit_ports)
+ return m_config->mem_unit_ports;
+ else
+ return m_config->mem_warp_parts;
}
/*
void ldst_unit::issue( register_set &reg_set )
@@ -3305,18 +3320,34 @@ void opndcoll_rfu_t::init( unsigned num_banks, shader_core_ctx *shader )
m_bank_warp_shift = (unsigned)(int) (log(m_warp_size+0.5) / log(2.0));
assert( (m_bank_warp_shift == 5) || (m_warp_size != 32) );
+ sub_core_model = shader->get_config()->sub_core_model;
+ m_num_warp_sceds = shader->get_config()->gpgpu_num_sched_per_core;
+ if(sub_core_model)
+ assert(num_banks % shader->get_config()->gpgpu_num_sched_per_core == 0);
+ m_num_banks_per_sched = num_banks / shader->get_config()->gpgpu_num_sched_per_core;
+
for( unsigned j=0; j<m_cu.size(); j++) {
- m_cu[j]->init(j,num_banks,m_bank_warp_shift,shader->get_config(),this);
+ m_cu[j]->init(j,num_banks,m_bank_warp_shift,shader->get_config(),this, sub_core_model, m_num_banks_per_sched );
}
m_initialized=true;
+
+
+
+
}
-int register_bank(int regnum, int wid, unsigned num_banks, unsigned bank_warp_shift)
+int register_bank(int regnum, int wid, unsigned num_banks, unsigned bank_warp_shift, bool sub_core_model, unsigned banks_per_sched, unsigned sched_id)
{
int bank = regnum;
if (bank_warp_shift)
bank += wid;
- return bank % num_banks;
+ if(sub_core_model) {
+ unsigned bank_num = (bank % banks_per_sched) + (sched_id * banks_per_sched);
+ assert(bank_num < num_banks);
+ return bank_num;
+ }
+ else
+ return bank % num_banks;
}
bool opndcoll_rfu_t::writeback( const warp_inst_t &inst )
@@ -3327,9 +3358,9 @@ bool opndcoll_rfu_t::writeback( const warp_inst_t &inst )
unsigned n=0;
for( r=regs.begin(); r!=regs.end();r++,n++ ) {
unsigned reg = *r;
- unsigned bank = register_bank(reg,inst.warp_id(),m_num_banks,m_bank_warp_shift);
+ unsigned bank = register_bank(reg,inst.warp_id(),m_num_banks,m_bank_warp_shift, sub_core_model, m_num_banks_per_sched, inst.get_schd_id());
if( m_arbiter.bank_idle(bank) ) {
- m_arbiter.allocate_bank_for_write(bank,op_t(&inst,reg,m_num_banks,m_bank_warp_shift));
+ m_arbiter.allocate_bank_for_write(bank,op_t(&inst,reg,m_num_banks,m_bank_warp_shift, sub_core_model, m_num_banks_per_sched, inst.get_schd_id()));
} else {
return false;
}
@@ -3413,7 +3444,7 @@ void opndcoll_rfu_t::allocate_reads()
const op_t &rr = *r;
unsigned reg = rr.get_reg();
unsigned wid = rr.get_wid();
- unsigned bank = register_bank(reg,wid,m_num_banks,m_bank_warp_shift);
+ unsigned bank = register_bank(reg,wid,m_num_banks,m_bank_warp_shift,sub_core_model, m_num_banks_per_sched, rr.get_sid());
m_arbiter.allocate_for_read(bank,rr);
read_ops[bank] = rr;
}
@@ -3464,7 +3495,9 @@ void opndcoll_rfu_t::collector_unit_t::init( unsigned n,
unsigned num_banks,
unsigned log2_warp_size,
const core_config *config,
- opndcoll_rfu_t *rfu )
+ opndcoll_rfu_t *rfu,
+ bool sub_core_model,
+ unsigned banks_per_sched)
{
m_rfu=rfu;
m_cuid=n;
@@ -3472,6 +3505,8 @@ void opndcoll_rfu_t::collector_unit_t::init( unsigned n,
assert(m_warp==NULL);
m_warp = new warp_inst_t(config);
m_bank_warp_shift=log2_warp_size;
+ m_sub_core_model = sub_core_model;
+ m_num_banks_per_sched = banks_per_sched;
}
bool opndcoll_rfu_t::collector_unit_t::allocate( register_set* pipeline_reg_set, register_set* output_reg_set )
@@ -3486,7 +3521,7 @@ bool opndcoll_rfu_t::collector_unit_t::allocate( register_set* pipeline_reg_set,
for( unsigned op=0; op < MAX_REG_OPERANDS; op++ ) {
int reg_num = (*pipeline_reg)->arch_reg.src[op]; // this math needs to match that used in function_info::ptx_decode_inst
if( reg_num >= 0 ) { // valid register
- m_src_op[op] = op_t( this, op, reg_num, m_num_banks, m_bank_warp_shift );
+ m_src_op[op] = op_t( this, op, reg_num, m_num_banks, m_bank_warp_shift, m_sub_core_model, m_num_banks_per_sched, (*pipeline_reg)->get_schd_id() );
m_not_ready.set(op);
} else
m_src_op[op] = op_t();
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index 4a87126..e6132f5 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -291,7 +291,7 @@ inline unsigned wid_from_hw_tid(unsigned tid, unsigned warp_size){return tid/war
const unsigned WARP_PER_CTA_MAX = 64;
typedef std::bitset<WARP_PER_CTA_MAX> warp_set_t;
-int register_bank(int regnum, int wid, unsigned num_banks, unsigned bank_warp_shift);
+int register_bank(int regnum, int wid, unsigned num_banks, unsigned bank_warp_shift, bool sub_core_model, unsigned banks_per_sched, unsigned sched_id );
class shader_core_ctx;
struct shader_core_config;
@@ -378,6 +378,8 @@ public:
// m_supervised_warps with their scheduling policies
virtual void order_warps() = 0;
+ int get_schd_id() const {return m_id;}
+
protected:
virtual void do_on_warp_issued( unsigned warp_id,
unsigned num_issued,
@@ -601,23 +603,25 @@ private:
public:
op_t() { m_valid = false; }
- op_t( collector_unit_t *cu, unsigned op, unsigned reg, unsigned num_banks, unsigned bank_warp_shift )
+ op_t( collector_unit_t *cu, unsigned op, unsigned reg, unsigned num_banks, unsigned bank_warp_shift, bool sub_core_model, unsigned banks_per_sched, unsigned sched_id )
{
m_valid = true;
m_warp=NULL;
m_cu = cu;
m_operand = op;
m_register = reg;
- m_bank = register_bank(reg,cu->get_warp_id(),num_banks,bank_warp_shift);
+ m_shced_id = sched_id;
+ m_bank = register_bank(reg,cu->get_warp_id(),num_banks,bank_warp_shift, sub_core_model, banks_per_sched, sched_id);
}
- op_t( const warp_inst_t *warp, unsigned reg, unsigned num_banks, unsigned bank_warp_shift )
+ op_t( const warp_inst_t *warp, unsigned reg, unsigned num_banks, unsigned bank_warp_shift, bool sub_core_model, unsigned banks_per_sched, unsigned sched_id )
{
m_valid=true;
m_warp=warp;
m_register=reg;
m_cu=NULL;
m_operand = -1;
- m_bank = register_bank(reg,warp->warp_id(),num_banks,bank_warp_shift);
+ m_shced_id = sched_id;
+ m_bank = register_bank(reg,warp->warp_id(),num_banks,bank_warp_shift, sub_core_model, banks_per_sched, sched_id);
}
// accessors
@@ -633,6 +637,10 @@ private:
else if( m_cu ) return m_cu->get_warp_id();
else abort();
}
+ unsigned get_sid() const
+ {
+ return m_shced_id;
+ }
unsigned get_active_count() const
{
if( m_warp ) return m_warp->active_count();
@@ -677,6 +685,7 @@ private:
unsigned m_operand; // operand offset in instruction. e.g., add r1,r2,r3; r2 is oprd 0, r3 is 1 (r1 is dst)
unsigned m_register;
unsigned m_bank;
+ unsigned m_shced_id; //scheduler id that has issued this inst
};
enum alloc_t {
@@ -697,7 +706,7 @@ private:
else if( m_allocation == WRITE_ALLOC ) { fprintf(fp,"wr: "); m_op.dump(fp); }
fprintf(fp,"\n");
}
- void alloc_read( const op_t &op ) { assert(is_free()); m_allocation=READ_ALLOC; m_op=op; }
+ void alloc_read( const op_t &op ) { assert(is_free()); m_allocation=READ_ALLOC; m_op=op; }
void alloc_write( const op_t &op ) { assert(is_free()); m_allocation=WRITE_ALLOC; m_op=op; }
void reset() { m_allocation = NO_ALLOC; }
private:
@@ -851,7 +860,9 @@ private:
unsigned num_banks,
unsigned log2_warp_size,
const core_config *config,
- opndcoll_rfu_t *rfu );
+ opndcoll_rfu_t *rfu,
+ bool m_sub_core_model,
+ unsigned num_banks_per_sched);
bool allocate( register_set* pipeline_reg, register_set* output_reg );
void collect_operand( unsigned op )
@@ -879,6 +890,9 @@ private:
unsigned m_bank_warp_shift;
opndcoll_rfu_t *m_rfu;
+ unsigned m_num_banks_per_sched;
+ bool m_sub_core_model;
+
};
class dispatch_unit_t {
@@ -921,6 +935,10 @@ private:
std::vector<collector_unit_t *> m_cu;
arbiter_t m_arbiter;
+ unsigned m_num_banks_per_sched;
+ unsigned m_num_warp_sceds;
+ bool sub_core_model;
+
//unsigned m_num_ports;
//std::vector<warp_inst_t**> m_input;
//std::vector<warp_inst_t**> m_output;
@@ -1361,6 +1379,7 @@ struct shader_core_config : public core_config
bool gpgpu_dual_issue_diff_exec_units;
//op collector
+ bool enable_specialized_operand_collector;
int gpgpu_operand_collector_num_units_sp;
int gpgpu_operand_collector_num_units_dp;
int gpgpu_operand_collector_num_units_sfu;
@@ -1392,6 +1411,7 @@ struct shader_core_config : public core_config
bool gpgpu_reg_bank_use_warp_id;
bool gpgpu_local_mem_map;
bool gpgpu_ignore_resources_limitation;
+ bool sub_core_model;
unsigned max_sp_latency;
unsigned max_sfu_latency;
@@ -1848,7 +1868,7 @@ public:
friend class scheduler_unit; //this is needed to use private issue warp.
friend class TwoLevelScheduler;
friend class LooseRoundRobbinScheduler;
- void issue_warp( register_set& warp, const warp_inst_t *pI, const active_mask_t &active_mask, unsigned warp_id );
+ void issue_warp( register_set& warp, const warp_inst_t *pI, const active_mask_t &active_mask, unsigned warp_id, unsigned sch_id );
void func_exec_inst( warp_inst_t &inst );
// Returns numbers of addresses in translated_addrs