gem5——缓存

本文详细介绍了gem5内存系统中涉及的文件结构,包括`SConscript`、`Cache.py`以及相关的C++源文件。`SConscript`负责编译配置,`Cache.py`定义了仿真对象,而C++源文件实现了具体功能。通过`SimObject`、`Source`、`DebugFlag`和`CompoundFlag`等关键字,gem5构建系统能够组织和编译代码。文章还探讨了Python与C++之间的交互,展示了如何通过参数传递配置C++类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 涉及到的相关文件

四个文件夹

compressors
prefetch
replacement_policies
tags

分别表示“缓存压缩”、“预取”、“替换算法”、“标志位”等相关结构
此外,还包括基本文件:

base.hh
base.cc
cache_blk.hh
cache_blk.cc
cache.hh
cache.cc
mshr_queue.hh
mshr_queue.cc
mshr.hh
mshr.cc
noncoherent_cache.hh
noncoherent_cache.cc
queue_entry.hh
queue.hh
write_queue_entry.hh
write_queue_entry.cc
write_queue.hh
write_queue.cc
Cache.py
SConscript

从这些文件中,可以观察到其中的文件包括三类:

  • SConscript:负责编译用 Scons
  • Cache.py:Python 提供接口
  • xx.hh/cc:c++ 实现具体的功能

2 SConscript

2.1 具体结构

Import('*')

SimObject('Cache.py', sim_objects=[
    'WriteAllocator', 'BaseCache', 'Cache', 'NoncoherentCache'],
    enums=['Clusivity'])
    
Source('base.cc')
Source('cache.cc')
Source('cache_blk.cc')
Source('mshr.cc')
Source('mshr_queue.cc')
Source('noncoherent_cache.cc')
Source('write_queue.cc')
Source('write_queue_entry.cc')

DebugFlag('Cache')
DebugFlag('CacheComp')
DebugFlag('CachePort')
DebugFlag('CacheRepl')
DebugFlag('CacheTags')
DebugFlag('CacheVerbose')
DebugFlag('HWPrefetch')
DebugFlag('MSHR')
DebugFlag('HWPrefetchQueue')

CompoundFlag('CacheAll', ['Cache', 'CacheComp', 'CachePort', 'CacheRepl',
                          'CacheVerbose', 'HWPrefetch', 'MSHR'])

2.2 SConscript 简介

SConscript 是 scons 默认自动寻找并执行的配置脚本,对环境进行基本的信息处理,然后创造环境对象,并调用 osconfig.py(硬件相关性较大的配置)build_tools.py(定义了各项公用的操作)
SConscript()方法,递归调用各级子目录中的SConscript,从而实现根据不同项目特点定义相应的代码组织、编译行为。

gem5 中,主要用 scons编译,并 SConscript 完成编译相关内容,主要用的语法有:

SimObject()
Source()
DebugFlag()
CompoundFlag()

2.3 SimoObject

# gem5-stable\src\SConscript
class SimObject(PySource):
    '''Add a SimObject python file as a python source object and add
    it to a list of sim object modules'''
    
class PySource(SourceFile):
	'''Add a python source file to the named package'''

# gem5-stable\site_scons\gem5_scons\sources.py
class SourceFile(object, metaclass=SourceMeta):
    '''Base object that encapsulates the notion of a source file.
    This includes, the source node, target node, various manipulations
    of those.  A source file also specifies a set of tags which
    describing arbitrary properties of the source file.'''
    def __init__(self, source, tags=None, add_tags=None, append=None):
    

主要功能是添加一个 python 对象到仿真对象中

2.4 Source

# gem5-stable\src\SConscript
class Source(SourceFile):
    pass

应该是加了一层封装,还是使用 SourceFile的初始化函数
从使用上来看,主要是指明源文件

2.5 DebugFlag

# gem5-stable\src\SConscript
def DebugFlag(name, desc=None, fmt=False, tags=None, add_tags=None):
    DebugFlagCommon(name, (), desc, fmt, tags=tags, add_tags=add_tags)
def DebugFlagCommon(name, flags, desc, fmt, tags, add_tags):
	...

用于指示出调试信息,调试位

2.6 CompoundFlag

# gem5-stable\src\SConscript
def CompoundFlag(name, flags, desc=None, tags=None, add_tags=None):
    DebugFlagCommon(name, flags, desc, False, tags=tags, add_tags=add_tags)

2.2.3和2.2.4主要是为增加调试信息,和复合标志(?)

3 Cache.py

主要定义了基本的模块

class Clusivity(Enum)
class WriteAllocator(SimObject)
class BaseCache(ClockedObject)
class Cache(BaseCache)
class NoncoherentCache(BaseCache)

# SConscript
SimObject('Cache.py', sim_objects=[
    'WriteAllocator', 'BaseCache', 'Cache', 'NoncoherentCache'],
    enums=['Clusivity'])

