2c2
< * Copyright (c) 2012-2013,2016 ARM Limited
---
> * Copyright (c) 2012-2013,2016,2018 ARM Limited
40a41
> * Nikos Nikoleris
53a55
> #include "base/intmath.hh"
59a62,71
> // Uncomment to enable sanity checks for the FALRU cache and the
> // TrackedCaches class
> //#define FALRU_DEBUG
>
> // A bitmask of the caches we are keeping track of. Currently the
> // lowest bit is the smallest cache we are tracking, as it is
> // specified by the corresponding parameter. The rest of the bits are
> // for exponentially growing cache sizes.
> typedef uint32_t CachesMask;
>
71,79c83,84
< /**
< * A bit mask of the sizes of cache that this block is resident in.
< * Each bit represents a power of 2 in MB size cache.
< * If bit 0 is set, this block is in a 1MB cache
< * If bit 2 is set, this block is in a 4MB cache, etc.
< * There is one bit for each cache smaller than the full size (default
< * 16MB).
< */
< int inCache;
---
> /** A bit mask of the caches that fit this block. */
> CachesMask inCachesMask;
93,99d97
< /** Array of pointers to blocks at the cache size boundaries. */
< FALRUBlk **cacheBoundaries;
< /** A mask for the FALRUBlk::inCache bits. */
< int cacheMask;
< /** The number of different size caches being tracked. */
< unsigned numCaches;
<
137,161d134
< /**
< * Check to make sure all the cache boundaries are still where they should
< * be. Used for debugging.
< * @return True if everything is correct.
< */
< bool check();
<
< /**
< * @defgroup FALRUStats Fully Associative LRU specific statistics
< * The FA lru stack lets us track multiple cache sizes at once. These
< * statistics track the hits and misses for different cache sizes.
< * @{
< */
<
< /** Hits in each cache size >= 128K. */
< Stats::Vector hits;
< /** Misses in each cache size >= 128K. */
< Stats::Vector misses;
< /** Total number of accesses. */
< Stats::Scalar accesses;
<
< /**
< * @}
< */
<
173d145
< * @param name The name to prepend to the stats name.
187c159
< * Returns the access latency and inCache flags as a side effect.
---
> * Returns the access latency and inCachesMask flags as a side effect.
191c163
< * @param inCache The FALRUBlk::inCache flags.
---
> * @param in_cache_mask Mask indicating the caches in which the blk fits.
195c167
< int *inCache);
---
> CachesMask *in_cache_mask);
289a262,385
>
> private:
> /**
> * Mechanism that allows us to simultaneously collect miss
> * statistics for multiple caches. Currently, we keep track of
> * caches from a set minimum size of interest up to the actual
> * cache size.
> */
> class CacheTracking
> {
> public:
> CacheTracking(unsigned min_size, unsigned max_size,
> unsigned block_size)
> : blkSize(block_size),
> minTrackedSize(min_size),
> numTrackedCaches(max_size > min_size ?
> floorLog2(max_size) - floorLog2(min_size) : 0),
> inAllCachesMask(mask(numTrackedCaches)),
> boundaries(new FALRUBlk *[numTrackedCaches])
> {
> fatal_if(numTrackedCaches > sizeof(CachesMask) * 8,
> "Not enough bits (%s) in type CachesMask type to keep "
> "track of %d caches\n", sizeof(CachesMask),
> numTrackedCaches);
> }
>
> ~CacheTracking()
> {
> delete[] boundaries;
> }
>
> /**
> * Initialiaze cache blocks and the tracking mechanism
> *
> * All blocks in the cache need to be initialized once.
> *
> * @param blk the MRU block
> * @param blk the LRU block
> */
> void init(FALRUBlk *head, FALRUBlk *tail);
>
> /**
> * Update boundaries as a block will be moved to the MRU.
> *
> * For all caches that didn't fit the block before moving it,
> * we move their boundaries one block closer to the MRU. We
> * also update InCacheMasks as neccessary.
> *
> * @param blk the block that will be moved to the head
> */
> void moveBlockToHead(FALRUBlk *blk);
>
> /**
> * Update boundaries as a block will be moved to the LRU.
> *
> * For all caches that fitted the block before moving it, we
> * move their boundaries one block closer to the LRU. We
> * also update InCacheMasks as neccessary.
> *
> * @param blk the block that will be moved to the head
> */
> void moveBlockToTail(FALRUBlk *blk);
>
> /**
> * Notify of a block access.
> *
> * This should be called every time a block is accessed and it
> * updates statistics. If the input block is nullptr then we
> * treat the access as a miss. The block's InCacheMask
> * determines the caches in which the block fits.
> *
> * @param blk the block to record the access for
> */
> void recordAccess(FALRUBlk *blk);
>
> /**
> * Check that the tracking mechanism is in consistent state.
> *
> * Iterate from the head (MRU) to the tail (LRU) of the list
> * of blocks and assert the inCachesMask and the boundaries
> * are in consistent state.
> *
> * @param head the MRU block of the actual cache
> * @param head the LRU block of the actual cache
> */
> void check(FALRUBlk *head, FALRUBlk *tail);
>
> /**
> * Register the stats for this object.
> */
> void regStats(std::string name);
>
> private:
> /** The size of the cache block */
> const unsigned blkSize;
> /** The smallest cache we are tracking */
> const unsigned minTrackedSize;
> /** The number of different size caches being tracked. */
> const int numTrackedCaches;
> /** A mask for all cache being tracked. */
> const CachesMask inAllCachesMask;
> /** Array of pointers to blocks at the cache boundaries. */
> FALRUBlk** boundaries;
>
> protected:
> /**
> * @defgroup FALRUStats Fully Associative LRU specific statistics
> * The FA lru stack lets us track multiple cache sizes at once. These
> * statistics track the hits and misses for different cache sizes.
> * @{
> */
>
> /** Hits in each cache */
> Stats::Vector hits;
> /** Misses in each cache */
> Stats::Vector misses;
> /** Total number of accesses */
> Stats::Scalar accesses;
>
> /**
> * @}
> */
> };
> CacheTracking cacheTracking;