aboutsummaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/shader.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim/shader.cc')
-rw-r--r--src/gpgpu-sim/shader.cc165
1 files changed, 144 insertions, 21 deletions
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 4640d65..d2f40a1 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;
@@ -147,6 +150,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
m_simt_stack,
&m_warp,
&m_pipeline_reg[ID_OC_SP],
+ &m_pipeline_reg[ID_OC_DP],
&m_pipeline_reg[ID_OC_SFU],
&m_pipeline_reg[ID_OC_MEM],
i
@@ -161,6 +165,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
m_simt_stack,
&m_warp,
&m_pipeline_reg[ID_OC_SP],
+ &m_pipeline_reg[ID_OC_DP],
&m_pipeline_reg[ID_OC_SFU],
&m_pipeline_reg[ID_OC_MEM],
i,
@@ -176,12 +181,28 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
m_simt_stack,
&m_warp,
&m_pipeline_reg[ID_OC_SP],
+ &m_pipeline_reg[ID_OC_DP],
&m_pipeline_reg[ID_OC_SFU],
&m_pipeline_reg[ID_OC_MEM],
i
)
);
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_DP],
+ &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,
@@ -190,6 +211,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
m_simt_stack,
&m_warp,
&m_pipeline_reg[ID_OC_SP],
+ &m_pipeline_reg[ID_OC_DP],
&m_pipeline_reg[ID_OC_SFU],
&m_pipeline_reg[ID_OC_MEM],
i,
@@ -211,8 +233,9 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
}
//op collector configuration
- enum { SP_CUS, SFU_CUS, MEM_CUS, GEN_CUS };
+ 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);
@@ -229,6 +252,15 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
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]);
@@ -263,7 +295,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
m_operand_collector.init( m_config->gpgpu_num_reg_banks, this );
// execute
- m_num_function_units = m_config->gpgpu_num_sp_units + m_config->gpgpu_num_sfu_units + 1; // sp_unit, sfu, ldst_unit
+ m_num_function_units = m_config->gpgpu_num_sp_units + m_config->gpgpu_num_dp_units + m_config->gpgpu_num_sfu_units + 1; // sp_unit, sfu, ldst_unit
//m_dispatch_port = new enum pipeline_stage_name_t[ m_num_function_units ];
//m_issue_port = new enum pipeline_stage_name_t[ m_num_function_units ];
@@ -275,12 +307,18 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
m_issue_port.push_back(OC_EX_SP);
}
+ for (int k = 0; k < m_config->gpgpu_num_dp_units; k++) {
+ m_fu.push_back(new dp_unit( &m_pipeline_reg[EX_WB], m_config, this ));
+ m_dispatch_port.push_back(ID_OC_DP);
+ m_issue_port.push_back(OC_EX_DP);
+ }
+
for (int k = 0; k < m_config->gpgpu_num_sfu_units; k++) {
m_fu.push_back(new sfu( &m_pipeline_reg[EX_WB], m_config, this ));
m_dispatch_port.push_back(ID_OC_SFU);
m_issue_port.push_back(OC_EX_SFU);
}
-
+
m_ldst_unit = new ldst_unit( m_icnt, m_mem_fetch_allocator, this, &m_operand_collector, m_scoreboard, config, mem_config, stats, shader_id, tpc_id );
m_fu.push_back(m_ldst_unit);
m_dispatch_port.push_back(ID_OC_MEM);
@@ -465,6 +503,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);
@@ -652,7 +698,7 @@ void shader_core_ctx::fetch()
if( !m_warp[warp_id].functional_done() && !m_warp[warp_id].imiss_pending() && m_warp[warp_id].ibuffer_empty() ) {
address_type pc = m_warp[warp_id].get_pc();
address_type ppc = pc + PROGRAM_MEM_START;
- unsigned nbytes=16;
+ unsigned nbytes=16;
unsigned offset_in_block = pc & (m_config->m_L1I_config.get_line_sz()-1);
if( (offset_in_block+nbytes) > m_config->m_L1I_config.get_line_sz() )
nbytes = (m_config->m_L1I_config.get_line_sz()-offset_in_block);
@@ -724,10 +770,19 @@ void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t*
}
void shader_core_ctx::issue(){
+
+ //Ensure fair round robin issu between schedulers
+ 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 +897,10 @@ 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;
@@ -876,16 +934,19 @@ 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() ) {
+ 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);
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) ) {
+ bool dp_pipe_avail = m_dp_out->has_free();
+ 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
if(pI->m_is_cdp && !warp(warp_id).m_cdp_dummy) {
@@ -910,14 +971,26 @@ 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 ( (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);
+ issued++;
+ issued_inst=true;
+ warp_inst_issued = true;
+ previous_issued_inst_exec_type = exec_unit_type_t::DP;
+ }
+ } //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);
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 +1025,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 +1090,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,
@@ -1081,11 +1172,12 @@ swl_scheduler::swl_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* dp_out,
register_set* sfu_out,
register_set* mem_out,
int id,
char* config_string )
- : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, mem_out, id )
+ : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, dp_out, sfu_out, mem_out, id )
{
unsigned m_prioritization_readin;
int ret = sscanf( config_string,
@@ -1347,8 +1439,14 @@ ldst_unit::process_cache_access( cache_t* cache,
mem_stage_stall_type result = NO_RC_FAIL;
bool write_sent = was_write_sent(events);
bool read_sent = was_read_sent(events);
- if( write_sent )
- m_core->inc_store_req( inst.warp_id() );
+ if( write_sent ) {
+ unsigned inc_ack = (m_config->m_L1D_config.get_mshr_type() == SECTOR_ASSOC)?
+ (mf->get_data_size()/SECTOR_SIZE) : 1;
+
+ for(unsigned i=0; i< inc_ack; ++i)
+ m_core->inc_store_req( inst.warp_id() );
+
+ }
if ( status == HIT ) {
assert( !read_sent );
inst.accessq_pop_back();
@@ -1360,7 +1458,7 @@ ldst_unit::process_cache_access( cache_t* cache,
if( !write_sent )
delete mf;
} else if ( status == RESERVATION_FAIL ) {
- result = COAL_STALL;
+ result = BK_CONF;
assert( !read_sent );
assert( !write_sent );
delete mf;
@@ -1369,8 +1467,8 @@ ldst_unit::process_cache_access( cache_t* cache,
//inst.clear_active( access.get_warp_mask() ); // threads in mf writeback when mf returns
inst.accessq_pop_back();
}
- if( !inst.accessq_empty() )
- result = BK_CONF;
+ if( !inst.accessq_empty() && result == NO_RC_FAIL)
+ result = COAL_STALL;
return result;
}
@@ -1465,7 +1563,7 @@ bool ldst_unit::memory_cycle( warp_inst_t &inst, mem_stage_stall_type &stall_rea
assert( CACHE_UNDEFINED != inst.cache_op );
stall_cond = process_memory_access_queue(m_L1D,inst);
}
- if( !inst.accessq_empty() )
+ if( !inst.accessq_empty() && stall_cond == NO_RC_FAIL)
stall_cond = COAL_STALL;
if (stall_cond != NO_RC_FAIL) {
stall_reason = stall_cond;
@@ -1530,6 +1628,13 @@ void sp_unit::active_lanes_in_pipeline(){
m_core->incfuactivelanes_stat(active_count);
m_core->incfumemactivelanes_stat(active_count);
}
+void dp_unit::active_lanes_in_pipeline(){
+ unsigned active_count=pipelined_simd_unit::get_active_lanes_in_pipeline();
+ assert(active_count<=m_core->get_config()->warp_size);
+ m_core->incspactivelanes_stat(active_count);
+ m_core->incfuactivelanes_stat(active_count);
+ m_core->incfumemactivelanes_stat(active_count);
+}
void sfu::active_lanes_in_pipeline(){
unsigned active_count=pipelined_simd_unit::get_active_lanes_in_pipeline();
@@ -1545,6 +1650,12 @@ sp_unit::sp_unit( register_set* result_port, const shader_core_config *config,sh
m_name = "SP ";
}
+dp_unit::dp_unit( register_set* result_port, const shader_core_config *config,shader_core_ctx *core)
+ : pipelined_simd_unit(result_port,config,config->max_sfu_latency,core)
+{
+ m_name = "DP ";
+}
+
void sp_unit :: issue(register_set& source_reg)
{
warp_inst_t** ready_reg = source_reg.get_ready();
@@ -1554,6 +1665,14 @@ void sp_unit :: issue(register_set& source_reg)
pipelined_simd_unit::issue(source_reg);
}
+void dp_unit :: issue(register_set& source_reg)
+{
+ warp_inst_t** ready_reg = source_reg.get_ready();
+ //m_core->incexecstat((*ready_reg));
+ (*ready_reg)->op_pipe=DP__OP;
+ m_core->incsp_stat(m_core->get_config()->warp_size,(*ready_reg)->latency);
+ pipelined_simd_unit::issue(source_reg);
+}
pipelined_simd_unit::pipelined_simd_unit( register_set* result_port, const shader_core_config *config, unsigned max_latency,shader_core_ctx *core )
: simd_function_unit(config)
@@ -1851,12 +1970,12 @@ void ldst_unit::cycle()
if( !m_response_fifo.empty() ) {
mem_fetch *mf = m_response_fifo.front();
- if (mf->istexture()) {
+ if (mf->get_access_type() == TEXTURE_ACC_R) {
if (m_L1T->fill_port_free()) {
m_L1T->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle);
m_response_fifo.pop_front();
}
- } else if (mf->isconst()) {
+ } else if (mf->get_access_type() == CONST_ACC_R) {
if (m_L1C->fill_port_free()) {
mf->set_status(IN_SHADER_FETCHED,gpu_sim_cycle+gpu_tot_sim_cycle);
m_L1C->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle);
@@ -2497,6 +2616,10 @@ unsigned int shader_core_config::max_cta( const kernel_info_t &k ) const
assert( result <= MAX_CTA_PER_SHADER );
if (result < 1) {
printf ("GPGPU-Sim uArch: ERROR ** Kernel requires more resources than shader has.\n");
+ if(gpgpu_ignore_resources_limitation) {
+ printf ("GPGPU-Sim uArch: gpgpu_ignore_resources_limitation is set, ignore the ERROR!\n");
+ return 1;
+ }
abort();
}