更改 Windows 线程调度程序时间片

xak*_*p35 4 windows timer threads windows-10

这个问题是关于将 Windows 内核调整为像操作系统一样实时的可能性,以及实现它的方法。这是一个非常具体的狭窄主题,需要深厚的知识水平——你要么知道,要么不知道。

我在 WS2016 x64 平台上,我只能将计时器分辨率设置为 500us(0.5ms),调用库NtSetTimerResolution()中的函数ntdll.dll。我猜想这个值与调度程序时间片有关。

但是,我想将其增加到 100us。测量可能涉及在循环内多次调用包装NtDelayExecution()调用,然后分析抖动、标准偏差等统计数据。QueryPerformanceCounter()

这该怎么办呢?是否有任何注册表/文件调整,我可以在其中设置任意 Windows 调度程序时间片?


附言。有些人可能会问“为什么需要它? ”,或者说“不要这样做,这是错误的! ”。我预见到了这种想法,并会提前回答。

  • 这只是软件实验。它只是为了测试这样做的可能性和物理结果。
  • 我知道这可能会导致潜在的问题,例如在上下文切换上浪费额外的 cpu 时间、系统不稳定、不负责任、数据丢失以及它可能导致的任何问题。我接受提前这样做的任何负面后果并承担所有责任。即使我的机器会冒烟和火花:)
  • 根据谷歌搜索或在这里搜索 - ofc 我已经做到了,但未能找到有用的信息,因为这个主题非常狭窄,与操作系统调度程序的功能有关。在任何 Windows 机器上做几乎没有意义。我知道我不能把它变成实时的。该网站搜索“sheduler timeslice”没有给出结果。

Jam*_*han 6

调度程序时间片间隔不直接受计时器分辨率的影响。对于客户端 SKU 上的大多数进程,该时间为 20 毫秒;对于拥有前台窗口的进程,该时间为 60 毫秒。在服务器 SKU 上,这些值通常均为 120 毫秒。

无论您如何使用 NtSetTimerResolution,这些值都是相同的。无论定时器分辨率如何,在检测到 20 毫秒间隔之前都会对适当数量的定时器时钟中断进行计数,并且调度程序会递减当前线程的“量子”计数器等。

因此,如果您确实设法将计时器分辨率提高到 100 usec,则不会影响线程调度。然而,它会产生额外的开销,因为检查定时器是否已过期的例程调用次数是之前的 5 倍。

没有注册表或其他调整可以改变这一点。

有一个注册表黑客可以用来克服客户端 SKU 上发生的“时间片拉伸”,或者使服务器系统的行为像客户端一样,反之亦然,就时间片长度而言。有时(由于线程退出等待时对 Thread->Quantum 进行了一些调整)时间片可能比“应该”短一些。但无法将时间片设置为小于 20 毫秒,或者设置为 20 毫秒的倍数以外的任何值,并且可用的不同倍数并不多。

请注意,调度程序时间片间隔对抢占没有影响。当一个线程的等待被解决时,如果该线程的优先级高于新线程理想处理器上当前正在运行的线程的优先级,则后一个线程将立即被抢占。在被抢占之前,它不会运行到其时间片的末尾。仅当多个线程以相同优先级竞争时,时间片才重要。

来源:其中大部分内容来自Solomon、Russinovich等人的Windows Internals

  • 据我在reactos源代码中看到的(最好的猜测是我们从打开的源代码中得到的)[`NtQueryTimerResolution()`只返回一些整数](https://doxygen.reactos.org/df/d59/ntoskrnl_2ex_2time_8c_source.html#l00481 )在 [`KeSetTimeIncrement()` 函数](https://doxygen.reactos.org/d0/db9/ntoskrnl_2ke_2clock_8c_source.html#l00228) 中更改 (2认同)