我正在阅读mlockall()的联机帮助页:http://man7.org/linux/man-pages/man2/mlock.2.html
提到
Real-time processes that are using mlockall() to prevent delays on page
faults should reserve enough locked stack pages before entering the time-
critical section, so that no page fault can be caused by function calls. This
can be achieved by calling a function that allocates a sufficiently large
automatic variable (an array) and writes to the memory occupied by this array in
order to touch these stack pages. This way, enough pages will be mapped for the
stack and can be locked into RAM. The dummy writes ensure that not even copy-
on-write page faults can occur in the critical section.
我对这句话感到有点困惑:
This can be achieved by calling a function that allocates a sufficiently large
automatic variable (an array) and writes to the memory occupied by this array in
order to touch these stack pages.
创建所有自动变量(堆栈上的变量)"即时#34;在调用函数时在堆栈上。那么我怎样才能实现上一个陈述所说的内容呢?
例如,我们说我有这个功能:
void foo() {
char a;
uint16_t b;
std::deque<int64_t> c;
// do something with those variables
}
或者在我调用任何函数之前它是什么意思,我应该在main()中调用这样的函数:
void reserveStackPages() {
int64_t stackPage[4096/8 * 1024 * 1024];
memset(stackPage, 0, sizeof(stackPage));
}
如果是,如果我首先在堆上分配stackPage变量,写入然后释放它会有所不同吗?可能是的,因为堆和堆栈在RAM中是2个不同的区域?
上面存在的std :: deque只是为了提出另一个相关的问题 - 如果我想使用堆栈页面和堆栈页面保留内存。将呼叫&#34;堆&#34;版本的reserveStackPages()帮助?目标是最小化应用程序中的所有抖动(是的,我知道还有许多其他的东西要看,例如TLB miss等;只是试图同时处理一种抖动,然后慢慢地进入全部)。
提前致谢。
P.S。如果重要的话,这适用于低延迟交易应用程序。
答案 0 :(得分:1)
您通常不需要使用mlockall
,除非您编写(或多或少难)实时应用程序(我实际上从未使用过它)。
如果确实需要它,你最好用C代码(不是真正的C ++代码)编写代码的最实时部分,因为你肯定想要了解内存分配的细节。请注意,除非您深入了解std::deque
实现,否则您并不确切知道它所处的位置(即使您的c
是automatic variable)。
您应首先了解的详细信息您的流程的虚拟地址空间。为此,proc(5)非常有用:从您的流程中,您将从外部(例如某个终端)阅读/proc/self/maps
(请参阅this)cat /proc/1234/maps
对于pid 1234的过程。或者使用pmap(1)。
因为堆和堆栈是RAM中的两个不同区域?
事实上,您的流程的地址空间包含许多细分(在/proc/1234/maps
中列出),远远超过两个。通常,每个动态链接的共享库(例如libc.so
)都会带来一些段。
在终端中尝试cat /proc/self/maps
和cat /proc/$$/maps
以更好地直观了解虚拟地址空间。在我的机器上,第一个给出cat
进程的19个段 - 每一个显示为一行 - 以及zsh
(我的shell)进程的第二个97段。
为确保您的堆栈有足够的空间,您确实可以调用一个函数来分配足够大的自动变量,例如reserveStackPages
。请注意,调用堆栈的大小实际上有限(通常为几兆字节,另请参阅setrlimit(2))。
如果您确实需要mlockall
(这不太可能),您可以考虑静态链接您的程序(在虚拟地址空间中使用较少的段)。
同时查看madvise(2)(也许mincore(2))。它通常比mlockall
更有用。顺便说一句,实际上,你的大部分虚拟内存都在RAM中(除非你的系统实验thrashing,然后你会立即看到它。)
另请阅读Operating Systems: Three Easy Pieces以了解paging的作用。
PS。纳秒级敏感应用程序没有多大意义(因为软件无法控制cache misses)。