Tips. 这个文件中的类,与 SConscript 的 SimObejct 是一一对应

class Cache(BaseCache):
    type = 'Cache'
    cxx_header = 'mem/cache/cache.hh'
    cxx_class = 'gem5::Cache'

比较核心的内容:

  • type 指明类型
  • cxx_header
  • cxx_class

4 xx.hh/cc

具体的功能实现,那么 Python 和 C++ 是如何一起?Python 是怎么调用 C++ 实现的功能(以 BaseCache 类为例,进行具体分析)
回顾 Cache.py 中关于 Basecache 类的定义

class BaseCache(ClockedObject):
    type = 'BaseCache'
    abstract = True
    cxx_header = "mem/cache/base.hh"

    size = Param.MemorySize("Capacity")
    assoc = Param.Unsigned("Associativity")

    tag_latency = Param.Cycles("Tag lookup latency")
    data_latency = Param.Cycles("Data access latency")
    response_latency = Param.Cycles("Latency for the return path on a miss");

    warmup_percentage = Param.Percent(0,
        "Percentage of tags to be touched to warm up the cache")

    max_miss_count = Param.Counter(0,
        "Number of misses to handle before calling exit")

    mshrs = Param.Unsigned("Number of MSHRs (max outstanding requests)")
    demand_mshr_reserve = Param.Unsigned(1, "MSHRs reserved for demand access")
    tgts_per_mshr = Param.Unsigned("Max number of accesses per MSHR")
    write_buffers = Param.Unsigned(8, "Number of write buffers")

    is_read_only = Param.Bool(False, "Is this cache read only (e.g. inst)")

    prefetcher = Param.BasePrefetcher(NULL,"Prefetcher attached to cache")
    prefetch_on_access = Param.Bool(False,
         "Notify the hardware prefetcher on every access (not just misses)")

    tags = Param.BaseTags(BaseSetAssoc(), "Tag store")
    replacement_policy = Param.BaseReplacementPolicy(LRURP(),
        "Replacement policy")

    compressor = Param.BaseCacheCompressor(NULL, "Cache compressor.")

    sequential_access = Param.Bool(False,
        "Whether to access tags and data sequentially")

    cpu_side = SlavePort("Upstream port closer to the CPU and/or device")
    mem_side = MasterPort("Downstream port closer to memory")

    addr_ranges = VectorParam.AddrRange([AllMemory],
         "Address range for the CPU-side port (to allow striping)")

    system = Param.System(Parent.any, "System we belong to")

    writeback_clean = Param.Bool(False, "Writeback clean lines")

    clusivity = Param.Clusivity('mostly_incl',
                                "Clusivity with upstream cache")

    write_allocator = Param.WriteAllocator(NULL, "Write allocator")

用到了 Param 把参数传递进来,这部分是编译后,会有一个参数对应表。

注意: src 文件夹中用到的参数,与编译后 build/X86文件夹下的代码不完全相同,并且会自动生成 Param 相关参数

那么,是如何与 C++ 中对应上?看 BaseCache 类

gem5-stable\src\mem\cache\base.hh
class BaseCache : public ClockedObject
{
protected:
    /**
     * Indexes to enumerate the MSHR queues.
     */
    enum MSHRQueueIndex
    {
        MSHRQueue_MSHRs,
        MSHRQueue_WriteBuffer
    };
}

编译结束后,gem5会自动生成一些文件

// \build\X86\params\BaseCache.hh
struct BaseCacheParams
    : public ClockedObjectParams
{
    std::vector< AddrRange > addr_ranges;
    unsigned assoc;
    Enums::Clusivity clusivity;
    BaseCacheCompressor * compressor;
    Cycles data_latency;
    unsigned demand_mshr_reserve;
    bool is_read_only;
    Counter max_miss_count;
    unsigned mshrs;
    bool prefetch_on_access;
    BasePrefetcher * prefetcher;
    BaseReplacementPolicy * replacement_policy;
    Cycles response_latency;
    bool sequential_access;
    uint64_t size;
    System * system;
    Cycles tag_latency;
    BaseTags * tags;
    unsigned tgts_per_mshr;
    int warmup_percentage;
    WriteAllocator * write_allocator;
    unsigned write_buffers;
    bool writeback_clean;
    unsigned int port_mem_side_connection_count;
    unsigned int port_cpu_side_connection_count;
};

此时,可根据 Cache.py 中的相关变量,把对应的值输入到 c++ 代码中

5 总结

至此,把一个文件夹中的多个部分进行了分析,并梳理了一下各自间的联系:

  • SConscript:负责编译文件,指明 Source(源文件)、Debug(调试信息)、SimObject(提供的仿真对象)
  • x.py:负责提供简要配置,并用于传输具体的接口信息
  • x.hh/cc:根据 x.py 提供的端口配置参数,实现具体的功能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值