gpt4 book ai didi

c++ - 文件支持的内存映射的 CPU 缓存行为/策略?

转载 作者:IT老高 更新时间:2023-10-28 22:27:52 25 4
gpt4 key购买 nike

有谁知道现代 x86 系统上的内存映射文件支持区域分配了哪种类型的 CPU 缓存行为或策略(例如,不可缓存的写入组合)?

有什么方法可以检测是哪种情况,并可能覆盖默认行为?

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

(编者注:该问题之前被表述为 memory mapped I/O ,但该短语具有不同的特定技术含义,尤其是在谈论 CPU 缓存时。即实际的 I/O 设备,如您与负载/存储交谈的 NIC 或视频卡.

这个问题其实是关于你从mmap(some_fd, ...)得到什么样的内存,当您不使用 MAP_ANONYMOUS 并且它由磁盘上的常规文件支持时。)

最佳答案

TL:DR 内存映射文件对它们映射到进程地址空间的页面缓存页面使用正常的回写策略。如果您想要不是 WB 的页面,您必须做一些特殊的和特定于操作系统的事情。

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

至少有四种缓存策略:

  • 完全缓存(回写,又名 WB) .
    应用于映射到主存(RAM)的物理地址空间。用于提高内存子系统性能的性能。此类设备的主要特性是其状态只能由软件更改并且只能影响软件。

    内存映射文件实现使用完全缓存 因为它们完全由软件(操作系统)实现,从磁盘读取文件块并将其放入内存,然后将该块(可能已修改)放回磁盘。硬件更新页表中的“脏”位,让操作系统确定需要同步到磁盘的内容。
  • 直写缓存。 (WT)
    此类设备的主要属性是其状态只能通过软件更改,但更改必须立即对设备产生影响。根据此策略,写入内存映射 IO 设备寄存器的数据将同时放置在两个地方:缓存中和设备中。但是,当启动数据读取时,数据将从缓存中捕获,而无需对设备进行昂贵的访问。

    此缓存策略对于不写入其内存、仅读取 CPU 写入的内容的 MMIO 设备可能很有用。在实践中,它很少用于任何事情。 GPU 不是那样的,并且会写入视频内存,因此它不用于视频 RAM。 (GPU 没有使该区域的 CPU 缓存失效的机制,因为 GPU 不是 CPU 缓存一致性域的一部分)
  • 不可缓存的写组合(WC aka USCW) :弱序内存通常用于映射视频 RAM。与不可缓存一样,除了 NT 存储让您一次高效地写入整个缓存行。 movntdqa loads let you efficiently read whole cache lines ,您无法从 WC 区域执行任何其他操作。正常加载为每个加载单独获取数据,即使在同一行中,因为它是不可缓存的。
  • 禁用缓存。 (UC)
    适用于几乎所有的IO设备,因为对内存映射IO设备寄存器的写入必须立即生效并且从内存映射IO设备寄存器读取必须从设备返回给读取器的实际数据。如果将缓存应用于内存映射 IO 设备,则会引入两个负面影响:
  • 对内存映射 IO 设备寄存器的写入将被延迟,直到缓存 Controller 决定用写入的数据刷新缓存线的那一刻。因此,驱动程序将无法知道写入设备的命令何时生效。
  • 可以缓存从内存映射 IO 设备寄存器中读取的数据。从同一个内存映射 IO 设备寄存器读取的后续数据可能不会从设备返回实际数据,而是从缓存中返回过时的数据。因此,驱动程序将很难捕获设备的实际状态。

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

    关于c++ - 文件支持的内存映射的 CPU 缓存行为/策略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15853526/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com