页面错误是否意味着 CPU 被阻塞,直到页面被带入 RAM? [英] Does Page fault means CPU blocked until the page is brought into RAM?

查看:73
本文介绍了页面错误是否意味着 CPU 被阻塞,直到页面被带入 RAM?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当页面错误发生时,我不太确定哪些工作将由 CPU 完成,哪些将由操作系统完成.这就是为什么我要问以下问题.

I am not quite sure about which work will be done by CPU and which will be done by the OS when a page fault occurs. That's why I'm asking the following questions.

考虑一个单核 CPU,运行多个进程.当发生页面错误时,操作系统会尝试从磁盘中获取所需的页面到 RAM,这将花费很长时间.在这段时间内,CPU 能否继续执行?还是 CPU 必须等到所需的页面加载到 RAM 中?

Consider a single-core CPU, with several processes running. When a page fault occurs, the OS would try to fetch the required page from disk to RAM, which will cost a long time. During this time period, can the CPU keep on executing? Or the CPU has to wait until the required page is loaded into RAM?

如果 CPU 可以继续执行而不等待所需的页面,那么当进程过多时可能会发生抖动.在某个时刻,CPU 执行的大部分指令都会导致页面错误,然后大部分时间将用于等待 OS 将页面从磁盘加载到 RAM.这就是为什么会发生颠簸.请问我的理解是否正确?

If the CPU can keep on executing without waiting for the required page, then thrashing may occur when there are too many processes. At some moment, most of the instructions that the CPU executes will cause page faults, then the most of the time spent will be waiting for OS loading the pages from disk to RAM. That's why thrashing occurs. May I know if my understanding is correct?

提前致谢.

更新:这个网站很好地描述了抖动.

Update: this website describes thrashing very well.

推荐答案

CPU 不知道它在"页错误.CPU 不是递归的

The CPU doesn't know that it's "in" a page fault. CPUs aren't recursive!

当 32 位 x86 CPU(例如)遇到页面错误时,它会执行以下操作(稍微简化):

When a 32-bit x86 CPU (for example) encounters a page fault, here's what it does (slightly simplified):

  • 将 CR2 的值设置为导致页面错误的地址.
  • 查看中断描述符表和其他一些表,找到页面错误处理程序(新 CS、新 EIP)和内核堆栈(新 SS、新 ESP)的地址.
  • 将 CS、EIP、SS 和 ESP 的值设置为刚读取的值.
  • 将旧的 SS、旧的 ESP、EFLAGS、旧的 CS 和旧的 EIP 压入堆栈.
  • 将 SS、ESP、EFLAGS、CS 和 EIP 寄存器推送到该堆栈上.
  • 更新标志以表明我们现在处于内核模式.

就是这样.现在,当内核想让 CPU 返回到它在页面错误发生之前所做的事情时,堆栈上有一些数据.但是内核没有义务使用这些数据.它可能会回到完全不同的地方,或者永远不会回去.这取决于内核.CPU 不在乎.

That's all it does. Now, there is some data on the stack that the kernel uses when it wants to make the CPU go back to what it was doing before the page fault happened. But the kernel isn't obligated to use that data. It could go back somewhere entirely different, or it could never go back. It's up to the kernel. The CPU doesn't care.

通常的内核将首先保存所有其他寄存器(重要!),查看地址,决定从哪里获取页面,告诉磁盘开始获取页面,注意该进程因页面错误而停止,然后它会继续做一些完全不同的事情,直到数据从磁盘返回.例如,它可能运行不同的进程.如果没有进程可以运行,它可能会关闭 CPU(是的,真的).

A usual kernel will first save all the other registers (important!), look at the address, decide where to get the page, tell the disk to start fetching the page, make a note that the process is stopped because of a page fault, and then it will go and do something entirely different until the data comes back from the disk. It might run a different process, for example. If there are no processes left to run, it might turn off the CPU (yes, really).

最终数据从磁盘返回,内核看到由于页面错误有一个进程在等待该数据,它更新页表以便进程可以看到数据,并重置所有寄存器,包括 SS、ESP、EFLAGS、CS 和 EIP.现在 CPU 正在做它之前做的所有事情.

Eventually the data comes back from the disk and the kernel sees that there's a process waiting for that data because of a page fault, and it updates the page table so the process can see the data, and it resets all the registers, including SS, ESP, EFLAGS, CS, and EIP. Now the CPU is doing whatever it was doing before.

要注意的关键点是:CPU 只关心现在寄存器中的内容!它没有长期记忆.如果您将寄存器值保存在某处,您可以让它停止做它正在做的事情,并在稍后恢复它,就好像什么也没发生过一样.例如,绝对没有要求您必须按照它们发生的顺序从函数调用中返回.CPU 不关心您是否有一个返回两次的函数,例如(参见 setjmp),或者如果您有两个协程并且在一个协程中调用 yield 会导致 yield 返回另一个.您不必像在 C 中那样按堆栈顺序执行操作.

The key point to notice is: the CPU only cares what's in its registers right now! It doesn't have a long-term memory. If you save the register values somewhere, you can make it stop doing whatever it was doing, and resume it later as if nothing ever happened. For example, there is absolutely no requirement that you have to return from function calls in the order they happened. The CPU doesn't care if you have a function that returns twice, for example (see setjmp), or if you have two coroutines and calling yield in one coroutine causes yield to return in the other one. You don't have to do things in stack order like you do in C.

这篇关于页面错误是否意味着 CPU 被阻塞,直到页面被带入 RAM?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