有谁知道在现代x86系统上为内存映射文件支持的区域分配了哪种类型的CPU缓存行为或策略(例如,不可缓存的写入组合)?
有没有办法检测是哪种情况,并可能覆盖默认行为?
Windows和Linux是您感兴趣的主要操作系统。
(编者注:此问题之前的措辞是memory mapped I/O,但该短语具有不同的特定技术含义,特别是在谈论CPU缓存时,即您说话的实际I / O设备,如NIC或视频卡与装载/商店。
这个问题实际上是关于从mmap(some_fd, ...)
获得什么样的内存,当你不使用MAP_ANONYMOUS并且它由磁盘上的常规文件支持时。)
答案 0 :(得分:15)
TL:DR内存映射文件对页面缓存的页面使用正常的回写策略,这些页面映射到进程的地址空间。如果您想要非WB的页面,则必须执行特殊操作和特定于操作系统。
应用于地址空间区域的缓存策略通常与操作系统无关,并且仅取决于地址空间页面后面的设备类型。事实上,操作系统可以自由地将任何缓存策略应用于任何内存区域,但错误分配的缓存策略可能会降低系统性能或完全破坏系统逻辑。
至少有四种缓存策略:
完全缓存(回写,又称WB)。 应用于映射到主存储器(RAM)的物理地址空间。用于提高内存子系统性能的性能。这些设备的主要特性是其状态只能通过软件进行更改,并且只能影响软件。
内存映射文件实现使用完全缓存,因为它们完全由软件(操作系统)实现,从磁盘读取文件块并将其放入内存,然后将此块(可能已修改)放回磁盘。硬件更新页表中的“脏”位,让操作系统找出需要同步到磁盘的内容。
直写式缓存。 (WT)强> 此类设备的主要特性是其状态只能由软件更改,但更改必须立即对设备产生影响。根据此策略,写入内存映射IO设备寄存器的数据将同时放置在两个位置:缓存和设备中。但是,当启动数据读取时,将从缓存中捕获数据,而无需昂贵的设备访问。
此缓存策略对于不写入其内存的MMIO设备非常有用,只能读取CPU写入的内容。在实践中,它很少用于任何事情。 GPU不是那样的,并且写入视频内存,所以它不用于视频RAM。 (GPU没有使该区域的CPU缓存无效的机制,因为GPU不是CPU的缓存一致性域的一部分)
movntdqa
loads let you efficiently read whole cache lines,你不能从WC地区做任何其他方式。正常加载为每个加载分别获取数据,即使在同一行内也是如此,因为它是不可缓存的。由于软件指定缓存策略的方式仅依赖于处理器,因此可以在任何操作系统中应用相同的算法。 最简单的方法是捕获CR3寄存器的内容,并使用它找到适合您想要知道的缓存策略的地址的页表条目,并检查PCD和PWT标志。但这种方式并不完整,因为很少有其他功能可以影响缓存(例如,可以在CR0上完全禁用缓存,另请参阅MTRR,PAT)。
答案 1 :(得分:2)
添加到ZarathustrA的现有答案:在Windows上,SEC_NOCACHE
转换此缓存。有一个SEC_WRITECOMBINE
,但显示已损坏(仅适用于SEC_RESERVE
或SEC_COMMIT
,这仅表示页面文件,并且您不想设置SEC_WRITECOMBINE
在那)。