summaryrefslogtreecommitdiff
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.cc135
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 {