【发布时间】:2016-11-16 21:26:04
【问题描述】:
我有一个关于内存映射 io 的问题。 假设有一个内存映射的 IO 外设,其值正在被 CPU 读取。读取后,该值将存储在缓存中。但内存中的值已被外部 IO 外设更新。 在这种情况下,CPU 将如何确定缓存已失效以及这种情况的解决方法是什么?
【问题讨论】:
标签: caching memory memory-management operating-system memory-barriers
我有一个关于内存映射 io 的问题。 假设有一个内存映射的 IO 外设,其值正在被 CPU 读取。读取后,该值将存储在缓存中。但内存中的值已被外部 IO 外设更新。 在这种情况下,CPU 将如何确定缓存已失效以及这种情况的解决方法是什么?
【问题讨论】:
标签: caching memory memory-management operating-system memory-barriers
这强烈依赖于平台。实际上,有两种不同的情况。
案例 #1。 内存映射外围设备。这意味着对某些物理内存地址范围的访问被路由到外围设备。不涉及实际的 RAM。例如,为了控制缓存,x86 具有 MTRR(“内存类型范围寄存器”)和 PAT(“页面属性表”)。它们允许在特定范围的物理内存上设置缓存模式。正常情况下,映射到RAM的内存范围是write-back-cacheable,而映射到外围设备的内存范围是uncacheable。 Intel's system programming guide, 11.3 “可用的缓存方法”中描述了不同的缓存策略。因此,当您向内存映射外设发出读取或写入请求时,CPU 缓存被绕过,请求直接发送到设备。
案例 #2。 DMA。它允许外围设备异步访问 RAM。在这种情况下,DMA 控制器与任何 CPU 没有区别,并且平等地参与缓存一致性协议。来自外围的写请求被其他 CPU 的缓存看到,缓存行要么失效,要么用新数据更新。其他 CPU 的缓存也可以看到读取请求,并且数据是从缓存返回的,而不是从主 RAM 中返回的。 (这只是一个示例:实际实现取决于平台。例如,SoC 通常不保证外设 CPU 的强缓存一致性。)
在这两种情况下,缓存问题也存在于编译器级别:编译器可能会将数据值缓存在寄存器中。这就是为什么编程语言有一些方法来禁止这种优化:例如,C 中的volatile 关键字。
【讨论】: