使用内存映射 I/O 管理缓存

deb*_*air 4 memory caching operating-system memory-management memory-barriers

我有一个关于内存映射 io 的问题。假设有一个内存映射的 IO 外设,其值正在被 CPU 读取。读取后,该值存储在缓存中。但是内存中的值已经被外部IO外设更新了。在这种情况下,CPU 将如何确定缓存已失效,这种情况的解决方法是什么?

gud*_*dok 6

这强烈依赖于平台。实际上,有两种不同的情况。

情况1。内存映射外设。这意味着对某些物理内存地址范围的访问被路由到外围设备。不涉及实际的 RAM。例如,为了控制缓存,x86 具有 MTRR(“内存类型范围寄存器”)和 PAT(“页面属性表”)。它们允许在特定范围的物理内存上设置缓存模式。在正常情况下,映射到 RAM 的内存范围是可写回缓存的,而映射到外围设备的内存范围是不可缓存的。不同的缓存策略在Intel 的系统编程指南11.3“可用缓存方法”中有所描述。因此,当您向内存映射外设发出读取或写入请求时,CPU 缓存将被绕过,

案例#2。DMA。它允许外围设备异步访问 RAM。在这种情况下,DMA 控制器与任何 CPU 没有区别,并且同样参与缓存一致性协议。来自外设的写请求被其他 CPU 的缓存看到,并且缓存线要么失效,要么用新数据更新。读取请求也会被其他 CPU 的缓存看到,并且数据从缓存而不是从主 RAM 返回。(这只是一个例子:实际实现取决于平台。例如,SoC 通常不保证强缓存一致性外设 <-> CPU。)

在这两种情况下,缓存的问题也存在于编译器层面:编译器可能会将数据值缓存在寄存器中。这就是为什么编程语言有一些禁止这种优化的方法:例如,volatileC 中的关键字。