[代码阅读]gem5中的classic cache 初步(1)

对于classic memory的研究,主要从cache入手;按照常理,首先从config文件入手,发现对于cache的配置,从BaseCache.py文件入手,

然后转到BaseCache.py文件,通过对BaseCache.py的微修改,查看编译的过程,找到BaseCache.py的作用以及与其他文件的关联;


发现:

1.      BaseCache.py主要用于生成params/BaseCache.hh文件;

对于其中Repl对象,我是比较关心的,具体的定义在params/Repl.hh中,该代码也是编译器scons生成的:

===========

//略去宏定义;

class Repl;

#include “params/SimObject.hh”

struct ReplParams : public SimobjectParams{};

===========

通过上面的代码,基本可以看到Repl是个空的对象,基本上不起作用的;通过后续的代码分析,的确可以验证我们当前的这个假设;

 

2.      通过grep命令,可以找到用到”BaseCache.hh”的相关文件有:

a)        mem/cache/base.hh;

b)        mem/cache/prefetch/base.hh;

c)        mem/cache/builder.cc;

 

3.      查看/mem/cache/base.hh文件,使用的方式主要如下:

typedef BaseCacheParams Params;

BaseCache(const Params *p);

 

4.      上面的第二行代码是对象创建函数,查看/mem/cache/base.cc文件,其中的代码如下:

BaseCache::BaseCache(constParams *p)

    : MemObject(p),

      mshrQueue("MSHRs", p->mshrs,4, MSHRQueue_MSHRs),

      writeBuffer("write buffer",p->write_buffers, p->mshrs+1000,

                  MSHRQueue_WriteBuffer),

      blkSize(p->block_size),

      hitLatency(p->latency),

      numTarget(p->tgts_per_mshr),

      forwardSnoops(p->forward_snoops),

      isTopLevel(p->is_top_level),

      blocked(0),

      noTargetMSHR(NULL),

      missCount(p->max_miss_count),

      drainEvent(NULL),

      addrRange(p->addr_range),

      _numCpus(p->num_cpus)

{

}

上述是一个构建函数,初始化参数都来自于BaseCache.hh中的BaseCacheParams对象;

 

5.      Prefetch部分暂时不考虑,我们关注mem/cache/builder.cc文件,这部分的代码完成cache的创建工作,其中值得留意的代码有:


const void *repl= NULL;

验证我们前面的猜想;

 

代码主体:

 

BaseCache *BaseCacheParams::create()

{

    int numSets = size / (assoc * block_size);

    if (subblock_size == 0) {

        subblock_size = block_size;

    }

 

#ifdefined(USE_CACHE_IIC)

    // Build IIC params

    IIC::Params iic_params;

    iic_params.size = size;

    iic_params.numSets = numSets;

    iic_params.blkSize = block_size;

    iic_params.assoc = assoc;

    iic_params.hashDelay = hash_delay;

    iic_params.hitLatency = latency;

    iic_params.rp = repl;

    iic_params.subblockSize = subblock_size;

#else

    constvoid *repl = NULL;

#endif

 

    BUILD_CACHES;

    return NULL;

}

 

 下面的宏完成cache的创建工作:

#defineBUILD_CACHES do {                              \

        if (repl == NULL) {                             \

            if (numSets == 1) {                         \

                BUILD_FALRU_CACHE;                      \

            } else {                                    \

               BUILD_LRU_CACHE;                    \

            }                                           \

        } else {                                        \

            BUILD_IIC_CACHE;                            \

        }                                              \

    } while (0)

 

#if defined(USE_CACHE_LRU)

#define BUILD_LRU_CACHE do {                                            \

        LRU *tags = newLRU(numSets, block_size, assoc, latency);      \

        BUILD_CACHE(LRU,tags);                                        \

    } while (0)

#else

#define BUILD_LRU_CACHE BUILD_CACHE_PANIC("lru cache")

#endif

 

#define BUILD_CACHE(TAGS, tags)                         \

    do {                                               \

        BasePrefetcher*pf;                             \

        if (prefetch_policy ==Enums::tagged) {         \

            pf = newTaggedPrefetcher(this);            \

        }                                              \

        else if(prefetch_policy == Enums::stride) {    \

            pf = newStridePrefetcher(this);            \

        }                                              \

        else if(prefetch_policy == Enums::ghb) {       \

            pf = newGHBPrefetcher(this);               \

        }                                              \

        else {                                          \

            pf = NULL;                                  \

        }                                              \

        Cache<TAGS>*retval =                           \

            newCache<TAGS>(this, tags, pf);            \

        return retval;                                  \

    } while (0)

 

#define BUILD_CACHE_PANIC(x) do {                       \

        panic("%s notcompiled into M5", x);            \

    } while (0)

 

上述代码之中的关键在于如下这句:

        Cache<TAGS> *retval=                           \

            newCache<TAGS>(this, tags, pf);           \

       return retval;

 

6.      这里的cache是一个模板类,将<TAGS>作为参数传递进去后,完成模板的具体化;完成这些操作后,大致就完成cache的创建和操作关联了,

查看上述的代码,一般是采用tag文件夹中的lru.cc,lru.hh来实例化TAG;


你可能感兴趣的:(cache,GEM5)