目录
- L2 Prefetcher简介
- 操作
- 流退出
- 页边界
- Memory Map
- 控制寄存器
- L2 Prefetcher 初始化
L2 prefetcher是U64内核新增的功能,U54内核没有这个功能。打开L2 prefetcher功能后,当访问大片内存,同时dcache中没有缓存时,访问内存的速率可以提高大概一倍。
L2 Prefetcher简介
SiFive L2 预取器是一个 per-hart
设备,它允许 L2 根据内核中的 harts 进行的数据访问模式来执行对内存的访问。
例如,如果一个 hart 正在读取一个大数组的每 100 个字节并且L1-dcache中没有缓存,预取器就会将适当的内存地址分配给 L2 缓存,使得后续对数组的访问产生L2 缓存命中。 这样就减少了整体访问数组的时间并提高应用程序的性能。
U64内核包含四个 L2 预取器实例。 它们的地址如表141所示
操作
L2 Prefetcher 可以监控每个 hart 八个不同的数据流,其中一个流由一个基地址和内存地址之间的跨度组成。 在可能的情况下,预取会自动发布到内存系统,并且 10 个条目的预取队列会在访问发布之前保存这些访问。 就缓存行而言,预取(或最大跨步长度)的范围由 additionalCtrl.window 寄存器设置。 例如,如果将其设置为 0x4,则 步长为 256 字节或更大的流将被忽略(假设每个缓存行为 64 字节)
每个流的初始预取数(或预取距离)由 basicCtrl.initialDist 设置。 预取距离将根据预取的成功和预取的整体范围进行调整。 如果 hart 继续进行与流的步幅匹配的直接访问(幅度和符号),则将进行额外的预取,并且预取距离会增加。 有可能 hart 进行的直接访问对于预取器来说太快了,hart 将不得不等待 L2 填充。 发生这种情况时,L2 预取器将增加预取距离(即发出更多预取)以尽量减少发生这种情况的机会。 增加预取距离的阈值由 additionalCtrl.hitMSHRThrd 设置。
为流发出的最大预取次数受 basicCtrl.maxAllowedDist
限制。 预取距离会逐渐增加,但有时可能不够快。 从初始距离加速到最大距离的速度由预取器自动管理。 basicCtrl.linToExpThrd
设置可用于微调此自适应加速。 该字段的值越小,预取器达到最大预取距离的速度就越快。
仅当存在空闲的 L2 未命中状态保持寄存器 (MSHR) 时才会发出预取。 additionalCtrl.qFullnessThrd 值用于控制预取器何时停止向内存系统发出提示。 这个 4 位字段允许 L2 缓存中的 MSHR 总数以 1/16 的分数表示。 例如,阈值 0xC 表示如果 75% 的 MSHR 已分配,预取将停止,直到正在使用的 MSHR 数量降至可用的 75% 以下。 此设置允许调整预取器,以便预取器不会停止由 Core Complex(来自 harts 和 Front Port master)进行的直接访问。
预取器监视对内存的读取和写入,并且步幅可以是递增或递减地址。 复位时禁用预取; 可以使用 basicCtrl.scalarLoadSupportEn
和 additionalCtrl.scalarStoreSupportEn
位启用标量支持,可以使用 additionalCtrl.vectorLoadSupportEn
和 additionalCtrl.vectorStoreSupportEn
位启用矢量支持。
流退出
预取流不太可能在应用程序的生命周期内无限期地持续下去,因此 L2 预取器提供了一种方法来淘汰旧流。 这允许跟踪新流。
流可以通过成功命中 L2 缓存而无需预取来退出。如果足够多的连续访问命中 L2 缓存,但没有预取,则预取器无需继续监视流。 additionalCtrl.hitCacheThrd
字段设置了该流退出的阈值。
页边界
L2 预取器可以编程为跨越内存的 4 KB
页边界。 这在没有 OS 页面保护或可以忽略 OS 页面保护的应用程序环境中很有用。
当设置 basicCtrl.crossPageEn
时,预取可以跨越 4 KB 边界。
如果 hart 继续进行与新的 4 KB 内存页中的步幅匹配的访问,预取将恢复。
Memory Map
L2 预取器控制寄存器的存储器映射如表 142 所示
控制寄存器
L2 预取器控制寄存器 basicCtrl
和 additionalCtrl
如下表所述。
L2 Prefetcher 初始化
L2 预取器需要在使用前在引导软件中进行初始化。 初始化后,L2 预取器可以根据需要在每个配置的基础上进行调整。 具体需要参考提供的SDK中L2预取器的软件示例。