如何禁用某些内存区域的cpu缓存?

我在维基百科上读到,禁用cpu-cache可以提高性能

Marking some memory ranges as non-cacheable can improve performance,by avoiding caching of memory regions that are rarely re-accessed.

当我谷歌搜索如何在Linux上的c,但我没有找到任何东西.这不是我真的需要这个功能,但我仍然感兴趣.

你知道任何使用这种优化的项目吗?

编辑:我正在为x86_64编程

解决方法

关于非缓存的评论并不意味着您认为它意味着什么,以及它在何处使用,它通常不是用户可访问的功能.也就是说,cpu缓存控制通常是特权操作.

那说……

– 可以使用属性“热”或“冷”的函数构建普通用户程序,让编译器告诉加载器以最有效利用缓存的方式对函数进行分组.

一个普通的程序可以使用linux中的madvise()函数来告诉分页函数各种各样的事情,包括刚刚使用的内存很快就会再次使用的事实.

– 内核本身在后来的内核中使用Memory Type Range Regesters(mtrr)和Page Attribute Table(pat)标志来告诉硬件特定的内存范围(例如内存映射的显示缓冲区,以及内存的各个部分). PCI总线)不会被缓存.

诸如您可能在任何C程序中使用的“normal Data™”基本上永远不会从标记其任何数据而不是缓存中受益.非缓存数据所享有的性能改进是随后缺少内存映射设备和显示缓冲区几乎不断需要的各种缓存 – 刷新和内存屏障操作.例如,在内存映射设备上放置缓存需要在每次读取之前使用cache invalidate命令,并在每次写入之后执行缓存强制写入命令,以确保读取和写入在所需的确切时刻发生.这将“中毒”缓存使用,使用并以最不友好和无益的方式立即丢弃缓存行(物理上有限的资源).

在极少数情况下,您编写的程序可以访问其中一个缓存有害区域 – 例如,如果您在Linux系统上编写了部分X显示服务器 – 内核已经为设备设置了寄存器,非缓存行为对您来说是透明的.

实际上,您的正常应用程序等级程序无法将变量标记为对各种madvise()类型的使用之外的缓存有害.

即使在那时,你可以获得任何好处的案例是如此罕见,如果你曾经碰到一个,问题集将包括作为你研究的一部分的需要和方法,你会被告知如何和为什么所以明确地说你永远不需要问这个问题.

再次回到相同的例子,如果您正在编写必要的驱动程序,当您阅读显示适配器硬件或PCI总线时,各种标志和技术将被记录并在硬件指南中讨论.

有很多方法可以通过英特尔平台上的CLCLEAR指令等方式从用户空间中释放高速缓存弹出.这些技术不会改善一般性能.

由于它是Linux系统上的特权操作,因此您可以编写一个内核驱动程序,该驱动程序获取并将内存区域标记为不可缓存,然后让您将其映射到应用程序中.但是,对这样一个地区的需求是如此罕见,而且很可能被误用,因此没有一种正常的方法来实施.

你是怎么做到的?你没有,至少不是你今天的那个人.当您成为具有多线程代码和数据同步问题的亲密专业知识的内核驱动程序编写者时,您将知道如何做到这一点,并且此时您将知道为什么您不希望除了作为最后一招.

TL; DR ::由于linux使用和管理数据和代码的方式,将普通应用程序的任何部分标记为不可缓存,不会造成比保存更多的心碎,从来没有任何好处.因此,没有非特权的API可以做到这一点.

附:此外,有人说,有人已经指出了导致这篇文章http://lwn.net/Articles/255364/内容,其中介绍了使程序非常友好缓存的方法,以及一些可以非常便宜地执行缓存绕过操作的方法.例如,memset()的使用倾向于在设置内存时围绕缓存,并且一些操作可以“流过”缓存.这与你提出的问题不同,但是一旦你理解了所有这篇文章,你就会更好地理解为什么将内存区域标记为无法访问通常,正如绝地所说,不是你的解决方案寻找.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...