From eae030c9d1d607d1c14e4ade99cb5caea6403efd Mon Sep 17 00:00:00 2001 From: aamir Date: Sat, 3 Nov 2018 17:03:58 -0700 Subject: merged with memory subsytem. Regression is passing but tensorcore kernel is stuck in deadlock --- src/gpgpu-sim/l2cache.cc | 166 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 142 insertions(+), 24 deletions(-) (limited to 'src/gpgpu-sim/l2cache.cc') diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index c5fc44e..25da107 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -74,6 +74,15 @@ memory_partition_unit::memory_partition_unit( unsigned partition_id, } } +void memory_partition_unit::handle_memcpy_to_gpu( size_t addr, unsigned global_subpart_id, mem_access_sector_mask_t mask ) +{ + unsigned p = global_sub_partition_id_to_local_id(global_subpart_id); + std::string mystring = + mask.to_string(); + MEMPART_DPRINTF("Copy Engine Request Received For Address=%llx, local_subpart=%u, global_subpart=%u, sector_mask=%s \n", addr, p, global_subpart_id, mystring.c_str()); + m_sub_partition[p]->force_l2_tag_update(addr,gpu_sim_cycle+gpu_tot_sim_cycle, mask); +} + memory_partition_unit::~memory_partition_unit() { delete m_dram; @@ -93,7 +102,9 @@ memory_partition_unit::arbitration_metadata::arbitration_metadata(const struct m m_private_credit_limit = 1; m_shared_credit_limit = config->gpgpu_frfcfs_dram_sched_queue_size + config->gpgpu_dram_return_queue_size - - (config->m_n_sub_partition_per_memory_channel - 1); + - (config->m_n_sub_partition_per_memory_channel - 1); + if(config->seperate_write_queue_enabled ) + m_shared_credit_limit += config->gpgpu_frfcfs_dram_write_queue_size; if (config->gpgpu_frfcfs_dram_sched_queue_size == 0 or config->gpgpu_dram_return_queue_size == 0) { @@ -220,7 +231,8 @@ void memory_partition_unit::dram_cycle() m_dram->cycle(); m_dram->dram_log(SAMPLELOG); - if( !m_dram->full() ) { + // mem_fetch *mf = m_sub_partition[spid]->L2_dram_queue_top(); + //if( !m_dram->full(mf->is_write()) ) { // L2->DRAM queue to DRAM latency queue // Arbitrate among multiple L2 subpartitions int last_issued_partition = m_arbitration_metadata.last_borrower(); @@ -228,6 +240,9 @@ void memory_partition_unit::dram_cycle() int spid = (p + last_issued_partition + 1) % m_config->m_n_sub_partition_per_memory_channel; if (!m_sub_partition[spid]->L2_dram_queue_empty() && can_issue_to_dram(spid)) { mem_fetch *mf = m_sub_partition[spid]->L2_dram_queue_top(); + if(m_dram->full(mf->is_write()) ) + break; + m_sub_partition[spid]->L2_dram_queue_pop(); MEMPART_DPRINTF("Issue mem_fetch request %p from sub partition %d to dram\n", mf, spid); dram_delay_t d; @@ -239,12 +254,13 @@ void memory_partition_unit::dram_cycle() break; // the DRAM should only accept one request per cycle } } - } + //} // DRAM latency queue - if( !m_dram_latency_queue.empty() && ( (gpu_sim_cycle+gpu_tot_sim_cycle) >= m_dram_latency_queue.front().ready_cycle ) && !m_dram->full() ) { - mem_fetch* mf = m_dram_latency_queue.front().req; - m_dram_latency_queue.pop_front(); + + if( !m_dram_latency_queue.empty() && ( (gpu_sim_cycle+gpu_tot_sim_cycle) >= m_dram_latency_queue.front().ready_cycle ) && !m_dram->full(m_dram_latency_queue.front().req->is_write()) ) { + mem_fetch* mf = m_dram_latency_queue.front().req; + m_dram_latency_queue.pop_front(); m_dram->push(mf); } } @@ -299,6 +315,7 @@ memory_sub_partition::memory_sub_partition( unsigned sub_partition_id, m_id = sub_partition_id; m_config=config; m_stats=stats; + m_memcpy_cycle_offset = 0; assert(m_id < m_config->m_n_mem_sub_partition); @@ -343,6 +360,14 @@ void memory_sub_partition::cache_cycle( unsigned cycle ) mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); m_L2_icnt_queue->push(mf); }else{ + if(m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE) + { + mem_fetch* original_wr_mf = mf->get_original_wr_mf(); + assert(original_wr_mf); + original_wr_mf->set_reply(); + original_wr_mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + m_L2_icnt_queue->push(original_wr_mf); + } m_request_tracker.erase(mf); delete mf; } @@ -355,10 +380,11 @@ void memory_sub_partition::cache_cycle( unsigned cycle ) if ( !m_config->m_L2_config.disabled() && m_L2cache->waiting_for_fill(mf) ) { if (m_L2cache->fill_port_free()) { mf->set_status(IN_PARTITION_L2_FILL_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); - m_L2cache->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle); + m_L2cache->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle+m_memcpy_cycle_offset); m_dram_L2_queue->pop(); } } else if ( !m_L2_icnt_queue->full() ) { + if(mf->is_write() && mf->get_type() == WRITE_ACK) mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); m_L2_icnt_queue->push(mf); m_dram_L2_queue->pop(); @@ -380,9 +406,10 @@ void memory_sub_partition::cache_cycle( unsigned cycle ) bool port_free = m_L2cache->data_port_free(); if ( !output_full && port_free ) { std::list events; - enum cache_request_status status = m_L2cache->access(mf->get_addr(),mf,gpu_sim_cycle+gpu_tot_sim_cycle,events); + enum cache_request_status status = m_L2cache->access(mf->get_addr(),mf,gpu_sim_cycle+gpu_tot_sim_cycle+m_memcpy_cycle_offset,events); bool write_sent = was_write_sent(events); bool read_sent = was_read_sent(events); + MEM_SUBPART_DPRINTF("Probing L2 cache Address=%llx, status=%u\n", mf->get_addr(), status); if ( status == HIT ) { if( !write_sent ) { @@ -402,6 +429,11 @@ void memory_sub_partition::cache_cycle( unsigned cycle ) m_icnt_L2_queue->pop(); } } else if ( status != RESERVATION_FAIL ) { + if(mf->is_write() && (m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE || m_config->m_L2_config.m_write_alloc_policy == LAZY_FETCH_ON_READ) && !was_writeallocate_sent(events)) { + mf->set_reply(); + mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + m_L2_icnt_queue->push(mf); + } // L2 cache accepted request m_icnt_L2_queue->pop(); } else { @@ -432,6 +464,11 @@ bool memory_sub_partition::full() const return m_icnt_L2_queue->full(); } +bool memory_sub_partition::full(unsigned size) const +{ + return m_icnt_L2_queue->is_avilable_size(size); +} + bool memory_sub_partition::L2_dram_queue_empty() const { return m_L2_dram_queue->empty(); @@ -532,7 +569,15 @@ unsigned memory_sub_partition::flushL2() if (!m_config->m_L2_config.disabled()) { m_L2cache->flush(); } - return 0; // L2 is read only in this version + return 0; //TODO: write the flushed data to the main memory +} + +unsigned memory_sub_partition::invalidateL2() +{ + if (!m_config->m_L2_config.disabled()) { + m_L2cache->invalidate(); + } + return 0; } bool memory_sub_partition::busy() const @@ -540,21 +585,94 @@ bool memory_sub_partition::busy() const return !m_request_tracker.empty(); } -void memory_sub_partition::push( mem_fetch* req, unsigned long long cycle ) -{ - if (req) { - m_request_tracker.insert(req); - m_stats->memlatstat_icnt2mem_pop(req); - if( req->istexture() ) { - m_icnt_L2_queue->push(req); - req->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); - } else { - rop_delay_t r; - r.req = req; - r.ready_cycle = cycle + m_config->rop_latency; - m_rop.push(r); - req->set_status(IN_PARTITION_ROP_DELAY,gpu_sim_cycle+gpu_tot_sim_cycle); - } +std::vector memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch* mf) +{ + std::vector result; + + if(mf->get_data_size() == SECTOR_SIZE && mf->get_access_sector_mask().count() == 1) { + result.push_back(mf); + } else if (mf->get_data_size() == 128 || mf->get_data_size() == 64) { + //We only accept 32, 64 and 128 bytes reqs + unsigned start=0, end=0; + if(mf->get_data_size() == 128) { + start=0; end=3; + } else if (mf->get_data_size() == 64 && mf->get_access_sector_mask().to_string() == "1100") { + start=2; end=3; + } else if (mf->get_data_size() == 64 && mf->get_access_sector_mask().to_string() == "0011") { + start=0; end=1; + } else if (mf->get_data_size() == 64 && (mf->get_access_sector_mask().to_string() == "1111" || mf->get_access_sector_mask().to_string() == "0000")) { + if(mf->get_addr() % 128 == 0) { + start=0; end=1; + } else { + start=2; end=3; + } + } else + { + printf("Invalid sector received, address = 0x%06x, sector mask = %s, data size = %d", + mf->get_addr(), mf->get_access_sector_mask(), mf->get_data_size()); + assert(0 && "Undefined sector mask is received"); + } + + std::bitset byte_sector_mask; + byte_sector_mask.reset(); + for(unsigned k=start*SECTOR_SIZE; k< SECTOR_SIZE; ++k) + byte_sector_mask.set(k); + + for(unsigned j=start, i=0; j<= end ; ++j, ++i){ + + const mem_access_t *ma = new mem_access_t( mf->get_access_type(), + mf->get_addr() + SECTOR_SIZE*i, + SECTOR_SIZE, + mf->is_write(), + mf->get_access_warp_mask(), + mf->get_access_byte_mask() & byte_sector_mask, + std::bitset().set(j)); + + mem_fetch *n_mf = new mem_fetch( *ma, + NULL, + mf->get_ctrl_size(), + mf->get_wid(), + mf->get_sid(), + mf->get_tpc(), + mf->get_mem_config(), + mf); + + result.push_back(n_mf); + byte_sector_mask <<= SECTOR_SIZE; + } + } else { + printf("Invalid sector received, address = 0x%06x, sector mask = %d, byte mask = , data size = %d", + mf->get_addr(), mf->get_access_sector_mask().count(), mf->get_data_size()); + assert(0 && "Undefined data size is received"); + } + + return result; +} + +void memory_sub_partition::push( mem_fetch* m_req, unsigned long long cycle ) +{ + if (m_req) { + m_stats->memlatstat_icnt2mem_pop(m_req); + std::vector reqs; + if(m_config->m_L2_config.m_cache_type == SECTOR) + reqs = breakdown_request_to_sector_requests(m_req); + else + reqs.push_back(m_req); + + for(unsigned i=0; iistexture() ) { + m_icnt_L2_queue->push(req); + req->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + } else { + rop_delay_t r; + r.req = req; + r.ready_cycle = cycle + m_config->rop_latency; + m_rop.push(r); + req->set_status(IN_PARTITION_ROP_DELAY,gpu_sim_cycle+gpu_tot_sim_cycle); + } + } } } -- cgit v1.3