Hi all,
I am confused by some code in Ruby.


touch() is called in tryCacheAccess() if the incoming request hits in the L1 
cache, and it is called in allocate() if the request misses in the L1 cache,
and then it is called again by setMRU() in hitCallback() after the request is 
serviced by the memory system.
Note that hitCallback() is called by readCallback() which is triggered by each 
memory access (both hit and miss). Thus touch() is called twice for each access 
in L1 cache.
This will affect the replacement decisions, especially for some specific 
replacement policy. I wonder if it is intentionally designed this way? Correct 
me if I am wrong. 


00145 CacheMemory::tryCacheAccess(const Address& address, RubyRequestType type,
00146                             DataBlock*& data_ptr)
00147 {
00148     assert(address == line_address(address));
00149     DPRINTF(RubyCache, "address: %s\n", address);
00150     Index cacheSet = addressToCacheSet(address);
00151     int loc = findTagInSet(cacheSet, address);
00152     if (loc != -1) {
00153         // Do we even have a tag match?
00154         AbstractCacheEntry* entry = m_cache[cacheSet][loc];
00155         m_replacementPolicy_ptr->touch(cacheSet, loc, curTick());
00156         data_ptr = &(entry->getDataBlk());
00157 
00158         if (entry->m_Permission == AccessPermission_Read_Write) {
00159             return true;
00160         }
00161         if ((entry->m_Permission == AccessPermission_Read_Only) &&
00162             (type == RubyRequestType_LD || type == 
RubyRequestType_IFETCH)) {
00163             return true;
00164         }
00165         // The line must not be accessible
00166     }
00167     data_ptr = NULL;
00168     return false;
00169 }


00236 AbstractCacheEntry*
00237 CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry)
00238 {
00239     assert(address == line_address(address));
00240     assert(!isTagPresent(address));
00241     assert(cacheAvail(address));
00242     DPRINTF(RubyCache, "address: %s\n", address);
00243 
00244     // Find the first open slot
00245     Index cacheSet = addressToCacheSet(address);
00246     std::vector<AbstractCacheEntry*> &set = m_cache[cacheSet];
00247     for (int i = 0; i < m_cache_assoc; i++) {
00248         if (!set[i] || set[i]->m_Permission == 
AccessPermission_NotPresent) {
00249             set[i] = entry;  // Init entry
00250             set[i]->m_Address = address;
00251             set[i]->m_Permission = AccessPermission_Invalid;
00252             DPRINTF(RubyCache, "Allocate clearing lock for addr: %x\n",
00253                     address);
00254             set[i]->m_locked = -1;
00255             m_tag_index[address] = i;
00256 
00257             m_replacementPolicy_ptr->touch(cacheSet, i, curTick());
00258 
00259             return entry;
00260         }
00261     }
00262     panic("Allocate didn't find an available entry");
00263 }




00494 void
00495 Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data,
00496                        bool llscSuccess,
00497                        const MachineType mach, const bool externalHit,
00498                        const Cycles initialRequestTime,
00499                        const Cycles forwardRequestTime,
00500                        const Cycles firstResponseTime)
00501 {
00502     PacketPtr pkt = srequest->pkt;
00503     Address request_address(pkt->getAddr());
00504     Address request_line_address(pkt->getAddr());
00505     request_line_address.makeLineAddress();
00506     RubyRequestType type = srequest->m_type;
00507     Cycles issued_time = srequest->issue_time;
00508 
00509     // Set this cache entry to the most recently used
00510     if (type == RubyRequestType_IFETCH) {
00511         m_instCache_ptr->setMRU(request_line_address);
00512     } else {
00513         m_dataCache_ptr->setMRU(request_line_address);
00514     }


00470 void
00471 Sequencer::readCallback(const Address& address, DataBlock& data,
00472                         bool externalHit, const MachineType mach,
00473                         Cycles initialRequestTime,
00474                         Cycles forwardRequestTime,
00475                         Cycles firstResponseTime)
00476 {
00477     assert(address == line_address(address));
00478     assert(m_readRequestTable.count(line_address(address)));
00479 
00480     RequestTable::iterator i = m_readRequestTable.find(address);
00481     assert(i != m_readRequestTable.end());
00482     SequencerRequest* request = i->second;
00483 
00484     m_readRequestTable.erase(i);
00485     markRemoved();
00486 
00487     assert((request->m_type == RubyRequestType_LD) ||
00488            (request->m_type == RubyRequestType_IFETCH));
00489 
00490     hitCallback(request, data, true, mach, externalHit,
00491                 initialRequestTime, forwardRequestTime, 
firstResponseTime);
00492 }


Xuhao Chen
224 Coordinated Science Lab
Electrical and Computer Engineering
University of Illinois at Urbana-Champaign                                      
  
_______________________________________________
gem5-users mailing list
[email protected]
http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users

Reply via email to