summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/Fermi/gpgpusim.config5
-rw-r--r--src/gpgpu-sim/shader.cc37
-rw-r--r--src/gpgpu-sim/shader.h22
3 files changed, 48 insertions, 16 deletions
diff --git a/configs/Fermi/gpgpusim.config b/configs/Fermi/gpgpusim.config
index afe86e7..5ec3f72 100644
--- a/configs/Fermi/gpgpusim.config
+++ b/configs/Fermi/gpgpusim.config
@@ -24,7 +24,7 @@
# Pipeline widths and number of FUs
# ID_OC_SP,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_SFU,OC_EX_MEM,EX_WB
--gpgpu_pipeline_widths 1,1,1,1,1,1,1
+-gpgpu_pipeline_widths 2,1,1,2,1,1,2
-gpgpu_num_sp_units 2
-gpgpu_num_sfu_units 1
@@ -105,5 +105,6 @@
# enable operand collector
-gpgpu_operand_collector_num_units_sp 6
-gpgpu_operand_collector_num_units_sfu 8
-
+-gpgpu_operand_collector_num_in_ports_sp 2
+-gpgpu_operand_collector_num_out_ports_sp 2
-visualizer_enabled 0
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 7ee6ba4..4ddac46 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -212,6 +212,12 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu,
assert(m_num_function_units == m_fu.size() and m_fu.size() == m_dispatch_port.size() and m_fu.size() == m_issue_port.size());
+ //there are as many result buses as the width of the EX_WB stage
+ num_result_bus = config->pipe_widths[EX_WB];
+ for(int i=0; i<num_result_bus; i++){
+ this->m_result_bus.push_back(new std::bitset<MAX_ALU_LATENCY>());
+ }
+
m_last_inst_gpu_sim_cycle = 0;
m_last_inst_gpu_tot_sim_cycle = 0;
}
@@ -695,10 +701,18 @@ unsigned shader_core_ctx::translate_local_memaddr( address_type localaddr, unsig
}
/////////////////////////////////////////////////////////////////////////////////////////
+int shader_core_ctx::test_res_bus(int latency){
+ for(int i=0; i<num_result_bus; i++){
+ if(!m_result_bus[i]->test(latency)){return i;}
+ }
+ return -1;
+}
void shader_core_ctx::execute()
{
- m_result_bus >>= 1;
+ for(int i=0; i<num_result_bus; i++){
+ *(m_result_bus[i]) >>=1;
+ }
for( unsigned n=0; n < m_num_function_units; n++ ) {
unsigned multiplier = m_fu[n]->clock_multiplier();
for( unsigned c=0; c < multiplier; c++ )
@@ -708,9 +722,10 @@ void shader_core_ctx::execute()
warp_inst_t** ready_reg = issue_inst.get_ready();
if( issue_inst.has_ready() && m_fu[n]->can_issue( **ready_reg ) ) {
bool schedule_wb_now = !m_fu[n]->stallable();
- if( schedule_wb_now && !m_result_bus.test( (*ready_reg)->latency ) ) {
+ int resbus = -1;
+ if( schedule_wb_now && (resbus=test_res_bus( (*ready_reg)->latency ))!=-1 ) {
assert( (*ready_reg)->latency < MAX_ALU_LATENCY );
- m_result_bus.set( (*ready_reg)->latency );
+ m_result_bus[resbus]->set( (*ready_reg)->latency );
m_fu[n]->issue( issue_inst );
} else if( !schedule_wb_now ) {
m_fu[n]->issue( issue_inst );
@@ -743,7 +758,12 @@ void shader_core_ctx::writeback()
{
warp_inst_t** preg = m_pipeline_reg[EX_WB].get_ready();
warp_inst_t* pipe_reg = (preg==NULL)? NULL:*preg;
- if( preg and !pipe_reg->empty() ) {
+ while( preg and !pipe_reg->empty() ) {
+ /*
+ * Right now, the writeback stage drains all waiting instructions
+ * assuming there are enough ports in the register file or the
+ * conflicts are resolved at issue.
+ */
/*
* The operand collector writeback can generally generate a stall
* However, here, the pipelines should be un-stallable. This is
@@ -765,6 +785,8 @@ void shader_core_ctx::writeback()
m_last_inst_gpu_sim_cycle = gpu_sim_cycle;
m_last_inst_gpu_tot_sim_cycle = gpu_tot_sim_cycle;
pipe_reg->clear();
+ preg = m_pipeline_reg[EX_WB].get_ready();
+ pipe_reg = (preg==NULL)? NULL:*preg;
}
}
@@ -1473,8 +1495,10 @@ void shader_core_ctx::display_pipeline(FILE *fout, int print_mem, int mask ) con
}
fprintf(fout, "-------------------------- other:\n");
- std::string bits = m_result_bus.to_string();
- fprintf(fout, "EX/WB sched= %s\n", bits.c_str() );
+ for(int i=0; i<num_result_bus; i++){
+ std::string bits = m_result_bus[i]->to_string();
+ fprintf(fout, "EX/WB sched[%d]= %s\n", i, bits.c_str() );
+ }
fprintf(fout, "EX/WB = ");
print_stage(EX_WB, fout);
fprintf(fout, "\n");
@@ -2340,3 +2364,4 @@ void shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned
}
}
}
+
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index 571a4b9..341915e 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -721,12 +721,12 @@ public:
~simd_function_unit() { delete m_dispatch_reg; }
// modifiers
- virtual void issue( register_set& source_reg ) { source_reg.move_out_to(m_dispatch_reg); }
+ virtual void issue( register_set& source_reg ) { source_reg.move_out_to(m_dispatch_reg); occupied.set(m_dispatch_reg->latency);}
virtual void cycle() = 0;
// accessors
virtual unsigned clock_multiplier() const { return 1; }
- virtual bool can_issue( const warp_inst_t & ) const { return m_dispatch_reg->empty(); }
+ virtual bool can_issue( const warp_inst_t &inst ) const { return m_dispatch_reg->empty() && !occupied.test(inst.latency); }
virtual bool stallable() const = 0;
virtual void print( FILE *fp ) const
{
@@ -737,6 +737,8 @@ protected:
std::string m_name;
const shader_core_config *m_config;
warp_inst_t *m_dispatch_reg;
+ static const unsigned MAX_ALU_LATENCY = 512;
+ std::bitset<MAX_ALU_LATENCY> occupied;
};
class pipelined_simd_unit : public simd_function_unit {
@@ -746,23 +748,25 @@ public:
//modifiers
virtual void cycle()
{
- if( !m_pipeline_reg[0]->empty() )
- //move_warp(*m_result_port,m_pipeline_reg[0]); // non-stallable pipeline
+ if( !m_pipeline_reg[0]->empty() ){
m_result_port->move_in(m_pipeline_reg[0]);
+ }
for( unsigned stage=0; (stage+1)<m_pipeline_depth; stage++ )
move_warp(m_pipeline_reg[stage], m_pipeline_reg[stage+1]);
if( !m_dispatch_reg->empty() ) {
- if( !m_dispatch_reg->dispatch_delay() ) {
+ if( !m_dispatch_reg->dispatch_delay()) {
int start_stage = m_dispatch_reg->latency - m_dispatch_reg->initiation_interval;
move_warp(m_pipeline_reg[start_stage],m_dispatch_reg);
}
}
+ occupied >>=1;
}
virtual void issue( register_set& source_reg )
{
//move_warp(m_dispatch_reg,source_reg);
- source_reg.move_out_to(m_dispatch_reg);
+ //source_reg.move_out_to(m_dispatch_reg);
+ simd_function_unit::issue(source_reg);
}
// accessors
@@ -855,7 +859,7 @@ public:
case MEMORY_BARRIER_OP: break;
default: return false;
}
- return simd_function_unit::can_issue(inst);
+ return m_dispatch_reg->empty();
}
virtual bool stallable() const { return true; }
bool response_buffer_full() const;
@@ -1203,6 +1207,7 @@ public:
void display_pipeline( FILE *fout, int print_mem, int mask3bit ) const;
private:
+ int test_res_bus(int latency);
void init_warps(unsigned cta_id, unsigned start_thread, unsigned end_thread);
virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid);
address_type next_pc( int tid ) const;
@@ -1276,7 +1281,8 @@ private:
std::vector<simd_function_unit*> m_fu; // stallable pipelines should be last in this array
ldst_unit *m_ldst_unit;
static const unsigned MAX_ALU_LATENCY = 512;
- std::bitset<MAX_ALU_LATENCY> m_result_bus;
+ unsigned num_result_bus;
+ std::vector< std::bitset<MAX_ALU_LATENCY>* > m_result_bus;
// used for local address mapping with single kernel launch
unsigned kernel_max_cta_per_shader;