Messages in this thread |  | | Date | Fri, 7 Feb 1997 08:05:12 -0500 | From | "Theodore Y. Ts'o" <> | Subject | Re: MMX for kernel |
| |
From: Olaf Titz <olaf@bigred.inka.de> Date: 07 Feb 1997 12:02:09 +0100
Jason Flynn <flynnjs@mobile-systems.bt.co.uk> wrote: > isn't it the process of clearing the registers (cos MMX and FPU > use the sam ones) and clearing the pipeline that takes these cycles ? > And surely this would be done anyway during task switching so > the only extra overhead is if you mix types within one task.
If the active task uses FPU registers, you have to save and restore the FPU state (unless you are sure the FPU is clear, but this can't be assured in the kernel). This alone takes really many cycles, at least 174 of them in the best case (all cache hits), not even counting mode switches, clearing etc.
The really important point (which I think Jason didn't understand) is that the FPU registers *aren't* saved and restored across task switches. The kernel plays a lazy evaluation game; there is a pointer which points to the task which last used the FPU, and if the task that is currently running isn't that task, the FPU is set to be *invalidated*, which causes the i386 hardware to perform a fault to the kernel when an FPU instruction is attempted. At that point, the kernel saves the FPU registers for the old task, loads the FPU registers for the currently running task, and restarts the instruction.
The advantage of this scheme is that is most tasks don't use the FPU (which generally is the case), you don't have to incur the overhead of saving the FPU for each task switch.
If there were many, many proceses which used the FPU, one could imagine an advisory bit which meant "when task switching to this process, immediately restore my FPU registers, since I'm an intensive FPU user". This would avoid the hardware fault after each task switch to that process if there were many processes using the FPU. However, this hasn't been implemented yet, and in practice it hasn't seemed to have been a problem.
As a result, though, if the kernel wants to use the FPU registers, it absolutely will have to save and then restore them, to avoid screwing up the above scheme. Actually, what we could do is put in better logic to determine whether or not the FPU is in use by a task (which is harder than you think because crt0 does zero them out, so you have to filter out that case), and then if the FPU isn't in use, you wouldn't need to restore the FPU right away. (You'd still have to do the lazy save, to avoid losing the current FPU state.)
The bottom line, though, is that it's not enough to just simply point out how many cycles a MMX or FPU-based kernel memcpy or ip checksum routine would save. You also have to look at the overall system performance for a systems where either (a) there are very few FPU-using tasks or (b) where there are very many FPU-using tasks, and you potentially have to radically alter the FPU register management strategy that's currently used by the kernel.
- Ted
|  |