ESP32-S3 采用双核共享 ICache
(指令缓存) 和 DCache
(数据缓存) 结构,如下图所示。以便当 CPU
的指令总线和数据总线同时发起请求时,也可以迅速响应:
Cache
的存储空间与内部存储空间可以复用。具体为 Internal SRAM0 和 Internal SRAM2 分别可被用于 ICache
与 DCache
。其中:
Internal SRAM0 的容量为 32 KB,可读可写。CPU 只可以通过指令总线访问这部分存储器。通过配置,这部分存储器中的 16 KB、或全部 32 KB 可以被 ICache
占用,用来缓存外部存储器的指令或只读数据。被 ICache
占用的部分不可以被 CPU 访问,未被 ICache
占用的部分仍然可以被 CPU
访问。
Internal SRAM2 的容量为 64 KB,可读可写。 CPU 只可以通过数据总线访问这部分存储器。通过配置,这部分存储器中的 32 KB、或全部 64 KB 可以被 DCache
占用,用来缓存外部存储器的数据。被 DCache
占用的部分不可以被 CPU 访问,未被 DCache
占用的部分仍然可以被 CPU 访问。
当两个核的指令总线同时访问 ICache
时,由仲裁器决定谁先获得访问 ICache
的权限;当两个核的数据总线同
时访问 DCache
时,由仲裁器决定谁先获得访问 DCache
的权限。当 Cache
缺失时,Cache
控制器会向外部存储器发起请求,当 ICache
和 DCache
同时发起外部存储器请求时,由仲裁器决定谁先获得外部存储器的使用权。ICache
的缓存大小可配置为 16 KB 或 32 KB,块大小可以配置为 16 B 或 32 B,当 ICache
缓存大小配置为 32 KB 时禁用 16 B 块大小模式。DCache
的缓存大小可配置为 32 KB 或 64 KB,块大小可以配置为 16 B、32 B 或 64 B,当 DCache 缓存大小配置为 64 KB 时禁用 16 B 块大小模式。
ESP32-S3 Cache
共有如下几种操作:
回写(Write-Back)
Write-Back 操作用于将 Cache
中的 “脏块” 的 “脏” 标记(Dirty bit)抹除,并将数据同步到外部存储器。Write-Back 操作结束后,外部存储器和 Cache
中存放的都是新数据。如果 CPU 接着去访问该数据,那么可以直接从 Cache
中访问到。只有 DCache
具有此功能。
所谓 “脏块” 是指,如果 Cache
中的数据比外部存储器中的数据要新,则 Cache
中的新数据被称为 “脏块”,Cache
通过 “脏” 标记来追踪这些 “脏块” 数据。如果抹除掉某个新数据的 “脏” 标记,Cache
将认为这个数据不是新的。
清除(Clean)
Clean 操作用于将 Cache
中的 “脏块” 的 “脏” 标记(Dirty bit)抹除,但不将数据同步到外部存储器。Clean
操作结束后,外部存储器中仍是旧数据,Cache
中存放的是新数据,但 Cache
以为不是新的。如果 CPU 接着去访问该数据,那么直接可以从 Cache
中访问到。只有 DCache
具有此功能。
失效(Invalidate)
Invalidate 操作用于删除 Cache
中的有效数据,即使该数据是 “脏块”,也不会将脏块同步到外部存储器。对于非脏块数据, Invalidate 操作结束后,该数据仅存在于外部存储器中。如果 CPU 接着去访问该数据,那么需要访问外部存储器。对于脏块数据, invalidate 结束后,外部存储器中存在的是旧数据,新数据将彻底丢失。Invalidate 分为自动失效 (Auto-Invalidate) 和手动失效 (Manual-Invalidate)。Manual-Invalidate 仅对 Cache
中落入指定区域的地址对应的数据做失效处理,而 Auto-Invalidate 会对 Cache
中的所有数据做失效处理。ICache
和 DCache
均具有此功能。
预取 (Preload)
Preload 功能用于将指令和数据提前加载到 Cache
中。预取操作的最小单位为 1 个块。预取分为手动预取 (Manual-Preload) 和自动预取 (Auto-Preload),Manual-Preload 是指硬件按软件指定的虚地址预取一段连续的数据;Auto-Preload 是指硬件根据当前命中/缺失(取决于配置)的地址,自动地预取一段连续的数据。ICache
和 DCache
均具有此功能。
锁定/解锁 (Lock/Unlock)
Lock 操作用于保护 Cache
中的数据不被替换掉。锁定分为预锁定和手动锁定。预锁定开启时,Cache
在填充缺失数据到 Cache
时,如果该数据落在指定区域,则将该数据锁定,未落入指定区域的数据不会被锁定。手动锁定开启时,Cache
检查 Cache
中的数据,并将落在指定区域的数据锁定,未落入指定区域的数据不会被锁定。当缺失发生时,Cache
会优先替换掉未被锁定的那一路的数据,因此锁定区域的数据会一直保存在 Cache
中。但当所有路都被锁定时, Cache
将进行正常替换,就像所有路都没有被锁定一样。解锁是锁定的逆操作,但解锁只有手动解锁。ICache
和 DCache
均具有此功能。
需要注意的是,Cache
的 Clean、Write-Back 和 Manual-Invalidate 操作均只对未被锁定的数据起作用。如果想对被锁定的数据执行这些操作,请先解锁这些数据。