加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

在Linux中进行堆栈预测 – 需要单个或多个故障

发布时间:2020-12-14 02:20:39 所属栏目:Linux 来源:网络整理
导读:在 Linux中,当进程从系统请求某些(虚拟)内存时,它只是在vma(进程的虚拟内存的描述符)中注册,但是在调用时不保留每个虚拟的物理页面.稍后,当进程将访问此页面时,它将出现故障(访问将生成Page Fault中断),PF#handler将分配物理页面和更新进程页面表. 有两种情
在 Linux中,当进程从系统请求某些(虚拟)内存时,它只是在vma(进程的虚拟内存的描述符)中注册,但是在调用时不保留每个虚拟的物理页面.稍后,当进程将访问此页面时,它将出现故障(访问将生成Page Fault中断),PF#handler将分配物理页面和更新进程页面表.

有两种情况:读取时的故障可能变为写入保护的零页面(特殊全局预归零页面)的链接;写入错误(无论是在零页面上还是在刚刚需要但未物理映射的页面上)都将导致实际的私有物理页面分配.

对于mmaps(和brk / sbrk,也是内部mmap),这个方法是每页;所有mmaped区域都在vma中注册为整体(它们具有开始和结束地址).但堆栈是以其他方式处理的,因为它只有起始地址(在典型平台上较高的地址;增长到较低地址).

问题是:

当我在堆栈附近访问新的未分配内存时,它将获得PF#并且增长.如果我不访问堆栈旁边的页面,而是访问堆栈10或100页的页面,这种增长如何处理?

例如.

int main() {
  int *a = alloca(100); /* some useful data */
  int *b = alloca(50*4096); /* skip 49 pages */
  int *c = alloca(100);

  a[0]=1;
 /* no accesses to b - this is untouched hole of 49 pages */
  c[0]=1;

}

该程序是否会为堆栈分配2或50个私有物理页面?

我认为要求内核在单个页面故障中分配数十个物理页面然后进行逐页分配的数十个页面故障是有利可图的(1个中断1上下文切换简单,缓存友好的循环遍历N个页面分配请求与N个中断N上下文 – 当mm代码可以从Icache中逐出时,切换N页分配.

解决方法

堆栈的自动增长可以被认为是对mremap的自动调用,以调整计为“堆栈”的虚拟地址区域的大小.一旦处理完毕,对堆栈区域或香草mmap区域的页面错误处理相同,即一次一页.

因此,您最终应该分配~2页,而不是?51页. @perreal的经验回答验证了这一点……

对于问题的最后部分,连续页面错误的成本是导致“大页面”发展的因素之一.我不认为Linux中还有其他方法可以“批量”处理页面错误.也许madvise可能会做一些事情,但我怀疑它主要是优化真正昂贵的页面错误部分,它正在查找存储上的后备页面).相比之下,映射到零页面的堆栈页面错误相对较轻.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读