From b09eeed6aa36239f661d6452e996e3e5f8ef5984 Mon Sep 17 00:00:00 2001 From: Tayler Hetherington Date: Wed, 19 Sep 2012 14:51:45 -0800 Subject: Revision #2 of modifying the cache hierarchy. Separated the L1 and L2 cache access() implementations. Removed PRIVATE/SHARED cache scope configurations. Added WRITE_EVICT cache write policy. [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 14109] --- src/gpgpu-sim/gpu-cache.cc | 277 ++++++++++++++++++++++++++++----------------- src/gpgpu-sim/gpu-cache.h | 85 ++++++++------ src/gpgpu-sim/l2cache.cc | 2 +- src/gpgpu-sim/l2cache.h | 2 +- src/gpgpu-sim/shader.cc | 2 +- src/gpgpu-sim/shader.h | 2 +- 6 files changed, 232 insertions(+), 138 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index c36b5e0..23e6ede 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -336,17 +336,17 @@ void baseline_cache::display_state( FILE *fp ) const{ } /// Read miss handler without writeback -void baseline_cache::read_request(new_addr_type addr, new_addr_type block_addr, unsigned cache_index, mem_fetch *mf, - unsigned time, bool &do_miss, std::list &events, bool read_only){ +void baseline_cache::send_read_request(new_addr_type addr, new_addr_type block_addr, unsigned cache_index, mem_fetch *mf, + unsigned time, bool &do_miss, std::list &events, bool read_only, bool wa){ bool wb=false; cache_block_t e; - read_request(addr, block_addr, cache_index, mf, time, do_miss, wb, e, events, read_only); + send_read_request(addr, block_addr, cache_index, mf, time, do_miss, wb, e, events, read_only, wa); } /// Read miss handler. Check MSHR hit or MSHR available -void baseline_cache::read_request(new_addr_type addr, new_addr_type block_addr, unsigned cache_index, mem_fetch *mf, - unsigned time, bool &do_miss, bool &wb, cache_block_t &evicted, std::list &events, bool read_only){ +void baseline_cache::send_read_request(new_addr_type addr, new_addr_type block_addr, unsigned cache_index, mem_fetch *mf, + unsigned time, bool &do_miss, bool &wb, cache_block_t &evicted, std::list &events, bool read_only, bool wa){ bool mshr_hit = m_mshrs.probe(block_addr); bool mshr_avail = !m_mshrs.full(block_addr); @@ -369,12 +369,76 @@ void baseline_cache::read_request(new_addr_type addr, new_addr_type block_addr, mf->set_data_size( m_config.get_line_sz() ); m_miss_queue.push_back(mf); mf->set_status(m_miss_queue_status,time); - events.push_back(READ_REQUEST_SENT); + if(!wa) + events.push_back(READ_REQUEST_SENT); do_miss = true; } } +/// Sends write request to lower level memory (write or writeback) +void data_cache::send_write_request(mem_fetch *mf, cache_event request, unsigned time, std::list &events){ + events.push_back(request); + m_miss_queue.push_back(mf); + mf->set_status(m_miss_queue_status,time); +} + +/// Sends read request, and possible write-back request, to lower level memory for a write miss with write-allocate +bool data_cache::send_write_allocate(mem_fetch *mf, new_addr_type addr, new_addr_type block_addr, unsigned cache_index, unsigned time, std::list &events){ + const mem_access_t *ma = new mem_access_t( L2_WR_ALLOC_R, + mf->get_addr(), + mf->get_data_size(), + false, // Now performing a read + mf->get_access_warp_mask(), + mf->get_access_byte_mask() ); + + 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()); + + bool do_miss = false; + bool wb = false; + cache_block_t evicted; + + // Send read request resulting from write miss + send_read_request(addr, block_addr, cache_index, n_mf, time, do_miss, wb, evicted, events, false, true); + + if( wb ) { // If evicted block is modified + mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr,L2_WRBK_ACC,m_config.get_line_sz(),true); + m_miss_queue.push_back(wb); + wb->set_status(m_miss_queue_status,time); + } + if( do_miss ) + return true; + return false; + +} + +/// Marks block as MODIFIED and updates block LRU +void data_cache::write_back_hit(new_addr_type block_addr, unsigned time, unsigned cache_index){ + m_tag_array.access(block_addr,time,cache_index); // update LRU state + cache_block_t &block = m_tag_array.get_block(cache_index); + block.m_status = MODIFIED; +} + +/// Marks block as INVALID and sends write request to lower level memory +bool data_cache::do_write_evict(mem_fetch *mf, unsigned time, unsigned cache_index, std::list &events){ + if(miss_queue_full(0)) + return false; // cannot handle request this cycle + + // generate a write-through/evict + cache_block_t &block = m_tag_array.get_block(cache_index); + send_write_request(mf, WRITE_REQUEST_SENT, time, events); + + // Invalidate block + block.m_status = INVALID; + return true; +} + /// Access cache for read_only_cache: returns RESERVATION_FAIL if request could not be accepted (for any reason) enum cache_request_status read_only_cache::access( new_addr_type addr, mem_fetch *mf, unsigned time, std::list &events ) { assert( mf->get_data_size() <= m_config.get_line_sz()); @@ -391,7 +455,7 @@ enum cache_request_status read_only_cache::access( new_addr_type addr, mem_fetch if ( status != RESERVATION_FAIL ) { if(!miss_queue_full(0)){ bool do_miss=false; - read_request(addr, block_addr, cache_index, mf, time, do_miss, events, true); + send_read_request(addr, block_addr, cache_index, mf, time, do_miss, events, true, false); if(do_miss) return MISS; } @@ -399,132 +463,141 @@ enum cache_request_status read_only_cache::access( new_addr_type addr, mem_fetch return RESERVATION_FAIL; } - /// This is meant to model the first level data cache in Fermi. /// It is write-evict (global) or write-back (local) at the granularity of individual blocks -/// for L1 and full write-back for L2 (the policy used in fermi according to the CUDA manual) -enum cache_request_status data_cache::access( new_addr_type addr, mem_fetch *mf, unsigned time, std::list &events ){ - assert( mf->get_data_size() <= m_config.get_line_sz()); - - bool wr = mf->get_is_write(); +/// (the policy used in fermi according to the CUDA manual) +enum cache_request_status l1_cache::access( new_addr_type addr, mem_fetch *mf, unsigned time, std::list &events ){ + assert( mf->get_data_size() <= m_config.get_line_sz()); + bool wr = mf->get_is_write(); bool isatomic = mf->isatomic(); enum mem_access_type type = mf->get_access_type(); + bool evict = (type == GLOBAL_ACC_W); // evict a line that hits on global memory write + new_addr_type block_addr = m_config.block_addr(addr); unsigned cache_index = (unsigned)-1; enum cache_request_status status = m_tag_array.probe(block_addr,cache_index); - if ( status == HIT ) { - // If write through policy or private cache with global write hit - if(wr && (m_config.m_write_policy == WRITE_THROUGH || - ( (m_config.m_cache_scope == PRIVATE) && (type == GLOBAL_ACC_W) ))){ - // Write through - if(miss_queue_full(0)) - return RESERVATION_FAIL; // cannot handle request this cycle - - // generate a write through - cache_block_t &block = m_tag_array.get_block(cache_index); - write_request(mf, WRITE_REQUEST_SENT, time, events); + if(wr){ // Write + assert(m_config.m_write_policy != READ_ONLY); + if(status == HIT){ + if(m_config.m_write_policy == WRITE_BACK && !evict){ + write_back_hit(block_addr, time, cache_index); + }else if(m_config.m_write_policy == WRITE_EVICT || evict){ + if(!do_write_evict(mf, time, cache_index, events)) + return RESERVATION_FAIL; + } + return HIT; + }else if ( status != RESERVATION_FAIL ) { + if(miss_queue_full(0)) + return RESERVATION_FAIL; // cannot handle request this cycle + // on miss, generate write through (no write buffering -- too many threads for that) + send_write_request(mf, WRITE_REQUEST_SENT, time, events); + return MISS; + } + }else{ // Read + if(status == HIT){ // Read hit: Update LRU state + m_tag_array.access(block_addr,time,cache_index); + if(isatomic){ // Atomics treated as global read/write requests - Perform read, mark line as MODIFIED + assert(type == GLOBAL_ACC_R); + cache_block_t &block = m_tag_array.get_block(cache_index); + block.m_status = MODIFIED; // mark line as dirty + } + return HIT; + }else if ( status != RESERVATION_FAIL ) { + if(miss_queue_full(1)) + return RESERVATION_FAIL; // cannot handle request this cycle (might need to generate two requests) - // invalidate block - block.m_status = INVALID; + bool do_miss = false; + bool wb = false; + cache_block_t evicted; + send_read_request(addr, block_addr, cache_index, mf, time, do_miss, wb, evicted, events, false, false); - }else{ // Write back cache or global read hit - m_tag_array.access(block_addr,time,cache_index); // update LRU state - if ( wr ) { - assert( type == LOCAL_ACC_W || type == L1_WRBK_ACC || m_config.m_cache_scope == SHARED); - // treated as write back... - cache_block_t &block = m_tag_array.get_block(cache_index); - block.m_status = MODIFIED; - } else if ( isatomic ) { - assert( type == GLOBAL_ACC_R ); - // treated as write back... - cache_block_t &block = m_tag_array.get_block(cache_index); - block.m_status = MODIFIED; // mark line as dirty + if(wb){ + mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr, L1_WRBK_ACC,m_config.get_line_sz(),true); + send_write_request(wb, WRITE_BACK_REQUEST_SENT, time, events); } - } - return HIT; - } else if ( status != RESERVATION_FAIL ) { - if ( wr ) { - if(m_config.m_write_aclloc_policy == NO_WRITE_ALLOCATE){ - // No write allocate, maximum 1 requests - if(miss_queue_full(0)) - return RESERVATION_FAIL; // cannot handle request this cycle - }else{ + if( do_miss ) + return MISS; + } + } + return RESERVATION_FAIL; +} + +/// Models second level shared cache with global write-back and write-allocate policies +enum cache_request_status l2_cache::access( new_addr_type addr, mem_fetch *mf, unsigned time, std::list &events ){ + assert( mf->get_data_size() <= m_config.get_line_sz()); + bool wr = mf->get_is_write(); + bool isatomic = mf->isatomic(); + enum mem_access_type type = mf->get_access_type(); + + new_addr_type block_addr = m_config.block_addr(addr); + unsigned cache_index = (unsigned)-1; + enum cache_request_status status = m_tag_array.probe(block_addr,cache_index); + + if(wr){ // Write + assert(m_config.m_write_policy != READ_ONLY); + if(status == HIT){ + if(m_config.m_write_policy == WRITE_BACK){ + write_back_hit(block_addr, time, cache_index); + }else if(m_config.m_write_policy == WRITE_EVICT){ + assert(0); + if(!do_write_evict(mf, time, cache_index, events)) + return RESERVATION_FAIL; + } + return HIT; + }else if ( status != RESERVATION_FAIL ) { + if(m_config.m_write_alloc_policy == WRITE_ALLOCATE){ // Write allocate, maximum 3 requests (write miss, read request, write back request) // Conservatively ensure the worst-case request can be handled this cycle bool mshr_hit = m_mshrs.probe(block_addr); bool mshr_avail = !m_mshrs.full(block_addr); - if(miss_queue_full(2) || - ( !(mshr_hit && mshr_avail) && !(!mshr_hit && mshr_avail && (m_miss_queue.size() < m_config.m_miss_queue_size)) ) ) + if(miss_queue_full(2) || (!(mshr_hit && mshr_avail) && !(!mshr_hit && mshr_avail && (m_miss_queue.size() < m_config.m_miss_queue_size)))) return RESERVATION_FAIL; - } - - // on miss, generate write through (no write buffering -- too many threads for that) - write_request(mf, WRITE_REQUEST_SENT, time, events); - - // If no write allocate, simply return miss - if(m_config.m_write_aclloc_policy == NO_WRITE_ALLOCATE) - return MISS; - - // Write allocate - Generate new read miss - const mem_access_t *ma = new mem_access_t( L2_WR_ALLOC_R, - mf->get_addr(), - mf->get_data_size(), - false, // Now performing a read - mf->get_access_warp_mask(), - mf->get_access_byte_mask() ); - - 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()); - - bool do_miss = false; - bool wb = false; - cache_block_t evicted; - - // Send read request resulting from write miss - read_request(addr, block_addr, cache_index, n_mf, time, do_miss, wb, evicted, events, false); - - if( wb ) { // If evicted block is modified - mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr,L2_WRBK_ACC,m_config.get_line_sz(),true); - m_miss_queue.push_back(wb); - wb->set_status(m_miss_queue_status,time); - } - if( do_miss ) - return MISS; - return RESERVATION_FAIL; - } else { + send_write_request(mf, WRITE_REQUEST_SENT, time, events); + // Tries to send write allocate request, returns true on success and false on failure + if(!send_write_allocate(mf, addr, block_addr, cache_index, time, events)) + return RESERVATION_FAIL; + }else{ + if(miss_queue_full(0)) + return RESERVATION_FAIL; // cannot handle request this cycle + + // on miss, generate write through (no write buffering -- too many threads for that) + send_write_request(mf, WRITE_REQUEST_SENT, time, events); + } + return MISS; + } + }else{ // Read + if(status == HIT){ // Read hit: Update LRU state + m_tag_array.access(block_addr,time,cache_index); + if(isatomic){ // Atomics treated as global read/write requests - Perform read, mark line as MODIFIED + assert(type == GLOBAL_ACC_R); + // treated as write back... + cache_block_t &block = m_tag_array.get_block(cache_index); + block.m_status = MODIFIED; // mark line as dirty + } + return HIT; + }else if ( status != RESERVATION_FAIL ) { if(miss_queue_full(1)) return RESERVATION_FAIL; // cannot handle request this cycle (might need to generate two requests) bool do_miss = false; bool wb = false; cache_block_t evicted; - read_request(addr, block_addr, cache_index, mf, time, do_miss, wb, evicted, events, false); + send_read_request(addr, block_addr, cache_index, mf, time, do_miss, wb, evicted, events, false, false); if(wb){ mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr, L1_WRBK_ACC,m_config.get_line_sz(),true); - write_request(wb, WRITE_BACK_REQUEST_SENT, time, events); + send_write_request(wb, WRITE_BACK_REQUEST_SENT, time, events); } if( do_miss ) - return MISS; - } - } - return RESERVATION_FAIL; + return MISS; + } + } + return RESERVATION_FAIL; } -/// Sends write request to lower level memory (write or writeback) -void data_cache::write_request(mem_fetch *mf, cache_event request, unsigned time, std::list &events){ - events.push_back(request); - m_miss_queue.push_back(mf); - mf->set_status(m_miss_queue_status,time); -} /// Access function for tex_cache /// return values: RESERVATION_FAIL if request could not be accepted diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 666b9a1..431760a 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -97,7 +97,8 @@ enum replacement_policy_t { enum write_policy_t { READ_ONLY, WRITE_BACK, - WRITE_THROUGH + WRITE_THROUGH, + WRITE_EVICT }; enum allocation_policy_t { @@ -111,11 +112,6 @@ enum write_allocate_policy_t { WRITE_ALLOCATE }; -enum cache_scope_t { - PRIVATE, // Local cache: If write-back, global writes are write through - SHARED // Global cache: If write-back, all writes are write-back -}; - enum mshr_config_t { TEX_FIFO, ASSOC // normal cache @@ -132,11 +128,11 @@ public: void init() { assert( m_config_string ); - char rp, wp, ap, mshr_type, scope, wap; + char rp, wp, ap, mshr_type, wap; - int ntok = sscanf(m_config_string,"%u:%u:%u:%c:%c:%c:%c:%c:%c:%u:%u:%u:%u", + int ntok = sscanf(m_config_string,"%u:%u:%u:%c:%c:%c:%c:%c:%u:%u:%u:%u", &m_nset, &m_line_sz, &m_assoc, &rp, &wp, &ap, - &mshr_type, &scope, &wap, &m_mshr_entries,&m_mshr_max_merge, + &mshr_type, &wap, &m_mshr_entries,&m_mshr_max_merge, &m_miss_queue_size,&m_result_fifo_entries); if ( ntok < 10 ) { @@ -155,6 +151,7 @@ public: case 'R': m_write_policy = READ_ONLY; break; case 'B': m_write_policy = WRITE_BACK; break; case 'T': m_write_policy = WRITE_THROUGH; break; + case 'E': m_write_policy = WRITE_EVICT; break; default: exit_parse_error(); } switch (ap) { @@ -163,7 +160,7 @@ public: default: exit_parse_error(); } switch (mshr_type) { - case 'F': m_mshr_type = TEX_FIFO; assert(ntok==13); break; + case 'F': m_mshr_type = TEX_FIFO; assert(ntok==12); break; case 'A': m_mshr_type = ASSOC; break; default: exit_parse_error(); } @@ -171,14 +168,9 @@ public: m_nset_log2 = LOGB2(m_nset); m_valid = true; - switch(scope){ - case 'P': m_cache_scope = PRIVATE; break; - case 'S': m_cache_scope = SHARED; break; - default: exit_parse_error(); - } switch(wap){ - case 'W': m_write_aclloc_policy = WRITE_ALLOCATE; break; - case 'N': m_write_aclloc_policy = NO_WRITE_ALLOCATE; break; + case 'W': m_write_alloc_policy = WRITE_ALLOCATE; break; + case 'N': m_write_alloc_policy = NO_WRITE_ALLOCATE; break; default: exit_parse_error(); } } @@ -236,8 +228,7 @@ private: enum allocation_policy_t m_alloc_policy; // 'm' = allocate on miss, 'f' = allocate on fill enum mshr_config_t m_mshr_type; - cache_scope_t m_cache_scope; // 'P' = PRIVATE, 'S' = SHARED - write_allocate_policy_t m_write_aclloc_policy; // 'W' = Write allocate, 'N' = No write allocate + write_allocate_policy_t m_write_alloc_policy; // 'W' = Write allocate, 'N' = No write allocate union { unsigned m_mshr_entries; @@ -258,6 +249,8 @@ private: friend class read_only_cache; friend class tex_cache; friend class data_cache; + friend class l1_cache; + friend class l2_cache; }; class tag_array { @@ -373,6 +366,7 @@ public: m_miss_queue_status = status; } + virtual enum cache_request_status access( new_addr_type addr, mem_fetch *mf, unsigned time, std::list &events ) = 0; /// Sends next request to lower level of memory void cycle(); /// Interface for response from lower memory level (model bandwidth restictions in caller) @@ -421,11 +415,11 @@ public: return ( (m_miss_queue.size()+num_miss) >= m_config.m_miss_queue_size ); } /// Read miss handler without writeback - void read_request(new_addr_type addr, new_addr_type block_addr, unsigned cache_index, mem_fetch *mf, - unsigned time, bool &do_miss, std::list &events, bool read_only); + void send_read_request(new_addr_type addr, new_addr_type block_addr, unsigned cache_index, mem_fetch *mf, + unsigned time, bool &do_miss, std::list &events, bool read_only, bool wa); /// Read miss handler. Check MSHR hit or MSHR available - void read_request(new_addr_type addr, new_addr_type block_addr, unsigned cache_index, mem_fetch *mf, - unsigned time, bool &do_miss, bool &wb, cache_block_t &evicted, std::list &events, bool read_only); + void send_read_request(new_addr_type addr, new_addr_type block_addr, unsigned cache_index, mem_fetch *mf, + unsigned time, bool &do_miss, bool &wb, cache_block_t &evicted, std::list &events, bool read_only, bool wa); }; /// Read only cache @@ -438,10 +432,7 @@ public: virtual enum cache_request_status access( new_addr_type addr, mem_fetch *mf, unsigned time, std::list &events ); }; -/// Data cache -/// This is meant to model the first level data cache in Fermi. -/// It is write-evict (global) or write-back (local) at the granularity of individual blocks -/// for L1 and full write-back for L2 (the policy used in fermi according to the CUDA manual) +/// Data cache - Implements common functions for L1 and L2 data cache class data_cache : public baseline_cache { public: data_cache( const char *name, const cache_config &config, @@ -452,13 +443,43 @@ public: m_memfetch_creator=mfcreator; } - virtual enum cache_request_status access( new_addr_type addr, mem_fetch *mf, unsigned time, std::list &events ); - - private: +protected: mem_fetch_allocator *m_memfetch_creator; - // Private functions for data cache access - void write_request(mem_fetch *mf, cache_event request, unsigned time, std::list &events); + // Functions for data cache access + /// Sends write request to lower level memory (write or writeback) + void send_write_request(mem_fetch *mf, cache_event request, unsigned time, std::list &events); + /// Sends read request, and possible write-back request, to lower level memory for a write miss with write-allocate + bool send_write_allocate(mem_fetch *mf, new_addr_type addr, new_addr_type block_addr, unsigned cache_index, unsigned time, std::list &events); + /// Marks block as MODIFIED and updates block LRU + void write_back_hit(new_addr_type block_addr, unsigned time, unsigned cache_index); + /// Marks block as INVALID and sends write request to lower level memory + bool do_write_evict(mem_fetch *mf, unsigned time, unsigned cache_index, std::list &events); +}; + +/// This is meant to model the first level data cache in Fermi. +/// It is write-evict (global) or write-back (local) at the granularity of individual blocks +/// (the policy used in fermi according to the CUDA manual) +class l1_cache : public data_cache { +public: + l1_cache(const char *name, const cache_config &config, + int core_id, int type_id, mem_fetch_interface *memport, + mem_fetch_allocator *mfcreator, enum mem_fetch_status status ) + : data_cache(name,config,core_id,type_id,memport,mfcreator,status){} + + virtual enum cache_request_status access( new_addr_type addr, mem_fetch *mf, unsigned time, std::list &events ); +}; + +/// Models second level shared cache with global write-back and write-allocate policies +class l2_cache : public data_cache { +public: + l2_cache(const char *name, const cache_config &config, + int core_id, int type_id, mem_fetch_interface *memport, + mem_fetch_allocator *mfcreator, enum mem_fetch_status status ) + : data_cache(name,config,core_id,type_id,memport,mfcreator,status){} + + virtual enum cache_request_status access( new_addr_type addr, mem_fetch *mf, unsigned time, std::list &events ); + }; /********************************************************************************************************************************************************/ diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index a580052..c03c47f 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -74,7 +74,7 @@ memory_partition_unit::memory_partition_unit( unsigned partition_id, m_mf_allocator = new partition_mf_allocator(config); if(!m_config->m_L2_config.disabled()) - m_L2cache = new data_cache(L2c_name,m_config->m_L2_config,-1,-1,m_L2interface,m_mf_allocator,IN_PARTITION_L2_MISS_QUEUE); + m_L2cache = new l2_cache(L2c_name,m_config->m_L2_config,-1,-1,m_L2interface,m_mf_allocator,IN_PARTITION_L2_MISS_QUEUE); unsigned int icnt_L2; unsigned int L2_dram; diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h index 22640b8..c2c624f 100644 --- a/src/gpgpu-sim/l2cache.h +++ b/src/gpgpu-sim/l2cache.h @@ -82,7 +82,7 @@ private: unsigned m_id; const struct memory_config *m_config; class dram_t *m_dram; - class data_cache *m_L2cache; + class l2_cache *m_L2cache; class L2interface *m_L2interface; partition_mf_allocator *m_mf_allocator; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 7b65add..0dd8fd0 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -1122,7 +1122,7 @@ ldst_unit::ldst_unit( mem_fetch_interface *icnt, m_L1C = new read_only_cache(L1C_name,m_config->m_L1C_config,m_sid,get_shader_constant_cache_id(),icnt,IN_L1C_MISS_QUEUE); m_L1D = NULL; if( !m_config->m_L1D_config.disabled() ) - m_L1D = new data_cache(L1D_name,m_config->m_L1D_config,m_sid,get_shader_normal_cache_id(),m_icnt,m_mf_allocator,IN_L1D_MISS_QUEUE); + m_L1D = new l1_cache(L1D_name,m_config->m_L1D_config,m_sid,get_shader_normal_cache_id(),m_icnt,m_mf_allocator,IN_L1D_MISS_QUEUE); m_mem_rc = NO_RC_FAIL; m_num_writeback_clients=5; // = shared memory, global/local (uncached), L1D, L1T, L1C m_writeback_arb = 0; diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 078633d..262a3be 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -922,7 +922,7 @@ private: tex_cache *m_L1T; // texture cache read_only_cache *m_L1C; // constant cache - data_cache *m_L1D; // data cache + l1_cache *m_L1D; // data cache std::map > m_pending_writes; std::list m_response_fifo; opndcoll_rfu_t *m_operand_collector; -- cgit v1.3