使用不可缓存内存的最佳实践

问题描述 投票:0回答:1

我读了这篇文章为什么内存区域会被标记为非缓存? 但除了“与硬件通信”的内存区域(例如 DMA)之外,没有提到其他原因。

还有其他充分的理由将内存标记为不可缓存吗?

附注似乎可以通过

mmap()
MAP_NOCACHE
标志将内存标记为不可从用户空间缓存,不是吗?

UPD

来自wiki

将某些内存范围标记为不可缓存可以提高性能, 通过避免缓存很少重新访问的内存区域。 这避免了将某些内容加载到缓存中的开销,而无需 有任何重用。缓存条目也可能被禁用或锁定 取决于上下文。

粗略地说,就是不让缓存不需要的数据堵塞缓存。即,不乱扔垃圾。
维基百科似乎在某种程度上误导了我们,因为它无法在任何广泛使用的操作系统上以这种方式提高性能..

c linux caching memory-management linux-kernel
1个回答
3
投票

还有其他充分的理由将内存标记为不可缓存吗?

不完全是,至少在 Linux 上不是。然而,存在很多可能的缺点。事实上,您无法使用

mmap
在 Linux 中创建未缓存的映射。

您提到的

MAP_NOCACHE
标志在 Linux 中不存在,但在 macOS 中存在,即使在那里,它似乎也不意味着未缓存的内存,而是与内核页面缓存相关(请参阅 macOS 的
man 2 mmap
) .

对于未缓存内存映射而言,一个可能被认为有趣的应用是保护来自架构缓存侧通道的数据,例如Meltdown。事实上,不久前就考虑过为用户空间提供创建未缓存映射的能力,以实现

memfd_secret
系统调用,但在 Andy Lutomirski 的建议下被废弃,他解释说:

我还没有准备好在 x86 上确认未缓存的映射。我很好 允许特权用户在 x86 上创建 UC 内存的概念 用于测试和实验,但它是一大堆蠕虫 一般的。立即想到的问题是:

  • 性能和 DoS 潜力。统一通信将具有奇怪的、依赖于架构和平台的性能特征。据我所知, 甚至访问语义也可能依赖于体系结构。我不是 确信可以使用未缓存的 C 语言编写可移植代码 特征。我还担心某些操作(未对齐的锁, 例如,可能任何锁定的访问)将触发总线锁定 x86,根据 CPU 和内核配置,将拒绝所有 其他CPU或发送信号。 (或者导致虚拟机管理程序终止或 否则会惩罚虚拟机,这会很糟糕。)

  • 正确性。我有报告称不同的 x86 虚拟机管理程序使用 UC 映射执行不同的操作,包括将它们视为常规的 WB 映射。所以当你要求时你得到的内存类型 “未缓存”实际上可能并未未缓存。

UC实际上是一个MMIO功能,而不是“保护我的数据”功能。滥用 它保护数据当然很有趣,但我还远没有做到 确信这是明智的。我特别不相信 猴子修补程序以在需要时使用未缓存的内存 定期分配内存是合理的做法。

© www.soinside.com 2019 - 2024. All rights reserved.