示例#1
0
  virtual InvalidateReply writeRemoteAction( const DataAccess& access ) {
    cache_iter_t cacheIter;

    bool noOtherCachesHaveLine = true;
    for ( cacheIter = allCaches->begin(); cacheIter != allCaches->end(); cacheIter++ ) {
      SMPCache<State, Addr_t> *otherCache = *cacheIter;
      if ( otherCache->CPUId == this->CPUId ) {
        continue;
      }

      State* otherLine = NULL;
      CacheResponse r = otherCache->L1cache->search( access.addr(), otherLine );
      if ( r == MISSED_TO_MEMORY ) { // not found in this cache
        continue;
      }

      switch ( otherLine->getState() ) {
      case MESI_MODIFIED:
      case MESI_EXCLUSIVE:
      case MESI_SHARED:
        otherLine->invalidate();
        noOtherCachesHaveLine = false;
        // have to keep searching to find all Shared copies
        break;
      case MESI_INVALID:
        // keep searching for more copies
        break;
      default:
        assert(false);
      }
    } // done with other caches

    return InvalidateReply( noOtherCachesHaveLine );
  } // end writeRemoteAction()
示例#2
0
  virtual RemoteReadService readRemoteAction( const DataAccess& access ) {
    cache_iter_t cacheIter;
    for ( cacheIter = allCaches->begin(); cacheIter != allCaches->end(); cacheIter++ ) {
      SMPCache<State, Addr_t> *otherCache = *cacheIter;
      if ( otherCache->CPUId == this->CPUId ) {
        continue;
      }

      State* otherLine = NULL;
      CacheResponse r = otherCache->L1cache->search( access.addr(), otherLine );
      if ( r == MISSED_TO_MEMORY ) {
        continue; // not found in this cache
      }
      // found in a remote cache!

      switch ( otherLine->getState() ) {
      case MESI_EXCLUSIVE:
      case MESI_MODIFIED:
        otherLine->changeStateTo( MESI_SHARED );
        return RemoteReadService( false, true );
      case MESI_SHARED:
        // everyone else will be in Shared state as well, so return now
        return RemoteReadService( true, false );
      case MESI_INVALID:
        // keep searching for other copies
        break;
      default:
        assert(false);
      }

    } // done with other caches

    // this happens if everyone was MESI_INVALID
    return RemoteReadService( false, false );
  } // end readRemoteAction()
示例#3
0
  /** Make a write request.
   * @param access the memory access being made
   * @param doStoreBufferAccess whether to use the det store buffer for this write */
  virtual void write( const DataAccess& access, bool doStoreBufferAccess ) {
    State* myLine = NULL;
    CacheResponse r = L1cache->search( access.addr(), myLine );

    if ( r != MISSED_TO_MEMORY ) {

      switch (r) {
      case L1_HIT:
        timeInMemoryHierarchy += L1_HIT_LATENCY;
        // default det cache latency is an L1 hit, so it doesn't matter whether we hit to a dirty line or not
        deterministicTimeInMemoryHierarchy += L1_HIT_LATENCY;
        break;
      case L2_HIT: {
        timeInMemoryHierarchy += L2_HIT_LATENCY;
        if ( myLine->isDirty() ) {
          deterministicTimeInMemoryHierarchy += L2_HIT_LATENCY;
        } else {
          deterministicTimeInMemoryHierarchy += L1_HIT_LATENCY;
        }
        break;
      }
      case L3_HIT:
        timeInMemoryHierarchy += L3_HIT_LATENCY;
        // shared cache hits aren't det
        deterministicTimeInMemoryHierarchy += L1_HIT_LATENCY;
        break;
      default:
        assert(false);
      }

      // we either hit somewhere in our private cache(s) or we hit in the shared cache,
      // but we may not have write permissions
      L1cache->access( access.addr(), myLine );

      switch ( myLine->getState() ) {
      case MESI_SHARED: // upgrade miss
        numUpgradeMisses++;
        writeRemoteAction( access ); // invalidate other copies
        timeInMemoryHierarchy += REMOTE_HIT_LATENCY;

        myLine->changeStateTo( MESI_MODIFIED );
        if ( useDetStoreBuffers && doStoreBufferAccess ) {
          myLine->setDirty();
          StoreBufferIsEmpty = false;
        }
        return;
      case MESI_EXCLUSIVE: // write hit
      case MESI_MODIFIED:
        numWriteHits++;

        // TODO: fix this duplication from the MESI_SHARED case
        myLine->changeStateTo( MESI_MODIFIED );
        if ( useDetStoreBuffers && doStoreBufferAccess ) {
          myLine->setDirty();
          StoreBufferIsEmpty = false;
        }
        return;
      default:
        assert(false);
      }

    }

    // we didn't have the line at all - need to check for remote copies

    InvalidateReply inv_ack = writeRemoteAction( access );

    // remote hits and missing to memory aren't det
    deterministicTimeInMemoryHierarchy += L1_HIT_LATENCY;

    if ( inv_ack.nobodyHasThisLine ) {
      numWriteMisses++;
      timeInMemoryHierarchy += MEMORY_ACCESS_LATENCY;
    } else {
      numWriteRemoteHits++;
      timeInMemoryHierarchy += REMOTE_HIT_LATENCY;
    }

    L1cache->access( access.addr(), myLine );

    myLine->changeStateTo( MESI_MODIFIED );
    if ( useDetStoreBuffers && doStoreBufferAccess ) {
      myLine->setDirty();
      StoreBufferIsEmpty = false;
    }

  } // end write()
