Ruby用于详细模拟系统的内存结构
1.ruby组成
- cache层次结构和各种替换策略
- cache层次结构由Cache Memory来实现,且不同实例的cache结构可以使用不同的替换策略
- 替换策略可以选择:LRU和Pseudo-LRU
- cache一致性协议
- 略。。。
- 互联网络
- 将存储器层次结构(cache、memory、DMA)的各种组件连接在一起。
- DMA和内存控制器
- 内存控制器用于处理cache失效后的请求
- 用于初始化内存请求和处理响应的sequencers部件
- sequencers负责向内存子系统(包括cache和芯片外的内存)服务来自处理器的加载/存储/原子内存请求
- 处理器和内存子系统之间的交互都要通过sequencers
- 每个核心或者物理线程都拥有一个sequencers
2.内存请求在ruby中的生命周期
- gem5中发出的请求(gem5包的形式)通过
RubyPort::recvTiming
(位于src/mem/ruby/system/RubyPort.hh/cc中)接口进入ruby的范围。rubyport实例化的数目和gem5硬件线程数目是一致的 - RubyPort将这个请求转换为RubyRequest object的形式,将其发送到
Sequencer::makeRequest
接口(Sequencer类本身是RubyPort类的派生类) 。 - 当请求到达
Sequencer::makeRequest
接口后,会给他分配资源并执行统计,将请求在mandatory queue(变量名为m_mandatory_q_ptr
)中排队,最后将他发送到ruby cache 层次结构中。 - L1 cache的控制器从mandatory queue中取出请求并查找L1 cache,进行必要的一致性状态转换,如果未命中需要通过类
MessageBuffer
将请求送到下一级cache。一旦请求命中,则通过MessageBuffer
类层层递进,向上推进。- 其中不同类型的cache控制器和组件通过
MessageBuffer
类(src/mem/ruby/buffers/MessageBuffer.cc/hh)进行交流沟通。
- 其中不同类型的cache控制器和组件通过
MessageBuffers
还充当片上互连的一致性消息的入口点。- 一旦请求在L1 cache中命中,L1 cache controller会利用Sequencer object对象的
readCallback
或者writeCallback
方法通知对应的Sequencer object。 - 最后,Sequencer清除相应请求的统计信息,然后调用
RubyPort :: ruby_hit_callback
方法,将结果发送到gem5的线程或者核心中