Windows 原理
Windows 原理
Windows的线程调度
No central scheduler! i.e. there is no always-instantiated routine called “the scheduler” The “code that does scheduling” is not a thread Scheduling routines are simply called whenever events occur that change the Ready state of a thread Things that cause scheduling events include: interval timer interrupts (for quantum end) interval timer interrupts (for timed wait completion) other hardware interrupts (for I/O wait completion) one thread changes the state of a waitable object upon which other thread(s) are waiting a thread waits on one or more dispatcher objects a thread priority is changed Based on doubly-linked lists (queues) of Ready threads Nothing that takes “order-n time” for n threads
没有中央调度器! 也就是说,没有总是实例化的例程称为“调度程序” “执行调度的代码”不是线程 只要发生更改线程的就绪状态的事件,就可以简单地调用调度例程 导致安排事件的事件包括: 间隔计时器中断(用于量子结束) 间隔计时器中断(用于定时等待完成) 其他硬件中断(用于I / O等待完成) 一个线程更改其他线程正在等待的等待对象的状态 线程等待一个或多个调度程序对象 线程优先级已更改 基于就绪线程的双链接列表(队列) n个线程不需要花费“ order-n time”
出处 D:\uTorrentPortable\Data\downloads\Microsoft leaked source code archive_2020-09-24\windows_research_kernel\Windows Kernel Source Code like\Windows Operating System Internals Curriculum Resource Kit (CRK)\UnitOS4
计时器中断时间有多长
计时器中断之间的间隔取决于Windows版本和您的硬件,但在我最近使用的每台计算机上,默认间隔为15.625毫秒(1,000毫秒除以64)。这意味着,如果您在某个随机时间调用Sleep(1),那么将来每当下一个中断触发时(或者如果下一个中断过早,则在此之后触发),您可能会在1.0毫秒至16.625毫秒之间的某个时间被唤醒。 。
出处
https://randomascii.wordpress.com/2020/10/04/windows-timer-resolution-the-great-rule-change/
如果运行的线程数少于core数,系统还会由于计时器中断定期切换到内核态吗
应该是的
在现代操作系统(如Windows,MacOS或Linux)中,每个线程(即将运行的线程)都有标准的时间间隔。在此时间间隔内,线程还可以等待某些东西(IO,同步原语),这也导致在此CPU上调度另一个线程。同样,如果时间段结束,调度程序将开始执行另一个线程。调度程序与计时器中断一起工作,以大约几毫秒的分辨率完成此任务。
https://stackoverflow.com/questions/22594589/how-processor-is-switched-from-user-mode-to-kernel-mode
切换到内核态需要多长时间
https://www.quora.com/How-many-cycles-does-it-take-to-switch-from-user-mode-to-kernel-mode-on-an-x86-x64-chip-(Windows-or-Linux-Unix)
A raw hardware switch, i.e. a sysenter directly to a sysexit instruction is in the 100-200 cycle range, comparable to a bad cache miss. The folklore that kernel/user crossings are insanely expensive in the hardware is a holdover from days when the hardware costs were 4-5x more heavyweight. A frequently espoused, and bogus, belief is that the TLB gets flushed on user/kernel boundaries, and this just ain’t so in x86.
However, in practice you don’t sysenter to a raw sysexit, but to a big long chain of software that does a SWAPGS and saves a bunch of state and enables interrupts and so on. There are also the usual hardware costs of changing paths: TLB and cache misses and worse, evictions of useful user cached state. In practice the leanest, meanest system call you’re likely to pull off, e.g. getppid, will take 1000 cycles or so.
L1高速缓存未命中的成本是多少?
数字来自CPU缓存刷新谬论博客文章,该文章表明对于特定2012年代英特尔处理器,以下内容是正确的:
- 寄存器访问=每个周期4条指令
- L1延迟= 3个周期(12 x寄存器)
- L2延迟= 12个周期(4 x L1,48 x寄存器)
- L3等待时间= 38个周期(3 x L2、12 x L1、144 x寄存器)
- 在3 GHz CPU上DRAM延迟= 65 ns = 195个周期(5 x L3、15 x L2、60 x L1、720 x寄存器)
该处理器高速缓存影响的画廊也使得有关这个主题的良好的阅读。