示例#4
0
  /** Perform a data read specified by the given `access'. */
  virtual void read( const DataAccess& access ) {

    State* line = NULL;
    CacheResponse r = L1cache->search( access.addr(), line );

    if ( r != MISSED_TO_MEMORY ) {
      // we hit somewhere in our private cache(s), or a shared cache
      numReadHits++;
      switch ( r ) {
      case L1_HIT:
        timeInMemoryHierarchy += L1_HIT_LATENCY;
        // default det cache latency is an L1 hit, so it doesn't matter whether we hit to a dirty line or not
        deterministicTimeInMemoryHierarchy += L1_HIT_LATENCY;
        return;
      case L2_HIT: {
        timeInMemoryHierarchy += L2_HIT_LATENCY;
        if ( line->isDirty() ) {
          deterministicTimeInMemoryHierarchy += L2_HIT_LATENCY;
        } else {
          deterministicTimeInMemoryHierarchy += L1_HIT_LATENCY;
        }
        return;
      }
      case L3_HIT:
        timeInMemoryHierarchy += L3_HIT_LATENCY;
        // shared cache hits aren't det
        deterministicTimeInMemoryHierarchy += L1_HIT_LATENCY;
        return;
      default:
        assert(false);
      }
    }


    // we missed, so check remote caches for data
    RemoteReadService rrs = readRemoteAction( access );

    // remote hits and missing to memory aren't det
    deterministicTimeInMemoryHierarchy += L1_HIT_LATENCY;

    MESIState newMesiState = MESI_INVALID;
    if ( rrs.providedData == false ) {
      // No Valid Read-Reply: Need to get this data from Memory
      numReadMisses++;
      timeInMemoryHierarchy += MEMORY_ACCESS_LATENCY-1;

      /* NB: we always fetch from memory into Exclusive. */
      newMesiState = MESI_EXCLUSIVE;

    } else if ( rrs.isShared ) {
      newMesiState = MESI_SHARED;
      numReadRemoteHits++;
      timeInMemoryHierarchy += REMOTE_HIT_LATENCY;

    } else {
      //Valid Read-Reply From Modified/Exclusive
      newMesiState = MESI_SHARED;
      numReadRemoteHits++;
      timeInMemoryHierarchy += REMOTE_HIT_LATENCY;
    }
    assert( newMesiState != MESI_INVALID );

    // pull in the actual line
    L1cache->access( access.addr(), line );
    line->changeStateTo( newMesiState );

  } // end read()