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预取器的软件示例。
end
猜你喜欢:
RISC-V SiFive U54内核——PMP物理内存保护