![更改 Windows 线程调度器时间片](https://linux22.com/image/1561990/%E6%9B%B4%E6%94%B9%20Windows%20%E7%BA%BF%E7%A8%8B%E8%B0%83%E5%BA%A6%E5%99%A8%E6%97%B6%E9%97%B4%E7%89%87.png)
这个问题是关于调整 Windows 内核以实现像 OS 一样的实时性的可能性,以及实现它的方法。这是一个非常具体的狭窄主题,需要深层次的知识 - 你要么知道,要么不知道。
我在 WS2016 x64 平台上,并且我只能将定时器分辨率设置为 500us(0.5 毫秒),调用库NtSetTimerResolution()
中的函数ntdll.dll
。我猜这个值与调度器时间片有关。
然而,我想将其增加到 100us. 测量可能涉及在循环内多次调用包装NtDelayExecution()
中的调用QueryPerformanceCounter()
,然后分析抖动、标准偏差等统计数据。
这该怎么办呢?是否有任何注册表/文件调整,我可以在其中设置任意的 Windows 调度器时间片?
PS. 有人可能会问“你为什么需要它?",或声明“别这么做,这是错的!”“。我预见到了这种想法,并会提前回答。
- 这只是软件实验。它只是为了测试这样做的可能性和物理结果。
- 我知道这可能会导致潜在的问题,比如仅在上下文切换上就浪费了额外的 CPU 时间、系统不稳定、不负责任、数据丢失以及它可能引起的任何问题。我接受提前这样做的任何负面后果并承担所有责任。即使我的机器冒出烟雾和火花 :)
- 按照谷歌搜索或在这里搜索 - 当然我已经这样做了,但找不到有用的信息,因为这个主题非常狭窄,与操作系统调度程序功能有关。而且在任何 Windows 机器上这样做几乎毫无意义。我知道我无法将其变成实时的。在这个网站上搜索“sheduler timeslice”没有结果。
答案1
调度程序时间片间隔不受计时器分辨率的直接影响。对于客户端 SKU 上的大多数进程,该间隔为 20 毫秒;对于拥有前台窗口的进程,该间隔为 60 毫秒。在服务器 SKU 上,这些值通常均为 120 毫秒。
无论您使用 NtSetTimerResolution 做什么,这些值都是相同的。无论计时器分辨率如何,在检测到 20 毫秒间隔之前都会计算适当数量的计时器时钟中断,并且调度程序会减少当前线程的“量子”计数器,等等。
因此,如果您确实设法将计时器分辨率提高到 100 微秒,则不会影响线程调度。但是,这将产生额外的开销,因为检查计时器是否已过期的例程调用次数是以前的 5 倍。
没有注册表或其他调整可以改变这一点。
有一种注册表黑客技术可用于解决客户端 SKU 上发生的“时间片延长”问题,或者就时间片长度而言,使服务器系统表现得像客户端或反之亦然。有时(由于线程退出等待时对 Thread->Quantum 进行了一些调整)时间片可能比它“应该”的要短一点。但是没有办法将时间片设置为小于 20 毫秒,或者设置为 20 毫秒的倍数以外的任何值,并且没有太多不同的倍数可用。
请注意,调度程序时间片间隔对抢占没有影响。当线程的等待得到解决时,如果该线程的优先级高于新线程理想处理器上当前运行的线程的优先级,则后者线程将被抢占立即地。它无法运行到时间片结束前就被抢占。时间片仅在多个线程以相同优先级竞争时才重要。
来源:大部分内容Windows 内部原理作者:所罗门·鲁西诺维奇等人。