gem5: classic缓存模型下多bank实现 - mem: model data array bank in classic cache

参考:mem: model data array bank in classic cache

问题:由于gem5的classic缓存模型中不支持多bank模式,如果想使用,需要自己实现。

特点:在review board中已经有人实现了该方法,见这里,该实现方法具有如下特点:

mem: model data array bank in classic cache
The classic cache does not model data array bank, i.e. if a read/write is being
serviced by a cache bank, no other requests should be sent to this bank.
This patch models a multi-bank cache. Features include:
1. detect if the bank interleave granularity is larger than cache line size
2. add CacheBank debug flag
3. Differentiate read and write latency
3a. read latency is named as read_latency
3b. write latency is named as write_latency
4. Add write_latency, num_banks, bank_itlv_bit into the Python parser
5. Enabling bank model by –l1-bank-model, –l2-bank-model, –l3-bank-model
Not modeled in this patch:
Due to the lack of retry mechanism in the cache master port, the access form
the memory side will not be denied if the bank is in service. Instead, the bank
service time will be extended. This is equivalent to an infinite write buffer
for cache fill operations.

实现方法,需要修改的文件如下:
1.configs/common/CacheConfig.py,新建个Mbankl3CacheConfig.py。修改各级缓存的配置,主要包括各级读写延迟,是否支持bank模式及设置多少个等。需要修改的内容如下:

# 修改三级缓存配置
system.l3 = l3_cache_class(clk_domain=system.cpu_clk_domain,
                                   size=options.l3_size,
                                # part=options.part,
                                   cache_level=3,
                                   assoc=options.l3_assoc,
                                # add for multi-bank
                                   read_latency=options.l3_read_lat,
                                   write_latency=options.l3_write_lat,
                                   enable_bank_model=options.l3_enable_bank,
                                   num_banks=options.l3_num_banks,
                                   bank_intlv_high_bit=options.l3_intlv_bit
                                   )

#修改二级换成配置
if options.l2cache:
            system.cpu[i].l2 = l2_cache_class(clk_domain=system.cpu_clk_domain,
                                          size=options.l2_size,
                                    # part=options.l2_assoc,
                                          cache_level=2,
                                          assoc=options.l2_assoc,
                                    # sff add for multi-bank 
                                          read_latency=options.l2_read_lat,
                                          write_latency=options.l2_write_lat,
                                          enable_bank_model=options.l2_enable_bank,
                                          num_banks=options.l2_num_banks,
                                          bank_intlv_high_bit=options.l2_intlv_bit)

#修改一级换成配置
if options.caches:
            icache = icache_class(size=options.l1i_size,
                        # part=options.l1i_assoc,
                                  cache_level=1,
                                  assoc=options.l1i_assoc,
                        # sff add for multi-bank
                                  read_latency=options.l1_read_lat,
                                  write_latency=options.l1_write_lat,
                                  enable_bank_model=options.l1_enable_bank,
                                  num_banks=options.l1_num_banks,
                                  bank_intlv_high_bit=options.l1_intlv_bit)

            dcache = dcache_class(size=options.l1d_size,
                        # part=options.l1d_assoc,
                                  cache_level=1,
                                  assoc=options.l1d_assoc,
                        # sff add for multi-bank
                                  read_latency=options.l1_read_lat,
                                  write_latency=options.l1_write_lat,
                                  enable_bank_model=options.l1_enable_bank,
                                  num_banks=options.l1_num_banks,
                                  bank_intlv_high_bit=options.l1_intlv_bit)

2.configs/common/Caches.py,新建Mbankl3Caches.py。修改各级缓存的默认参数配置,修改如下:
主要包括:
read_latency = 2
write_latency = 2
enable_bank_model = False

class L1Cache(BaseCache):
    assoc = 2
    read_latency = 2
    response_latency = 2
    mshrs = 4
    tgts_per_mshr = 20
    is_top_level = True
# sff adds below
    write_latency = 2
    cache_level = 1
    enable_bank_model = False

class L2Cache(BaseCache):
    assoc = 8
    read_latency = 8
    response_latency = 20
    mshrs = 20
    tgts_per_mshr = 12
    write_buffers = 8
# sff adds below param
    write_latency = 8
    cache_level = 2
    enable_bank_model = False

class L3Cache(BaseCache):
    assoc = 8
    read_latency = 36
    response_latency = 20
    mshrs = 20
    tgts_per_mshr = 12
    write_buffers = 8
# sff adds below param
    write_latency = 36
    cache_level = 3
    enable_bank_model = False

class IOCache(BaseCache):
    assoc = 8
    read_latency = 50
    response_latency = 50
    mshrs = 20
    size = '1kB'
    tgts_per_mshr = 12
    forward_snoops = False
    is_top_level = True
# sff adds below
    write_latency = 50
    cache_level = 0
    enable_bank_model = False

class PageTableWalkerCache(BaseCache):
    assoc = 2
    read_latency = 2
    response_latency = 2
    mshrs = 10
    size = '1kB'
    tgts_per_mshr = 12
    is_top_level = True
