当前位置: 首页 > 面试题库 >

是否可以在用户空间上在Linux上分配不可缓存的内存块?

邹齐智
2023-03-14
问题内容

我的应用程序中有一堆缓冲区(其中25到30个),它们很大(.5mb),可以同时访问simulataneousley。更糟糕的是,它们中的数据通常只读取一次,并且经常更新(例如每秒30次)。某种非最佳缓存使用的完美风暴。

无论如何,我想到,如果我可以将内存块标记为不可缓存,那将是很酷的……从理论上讲,这将为其他所有内容在缓存中留出更多空间。

那么,他们是否有办法获得在Linux中标记为不可缓存的内存块?


问题答案:

每个程序员都应该了解的内存(PDF)中介绍了如何避免像这样的数据污染缓存-
这是从Red Hat开发的角度写的,对您而言如此完美。但是,大多数都是跨平台的。

您想要的被称为“非临时访问”,并告诉处理器期望您现在正在读取的值将在一段时间内不再需要。然后,处理器避免缓存该值。

请参阅上面链接的PDF的第49页。它使用intel内在函数来进行高速缓存周围的流传输。

在读取方面,直到最近,除了使用非临时访问(NTA)预取指令的弱提示之外,处理器都缺乏支持。没有等同于读取的写合并,这对于不可缓存的内存(例如内存映射的I
/
O)尤其不利。英特尔通过SSE4.1扩展引入了NTA负载。它们使用少量的流负载缓冲区来实现。每个缓冲区包含一个缓存行。给定高速缓存行的第一条movntdqa指令会将高速缓存行加载到缓冲区中,可能会替换另一条高速缓存行。后续的16字节对齐访问同一高速缓存行将以很小的代价从加载缓冲区进行服务。除非有其他原因,否则缓存行不会加载到缓存中,这样就可以加载大量内存,而不会污染缓存。编译器为此指令提供了一个内在函数:

#include <smmintrin.h>
__m128i _mm_stream_load_si128 (__m128i *p);

此内在函数应多次使用,并以16字节块的地址作为参数传递,直到读取每个高速缓存行。只有这样才能启动下一个缓存行。由于有一些流读取缓冲区,因此可能可以一次从两个内存位置读取

如果在读取时通过存储器以线性顺序读取缓冲区,则对您而言将是完美的。您使用流读取来这样做。当您要修改它们时,缓冲区将按线性顺序进行修改,如果您不希望很快再从同一线程读取它们,则可以使用流式写入来执行。



 类似资料:
  • 我在学计算机工程,我有一些电子课程。我从我的两位教授(这些课程)那里听说,可以避免使用函数(在、等之后),因为分配的内存空间可能不会再次用于分配其他内存。也就是说,例如,如果您分配4个字节,然后释放它们,您将有4个字节的空间,可能不会再次分配:您将有一个洞。 我认为这太疯狂了:你不可能有一个在堆上分配内存而不释放内存的非玩具程序。但是我没有知识来解释为什么它如此重要,对于每一个malloc()必须

  • 问题内容: 似乎在Windows 32位上,内核将从全部4G用户虚拟内存空间中保留1G虚拟内存,并将 某些 内核空间映射到此1G空间中。 所以我的问题是: 在32位Linux上是否有类似情况? 如果是这样,我们如何看到整个内存布局? 我认为 只能看到某些过程的用户空间布局。 谢谢! 问题答案: 实际上,在32位Windows上,如果没有引导选项,内核将映射到线性地址空间的前2GB,剩下2GB的空间

  • 我目前使用的是apache ignite 2.3.0和java API。我有一个具有两个节点和两个不同缓存的数据网格。一个是本地的,另一个是分区的。 假设我的本地缓存位于节点#1上。 谢谢

  • 问题内容: 我正在尝试打电话 直接,但获得EFAULT错误代码。出现此错误是因为 buf 指向内核空间中的内存。 那么,是否有可能从内核分配用户空间内存? 与 内核内存相似并返回指向内核内存的指针。 问题答案: 您可以使用以下方法临时禁用内存地址有效性检查:

  • 问题内容: 我在一个具有不同进程的应用程序上工作,并被要求包含那些进程以实现更多隔离。 问题在于,进程与单个“管理程序”进程共享内存以便交换数据(它们使用经典的共享缓冲区)。该解决方案是为满足性能要求而实施的,因为它在用户空间中运行,因此在用户空间和内核空间之间没有内容切换。 如果我没看错,则不可能在单个IPC名称空间内运行多个docker容器,但是我不知道单个docker容器是否可能属于不同的I

  • 为什么不检查它是否可以分配内存? 摘自: 如果分配导致堆栈溢出,则程序行为未定义。…如果无法扩展堆栈帧,则没有错误指示。 现在和都返回一个指针,指向新分配的内存的开始,这意味着它们都必须知道堆栈/堆在当前时刻的结束位置。实际上,来自: 调用增量为0的sbrk()可以用来查找程序中断的当前位置。 因此,按照我的理解,检查是否可以分配所需的内存,本质上归结为检查堆栈的当前末端和堆的当前末端之间是否有足