diff options
Diffstat (limited to 'src/gpgpu-sim/shader.cc')
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 128 |
1 files changed, 75 insertions, 53 deletions
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 730cb6d..cddd0a3 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -2282,32 +2282,40 @@ bool ldst_unit::memory_cycle(warp_inst_t &inst, // bypass L1 cache unsigned control_size = 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_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 = - m_mf_allocator->alloc(inst, access, - m_core->get_gpu()->gpu_sim_cycle + - m_core->get_gpu()->gpu_tot_sim_cycle); - m_icnt->push(mf); - inst.accessq_pop_back(); - // inst.clear_active( access.get_warp_mask() ); - if (inst.is_load()) { - for (unsigned r = 0; r < MAX_OUTPUT_VALUES; r++) - if (inst.out[r] > 0) - assert(m_pending_writes[inst.warp_id()][inst.out[r]] > 0); - } else if (inst.is_store()) - m_core->inc_store_req(inst.warp_id()); + for (unsigned i = 0; i < m_config->m_L1D_config.l1_banks; i++) { + if (inst.accessq_empty()) { + break; + } + const mem_access_t &access = inst.accessq_back(); + unsigned size = access.get_size() + control_size; + // printf("Interconnect:Addr: %x, size=%d\n",access.get_addr(),size); + 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; + break; + } else if (!m_memory_config->SST_mode && + (m_icnt->full(size, inst.is_store() || inst.isatomic()))) { + stall_cond = ICNT_RC_FAIL; + break; + } else { + mem_fetch *mf = + m_mf_allocator->alloc(inst, access, + m_core->get_gpu()->gpu_sim_cycle + + m_core->get_gpu()->gpu_tot_sim_cycle); + m_icnt->push(mf); + inst.accessq_pop_back(); + // inst.clear_active( access.get_warp_mask() ); + if (inst.is_load()) { + for (unsigned r = 0; r < MAX_OUTPUT_VALUES; r++) + if (inst.out[r] > 0) + assert(m_pending_writes[inst.warp_id()][inst.out[r]] > 0); + } else if (inst.is_store()) + m_core->inc_store_req(inst.warp_id()); + } } } else { assert(CACHE_UNDEFINED != inst.cache_op); @@ -4534,41 +4542,55 @@ unsigned simt_core_cluster::get_n_active_sms() const { } unsigned simt_core_cluster::issue_block2core() { + const unsigned max_pending_ctas = 4; + for (unsigned core = 0; core < m_config->n_simt_cores_per_cluster; core++) { + if (m_core[core]->pending_ctas.size() < max_pending_ctas) { + kernel_info_t *kernel; + // Jin: fetch kernel according to concurrent kernel setting + if (m_config->gpgpu_concurrent_kernel_sm) { // concurrent kernel on sm + // always select latest issued kernel + kernel_info_t *k = m_gpu->select_kernel(); + kernel = k; + } else { + // first select core kernel, if no more cta, get a new kernel + // only when core completes + kernel = m_core[core]->get_kernel(); + if (!m_gpu->kernel_more_cta_left(kernel)) { + // wait till current kernel finishes + if (m_core[core]->get_not_completed() == 0 && + m_core[core]->pending_ctas.empty()) { + kernel_info_t *k = m_gpu->select_kernel(); + if (k) m_core[core]->set_kernel(k); + kernel = k; + } + } + } + if (kernel) { + if (kernel->allocated_ctas < kernel->num_blocks()) { + m_core[core]->pending_ctas.push_back(kernel); + kernel->allocated_ctas++; + } + } + } + } + unsigned num_blocks_issued = 0; for (unsigned i = 0; i < m_config->n_simt_cores_per_cluster; i++) { unsigned core = (i + m_cta_issue_next_core + 1) % m_config->n_simt_cores_per_cluster; - kernel_info_t *kernel; - // Jin: fetch kernel according to concurrent kernel setting - if (m_config->gpgpu_concurrent_kernel_sm) { // concurrent kernel on sm - // always select latest issued kernel - kernel_info_t *k = m_gpu->select_kernel(); - kernel = k; - } else { - // first select core kernel, if no more cta, get a new kernel - // only when core completes - kernel = m_core[core]->get_kernel(); - if (!m_gpu->kernel_more_cta_left(kernel)) { - // wait till current kernel finishes - if (m_core[core]->get_not_completed() == 0) { - kernel_info_t *k = m_gpu->select_kernel(); - if (k) m_core[core]->set_kernel(k); - kernel = k; - } + if (m_core[core]->pending_ctas.size() > 0) { + kernel_info_t *pending_cta = m_core[core]->pending_ctas.front(); + if (m_core[core]->can_issue_1block(*pending_cta)) { + m_core[core]->issue_block2core(*pending_cta); + m_core[core]->pending_ctas.pop_front(); + num_blocks_issued++; + m_cta_issue_next_core = core; + break; } } - - if (m_gpu->kernel_more_cta_left(kernel) && - // (m_core[core]->get_n_active_cta() < - // m_config->max_cta(*kernel)) ) { - m_core[core]->can_issue_1block(*kernel)) { - m_core[core]->issue_block2core(*kernel); - num_blocks_issued++; - m_cta_issue_next_core = core; - break; - } } + return num_blocks_issued; } |