# sff adds below
    write_latency = 2
    cache_level = 0
    enable_bank_model = False

3.configs/common/Options.py,添加选项,修改如下:

#添加选项
    parser.add_option("--l1-read-lat", type="int", default="2",
                      help="L1 read latency (cycles).")
    parser.add_option("--l2-read-lat", type="int", default="10",
                      help="L2 read latency (cycles).")
    parser.add_option("--l3-read-lat", type="int", default="40",
                      help="L3 read latency (cycles).")
    parser.add_option("--l1-write-lat", type="int", default="2",
                      help="L1 write latency (cycles).")
    parser.add_option("--l2-write-lat", type="int", default="10",
                      help="L2 write latency (cycles).")
    parser.add_option("--l3-write-lat", type="int", default="40",
                      help="L3 write latency (cycles).")
    parser.add_option("--l1-enable-bank", action="store_true",
                      help="Enable L1 bank model")
    parser.add_option("--l2-enable-bank", action="store_true",
                      help="Enable L2 bank model")
    parser.add_option("--l3-enable-bank", action="store_true",
                      help="Enable L3 bank model")
    parser.add_option("--l1-num-banks", type="int", default="1",
                      help="L1 bank count.")
    parser.add_option("--l2-num-banks", type="int", default="1",
                      help="L2 bank count.")
    parser.add_option("--l3-num-banks", type="int", default="1",
                      help="L3 bank count.")
    parser.add_option("--l1-intlv-bit", type="int", default="0",
                      help="L1 bank interleave highest bit.")
    parser.add_option("--l2-intlv-bit", type="int", default="0",
                      help="L2 bank interleave highest bit.")
    parser.add_option("--l3-intlv-bit", type="int", default="0",
                      help="L3 bank interleave highest bit.")

4.src/mem/cache/BaseCache.py,修改如下:

    read_latency = Param.Cycles("The read latency for this cache (cycles)")
    write_latency = Param.Cycles("The write latency for this cache (cycles)")
    response_latency = Param.Cycles(
            "Additional cache latency for the return path to core on a miss")
    enable_bank_model = Param.Bool("knob to control if the bank model is used")
    num_banks = Param.Int(1, "Number of cache data array banks")
    bank_intlv_high_bit = Param.Int(0,
        "Cache data array bank interleave highest bit "
        "(0=automatically aligned to cache line granularity)")

5.src/mem/cache/SConscript, 定义bank追踪,修改如下:

DebugFlag('CacheBank')

6.src/mem/cache/base.hh,此处修改较多,最好参照patch修改,具体如下:

#include "debug/CacheBank.hh"

//在185行后添加类
// EventWrapper<SlavePort, &SlavePort::sendRetry> sendRetryEvent;
// };在它的后面
    /** * Cache data array bank. * Only models bank access contention, does not hold actual data */
    class CacheBank
    {

      private:
        /** Descriptive name (for DPRINTF output) */
        std::string bankName;

        bool inService;

        Tick nextIdleTick;

      public:

        /** Mark this cache bank in-service until finishTick */
        void markInService(Tick finishTick);

        /** Check and unmark this cache bank in-service if necessary */
        void checkAndUnmarkInService();

        /** Extend this cache bank's in-service time by extraTick */
        void extendService(Tick extraTick);

        CacheBank(const std::string &_name) :
            bankName(_name),
            inService(false),
            nextIdleTick(0)
        {}

        bool isBusy() const { return inService; }

        Tick finishTick() const { return nextIdleTick; }

        /** Return bank name (for DPRINTF). */
        const std::string name() const { return bankName; }

    };

//在上面后4行添加
/** Data array banks */
    std::vector<CacheBank *> bank;

//250行
const Cycles readLatency;

//在const Cycles responseLatency;后添加
    /** * The knob to turn on/off cache data array bank model */
    const bool enableBankModel;

    /** * The number of cache data array banks. */
    const unsigned numBanks;

    /** * The number of cache data array bank interleave bits */
    const unsigned bankIntlvBits;

    /** * Cache data array bank interleave high bit */
    const unsigned bankIntlvHighBit;

    /** * Cache data array bank interleave low bit */
    const unsigned bankIntlvLowBit;

    /** * Cache data array bank interleve mask */
    const Addr bankIntlvMask;

//在virtual void regStats();后修改
/** Non-default destructor is needed to deallocate memory. */
    virtual ~BaseCache();

// getBlockSize() const后添加
 /** * Return bank ID according to interleave bits */
    unsigned
    getBankId(Addr addr) const
    {
        return (addr & bankIntlvMask) >> bankIntlvLowBit;
    }

7.src/mem/cache/base.cc,参照patch修改;

8.src/mem/cache/cache_impl.hh,参照patch修改;

9.src/mem/cache/tags/Tags.py,修改如下:

hit_latency = Param.Cycles(Parent.read_latency,
                               "The hit latency for this cache")

你可能感兴趣的:(缓存,GEM5,多bank)