2013-04-06 93 views
13

有谁知道在现代x86系统上,哪些类型的CPU高速缓存行为(例如无法缓存的写入组合)被分配给文件支持的,内存映射I/O?有没有什么办法来检测是哪种情况,并可能覆盖默认行为?内存映射I/O的高速缓存行为

Windows和Linux是感兴趣的主要操作系统。

+0

我可能会非常错误,但我怀疑他们对此做了什么特别的事情。文件支持的内存页面可以像其他任何典型的内存区域一样进行处理并正常缓存。我之所以这么说,是因为我可以访问文件支持的内存(几年前),并没有观察到由于特殊缓存而可能导致的不规则性。虽然我没有结果或代码了。另外,我测试的是直接内存映射文件,而不是任何设备I/O等。 – yzt 2013-04-06 17:17:06

+0

我的经历与@ YaserZhian的一致。事实上,Windows(至少)似乎将普通内存视为一种内存映射文件,它恰好映射到交换文件而不是其他文件。 – 2013-04-06 17:25:46

+1

[This may help you](http://kerneltrap.org/mailarchive/linux-kernel/2008/4/29/1657814) – DOOM 2013-04-06 17:30:41

回答

13

应用于地址空间区域的高速缓存策略通常独立于操作系统,并且仅取决于地址空间页面后面的设备类型。事实上,操作系统可以自由地将任何缓存策略应用于任何内存区域,但是缓慢分配的缓存策略可能会降低系统性能或破坏系统逻辑。

有三种缓存策略:

  1. 全部缓存(回写)。 应用于映射到主存储器(RAM)的物理地址空间。用于提高内存子系统执行的性能。这种设备的主要特性是它的状态只能通过软件改变,并且只能影响软件。内存映射文件实现使用完全缓存,因为它们完全由软件(操作系统)实现,该软件从磁盘读取文件块并将其放入内存,然后将该块(可能已修改)重新放回到磁盘。
  2. 写通缓存。 适用于内存映射视频内存等输出设备。这些设备的主要特性是只能通过软件更改状态,但更改必须立即对设备产生影响。根据此策略,写入内存映射IO设备寄存器的数据将同时放置在两个位置:缓存和设备中。但是,当数据读取将启动时,数据将从缓存中捕获,无需对设备进行高级访问。
  3. 禁用缓存。 适用于几乎所有IO设备,因为写入内存映射IO设备寄存器必须立即生效,并且从内存映射IO设备寄存器读取必须从设备返回读取器实际数据。如果高速缓存将应用于内存映射的IO设备,则会引入两个负面影响:
    1. 对内存映射IO设备寄存器的写入将被延迟,直到高速缓存控制器决定清除高速缓存行为止书面数据。因此,驱动程序将无法知道写入设备的命令何时生效。
    2. 可以高速缓存来自内存映射IO设备寄存器的读取数据。随后从同一个内存映射IO设备寄存器中读取的数据可能不会返回设备的实际数据,而是来自缓存的过期数据。因此,驾驶员很难捕捉设备的实际状态。

由于这样的事实,通过软件可以指定缓存策略的方法是只依赖于处理器相同的算法可以在任何操作系统上。 最简单的方法是捕获CR3寄存器的内容,并使用它找到适合您要知道的缓存策略的地址的页表项,并检查PCD和PWT标志。但这种方式并不完整,因为很少有其他功能会影响缓存(例如,缓存可以在CR0上完全禁用,另请参阅MTRR,PAT)。

+0

我很惊讶没人提高这个呢。很好的答案! – 2013-04-07 23:07:03

1

要添加到ZarathustrA的现有答案:在Windows上,此缓存轮流使用SEC_NOCACHE。有一个SEC_WRITECOMBINE,但似乎中断(它只适用于SEC_RESERVESEC_COMMIT,这意味着只有页面文件,并且你不想设置SEC_WRITECOMBINE那个)。