结果很多有4000多行,但是没有一个教程详细的介绍到底哪些参数对应哪些意思。
频率
1 system.clk_domain
[system.clk_domain]
type=SrcClockDomain
clock=1000
domain_id=-1
eventq_index=0
init_perf_level=0
voltage_domain=system.voltage_domain
2. system.cpu.interrupts.clk_domain
[system.cpu.interrupts.clk_domain]
type=DerivedClockDomain
clk_divider=16
clk_domain=system.cpu_clk_domain
eventq_index=0
3. system.cpu_clk_domain
第200行。
[system.cpu_clk_domain]
type=SrcClockDomain
clock=500
domain_id=-1
eventq_index=0
init_perf_level=0
voltage_domain=system.cpu_voltage_domain
4. system.ruby.clk_domain
第1000行。
[system.ruby.clk_domain]
type=SrcClockDomain
clock=500
domain_id=-1
eventq_index=0
init_perf_level=0
voltage_domain=system.voltage_domain
5. system.ruby.memctrl_clk_domain
[system.ruby.memctrl_clk_domain]
type=DerivedClockDomain
clk_divider=3
clk_domain=system.ruby.clk_domain
eventq_index=0
频率小结
一共有3个不同的时钟域的范围分别是system,cpu 和ruby,给5个实例使用。其中system实例单独一个,cpu和cpu.interrupts.共用一个相同的范围,ruby和ruby.memctrl共用一个。
children 关系
system下有很多children,关键的是cpu和ruby,我们单独拿出来细看。
cpu的children
ruby的children
L1 cache 和ruby noc的关系: 从l1_cntrl0 看起
如下图,有2个不同名字的port分别是inport和outport,每个port各有2个序号,一共4个port。 inport 和outport的序号0 两个port 是给request的,序号1的两个port是给response的。
代码 在gem5/src/python/gem5/components/cachehierarchies/ruby/caches/mesi_two_level/l1_cache.py
@overrides(AbstractL1Cache)
def connectQueues(self, network):
self.mandatoryQueue = MessageBuffer()
self.requestFromL1Cache = MessageBuffer()
self.requestFromL1Cache.out_port = network.in_port
self.responseFromL1Cache = MessageBuffer()
self.responseFromL1Cache.out_port = network.in_port
self.unblockFromL1Cache = MessageBuffer()
self.unblockFromL1Cache.out_port = network.in_port
self.optionalQueue = MessageBuffer()
self.requestToL1Cache = MessageBuffer()
self.requestToL1Cache.in_port = network.out_port
self.responseToL1Cache = MessageBuffer()
self.responseToL1Cache.in_port = network.out_port
这里的MessageBuffer实例被用于在Ruby内存系统中的L1缓存和网络之间建立通信。这些MessageBuffer实例不是同一个对象,而是各自独立的实例,分别用于处理不同类型的消息和数据流。
每个MessageBuffer实例在这里扮演了特定的角色:
- mandatoryQueue:用于处理强制性消息,可能是与缓存一致性或其他关键操作相关的消息。
- requestFromL1Cache:从L1缓存发出的请求消息的缓冲区。out_port连接到网络的输入端口,表示这些请求将被发送到网络上。 它是master CPU的send request port.
- responseFromL1Cache:从L1缓存发出的响应消息的缓冲区。同样,它的out_port也连接到网络,用于发送响应。它是slave CPU的send response port.
- unblockFromL1Cache:用于发送从L1缓存来的解锁消息,这些消息通知网络其他组件可以继续处理之前被阻塞的操作。
- optionalQueue:可能用于处理可选的消息或特定类型的通信。
- requestToL1Cache 接收发送给L1缓存的请求,是slave cpu的 receive request port。 它们的in_port连接到网络的输出端口表示它们接收来自网络的消息。
- responseToL1Cache:master cpu的 receive response port 。它们的in_port连接到网络的输出端口表示它们接收来自网络的消息。
如下图所示。 注意,master cpu和request cpu不是固定的。我们先假定cpu 0是master cpu,cpu 1是slave cpu,那么只有上半部分使用了。
- 先是cpu0 的send reqport发送了 一个req. requestFromL1Cache 这时候被使用了,它的.out_port = network.in_port,它把req传送给了网络。
- 经过一段时间,网络把这个req传出去了,因为 requestToL1Cache.in_port = network.out_port,它现在到达了cpu1 的requestToL1Cache,也就是 cpu 1的 receive req port.
- 这时候会cpu1 花一些时间处理,准备好了一个resp要发回给cpu0. 它先是放到自己的 send resp port里,也就是 responseFromL1Cache。 同时 responseFromL1Cache.out_port = network.in_port,它会进入到noc网络里。
- noc运输结束后,resp 到达了 network.out_port。 因为 responseToL1Cache.in_port = network.out_port,它会进入到 cpu 0的 responseToL1Cache里,也就是cpu 0的 receive resp port 里。
其中 network来自于外界传递。 这里的初始化的AbstractL1Cache会被 @overrides(AbstractL1Cache)覆盖。
class L1Cache(AbstractL1Cache):
def __init__(
self,
l1i_size,
l1i_assoc,
l1d_size,
l1d_assoc,
network ,
core: AbstractCore,
num_l2Caches,
cache_line_size,
target_isa: ISA,
clk_domain: ClockDomain,
):
"""Creating L1 cache controller. Consist of both instruction
and data cache.
"""
super().__init__(network, cache_line_size)
L2 cache 和ruby noc的关系: 从l2_cntrl0 看起
system.ruby.l2_cntrl0.一共有9个内容:
- [system.ruby.l2_cntrl0.L2cache]
- [system.ruby.l2_cntrl0.DirRequestFromL2Cache]
- [system.ruby.l2_cntrl0.L1RequestFromL2Cache]
- [system.ruby.l2_cntrl0.L1RequestToL2Cache]
- [system.ruby.l2_cntrl0.responseToL2Cache]
- [system.ruby.l2_cntrl0.responseFromL2Cache]
- [system.ruby.l2_cntrl0.L2cache.replacement_policy]
- [system.ruby.l2_cntrl0.power_state]
- [system.ruby.l2_cntrl0.unblockToL2Cache]
其中第一个[system.ruby.l2_cntrl0.L2cache] type是RubyCache
2-6是type=MessageBuffer。
7-9我们先忽略
附录参考代码
MESI_Two_Level 的l2cache相连。
我们回顾一下isa用的什么protocol: build/opt下的x86指定了MESI_Two_Level
USE_X86_ISA = True
PROTOCOL = 'MESI_Two_Level'
NUMBER_BITS_PER_SET = '128'
在gem5/src/python/gem5/components/cachehierarchies/ruby/caches/mesi_two_level/l2_cache.py
里:指定了 这些cache/buffer怎么相连的。
强调一下,这里的都是l2cache里的,比如 L1RequestToL2Cache 其实是[system.ruby.l2_cntrl0.L1RequestToL2Cache]。
@overrides(AbstractL2Cache)
def connectQueues(self, network):
self.DirRequestFromL2Cache = MessageBuffer()
self.DirRequestFromL2Cache.out_port = network.in_port
self.L1RequestFromL2Cache = MessageBuffer()
self.L1RequestFromL2Cache.out_port = network.in_port
self.responseFromL2Cache = MessageBuffer()
self.responseFromL2Cache.out_port = network.in_port
self.unblockToL2Cache = MessageBuffer()
self.unblockToL2Cache.in_port = network.out_port
self.L1RequestToL2Cache = MessageBuffer()
self.L1RequestToL2Cache.in_port = network.out_port
self.responseToL2Cache = MessageBuffer()
self.responseToL2Cache.in_port = network.out_port
其中network是从外界传递来的
def __init__(
self, l2_size, l2_assoc, network, num_l2Caches, cache_line_size
):
super().__init__(network, cache_line_size)