diff options
Diffstat (limited to 'src/gpgpu-sim/shader.cc')
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 135 |
1 files changed, 124 insertions, 11 deletions
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 4d4f112..7482e0e 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -162,7 +162,10 @@ void shader_core_ctx::create_front_pipeline() { } // m_icnt = new shader_memory_interface(this,cluster); - if (m_config->gpgpu_perfect_mem) { + if (m_memory_config->SST_mode) { + m_icnt = new sst_memory_interface( + this, static_cast<sst_simt_core_cluster *>(m_cluster)); + } else if (m_config->gpgpu_perfect_mem) { m_icnt = new perfect_memory_interface(this, m_cluster); } else { m_icnt = new shader_memory_interface(this, m_cluster); @@ -2281,7 +2284,15 @@ bool ldst_unit::memory_cycle(warp_inst_t &inst, inst.is_store() ? WRITE_PACKET_SIZE : READ_PACKET_SIZE; unsigned size = access.get_size() + control_size; // printf("Interconnect:Addr: %x, size=%d\n",access.get_addr(),size); - if (m_icnt->full(size, inst.is_store() || inst.isatomic())) { + if (m_memory_config->SST_mode && + (static_cast<sst_memory_interface *>(m_icnt)->full( + size, inst.is_store() || inst.isatomic(), access.get_type()))) { + // SST need mf type here + // Cast it to sst_memory_interface pointer first as this full() method + // is not a virtual method in parent class + stall_cond = ICNT_RC_FAIL; + } else if (!m_memory_config->SST_mode && + (m_icnt->full(size, inst.is_store() || inst.isatomic()))) { stall_cond = ICNT_RC_FAIL; } else { mem_fetch *mf = @@ -2846,7 +2857,10 @@ void ldst_unit::cycle() { } } else { if (mf->get_type() == WRITE_ACK || - (m_config->gpgpu_perfect_mem && mf->get_is_write())) { + ((m_config->gpgpu_perfect_mem || m_memory_config->SST_mode) && + mf->get_is_write())) { + // SST memory is handled by SST mem hierarchy + // Perfect mem m_core->store_ack(mf); m_response_fifo.pop_front(); delete mf; @@ -4020,7 +4034,8 @@ void shader_core_ctx::accept_ldst_unit_response(mem_fetch *mf) { void shader_core_ctx::store_ack(class mem_fetch *mf) { assert(mf->get_type() == WRITE_ACK || - (m_config->gpgpu_perfect_mem && mf->get_is_write())); + ((m_config->gpgpu_perfect_mem || m_memory_config->SST_mode) && + mf->get_is_write())); unsigned warp_id = mf->get_wid(); m_warp[warp_id]->dec_store_req(); } @@ -4573,7 +4588,46 @@ bool simt_core_cluster::icnt_injection_buffer_full(unsigned size, bool write) { return !::icnt_has_buffer(m_cluster_id, request_size); } +bool sst_simt_core_cluster::SST_injection_buffer_full(unsigned size, bool write, + mem_access_type type) { + switch (type) { + case CONST_ACC_R: + case INST_ACC_R: { + return response_queue_full(); + break; + } + default: { + return ::is_SST_buffer_full(m_cluster_id); + break; + } + } +} + void simt_core_cluster::icnt_inject_request_packet(class mem_fetch *mf) { + // Update stats based on mf type + update_icnt_stats(mf); + + // The packet size varies depending on the type of request: + // - For write request and atomic request, the packet contains the data + // - For read request (i.e. not write nor atomic), the packet only has control + // metadata + unsigned int packet_size = mf->size(); + if (!mf->get_is_write() && !mf->isatomic()) { + packet_size = mf->get_ctrl_size(); + } + m_stats->m_outgoing_traffic_stats->record_traffic(mf, packet_size); + unsigned destination = mf->get_sub_partition_id(); + mf->set_status(IN_ICNT_TO_MEM, + m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle); + if (!mf->get_is_write() && !mf->isatomic()) + ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void *)mf, + mf->get_ctrl_size()); + else + ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void *)mf, + mf->size()); +} + +void simt_core_cluster::update_icnt_stats(class mem_fetch *mf) { // stats if (mf->get_is_write()) m_stats->made_write_mfs++; @@ -4618,6 +4672,12 @@ void simt_core_cluster::icnt_inject_request_packet(class mem_fetch *mf) { default: assert(0); } +} + +void sst_simt_core_cluster::icnt_inject_request_packet_to_SST( + class mem_fetch *mf) { + // Update stats + update_icnt_stats(mf); // The packet size varies depending on the type of request: // - For write request and atomic request, the packet contains the data @@ -4628,15 +4688,25 @@ void simt_core_cluster::icnt_inject_request_packet(class mem_fetch *mf) { packet_size = mf->get_ctrl_size(); } m_stats->m_outgoing_traffic_stats->record_traffic(mf, packet_size); - unsigned destination = mf->get_sub_partition_id(); mf->set_status(IN_ICNT_TO_MEM, m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle); - if (!mf->get_is_write() && !mf->isatomic()) - ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void *)mf, - mf->get_ctrl_size()); - else - ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void *)mf, - mf->size()); + switch (mf->get_access_type()) { + case CONST_ACC_R: + case INST_ACC_R: { + push_response_fifo(mf); + break; + } + default: { + if (!mf->get_is_write() && !mf->isatomic()) + ::send_read_request_SST(m_cluster_id, mf->get_addr(), + mf->get_data_size(), (void *)mf); + else + ::send_write_request_SST(m_cluster_id, mf->get_addr(), + mf->get_data_size(), (void *)mf); + + break; + } + } } void simt_core_cluster::icnt_cycle() { @@ -4678,6 +4748,49 @@ void simt_core_cluster::icnt_cycle() { } } +void sst_simt_core_cluster::icnt_cycle_SST() { + if (!m_response_fifo.empty()) { + mem_fetch *mf = m_response_fifo.front(); + unsigned cid = m_config->sid_to_cid(mf->get_sid()); + if (mf->get_access_type() == INST_ACC_R) { + // instruction fetch response + if (!m_core[cid]->fetch_unit_response_buffer_full()) { + m_response_fifo.pop_front(); + m_core[cid]->accept_fetch_response(mf); + } + } else { + // data response + if (!m_core[cid]->ldst_unit_response_buffer_full()) { + m_response_fifo.pop_front(); + m_memory_stats->memlatstat_read_done(mf); + m_core[cid]->accept_ldst_unit_response(mf); + } + } + } + + // pop from SST buffers + if (m_response_fifo.size() < m_config->n_simt_ejection_buffer_size) { + mem_fetch *mf = (mem_fetch *)(static_cast<sst_gpgpu_sim *>(get_gpu()) + ->SST_pop_mem_reply(m_cluster_id)); + if (!mf) return; + assert(mf->get_tpc() == m_cluster_id); + + // do atomic here + // For now, we execute atomic when the mem reply comes back + // This needs to be validated + if (mf && mf->isatomic()) mf->do_atomic(); + + unsigned int packet_size = + (mf->get_is_write()) ? mf->get_ctrl_size() : mf->size(); + m_stats->m_incoming_traffic_stats->record_traffic(mf, packet_size); + mf->set_status(IN_CLUSTER_TO_SHADER_QUEUE, + m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle); + // m_memory_stats->memlatstat_read_done(mf,m_shader_config->max_warps_per_shader); + m_response_fifo.push_back(mf); + m_stats->n_mem_to_simt[m_cluster_id] += mf->get_num_flits(false); + } +} + void simt_core_cluster::get_pdom_stack_top_info(unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc) const { |
