caching - 写入内存的策略
问题描述
我了解何时需要将数据传送到 CPU:
在缓存未命中时,我们访问缓存,访问 DRAM:
a) 如果 DRAM 命中,我们将数据从 DRAM 复制回缓存。
b) 我们将数据从磁盘复制到 DRAM,然后从 DRAM 复制到缓存。在缓存命中时,我们只访问缓存。
写入内存时应该使用什么策略?
例如:
在每次写入缓存命中时,我们是否更新缓存、DRAM 和磁盘?
对于每次写入未命中,我们是否写入磁盘,将该磁盘块读入 DRAM,然后将 DRAM 块读入缓存?
解决方案
大多数现代 CPU 的缓存速度比 DRAM 快得多,因此回写是唯一有意义的策略。当片上缓存和 DRAM 之间的差距不是很大时,一些较旧的 CPU 或现代嵌入式可能具有直写 CPU 缓存。无论哪种方式,这都是硬件管理的,对软件是不可见的。
但是写入总是在 DRAM 处停止,如果/当他们做到了那么远。当页面在 DRAM 中时,磁盘上的“后备存储”并不重要。如果您想将 DRAM 视为内存映射文件(或匿名内存的页面文件)的缓存,那么唯一对性能有意义的写入策略就是回写!
回写到磁盘是由软件管理的,因此实施直写策略需要在提交到 DRAM 后使每个存储陷阱到操作系统,此时操作系统必须运行一堆代码来启动 SATA 写入命令的整个页面。(并且必须在不访问任何 DRAM 本身的情况下执行此操作,否则这些写入将如何在磁盘上同步?或者您可能会在这里摆脱困境,因为内核内存通常不可分页,因此该内核代码仅被支持通过 DRAM,而不是最终通过磁盘页面。)
即使磁盘写入可以有效地使用字节或字粒度(除非您的“磁盘”实际上是非易失性 RAM,例如 3D XPoint(例如Optane DC Persistent Memory)或电池支持的 DRAM,否则它非常不可能),仅仅捕获每家商店仍然会破坏性能,比如慢数百倍。
DRAM和磁盘的差距一直很大;硬件没有机制可以有效地写入“磁盘”。除了连接到内存总线的现代非易失性存储之外,它可以真正进行内存映射,如 Linux mmap(MAP_SYNC)
。但是在 cpu-cache 和持久性 NV-DRAM 之间没有普通的 DRAM
I/O 与 DRAM 性能;随机 DRAM 写入(在现代 x86 上,使用绕过缓存的 NT 存储)需要大约 60ns 的 64 字节粒度(对于完整缓存行的突发写入),包括将存储从 CPU 核心获取到内存控制器。(60ns 实际上类似于读取的 L3-miss 加载使用延迟,但我将假设 NT 存储类似。)
随机磁盘写入旋转磁盘大约需要 10 毫秒,因此慢了大约 6 个数量级。甚至检测
此外,磁盘写入的最小大小通常为 512 或 4096字节(1 个硬件扇区),因此要写入 1 个字节或字或 CPU 高速缓存行,将需要磁盘的读取-修改-写入周期。
推荐阅读
- x-content-type-options - 带有值“nosniff”的“X-Content-Type-Options”标头阻止 CSS 和 JS
- opencv - 估计 2D 图像中平面的 3D 方向
- php - 使用php从给定链接中提取数据
- php - 作曲家要求 laravel/ui 不适用于 Lumen 中的 php artisan make:auth
- .net-core - 从 Libvlcsharp (dvb-t) 获取程序信息
- sql - Oracle SQL - 将数值转换为实际时间戳(仅时间 - 无日期)
- tfs - HOWTO:在还原后修复不同步的 TFS 工作区
- python - 我们如何从输入图像中去除棋盘状噪声
- javascript - 如何将文件发布到 ASP.NET Web api
- python - 如何在特定条件下组合熊猫中的连续行