如何在Windows或Linux等操作系统上测量时间片的长度



有没有办法获取时间片的长度?如何设计一个实验来以某种方式弄清楚它,比如一段 C 代码?

我已经详细阅读了名为"如何知道 Linux 调度程序时间片?"的相关问题,但没有关于如何使用 C 在 win 10 上获取时间片的答案。

这有一个困难的挑战,因为根据定义,计时器中断是异步的,内核可以决定在任何计时器中断上抢占你的进程。或不。

也许您可以访问(好吧,如果您计划一个如此具有挑战性的问题,我假设您拥有管理员权限)一个内核变量,该变量记录了它所做的上下文切换的数量,因此,计算您的进程自过去一段时间以来从 CPU 中调度出的次数。

事实是,当你第一次开始计时时,然后当你试图看看发生了什么时,你就会被安排。

试图知道你的进程被编程点之间的某些东西中断了多少次是一项艰巨的任务,因为有很多设备在这样做,而且一般来说,你不能假设在任何一个中断处都有上下文切换。通常,内核维护计数器以了解已计算了多少 X 类型的中断,您可以使用计数器值的差异来了解从那时起发生了多少 X 类型的中断。 哪些,或者它们如何变成进程(或线程)上下文切换通常不可用,但通过查看内核源代码。

但。。。。您有一个简单的方法来检查估计值。 如果使用系统中可用的不同clock_gettime时钟来比较时间,则可以估计进程代表其消耗的 CPU 时间量以及系统执行其他操作的时间量。 您将从时钟之间的差异中获得一个粗略且不精确的值。 例如 FreeBSD 有

  • CLOCK_VIRTUAL仅当 CPU 代表调用进程在用户模式下运行时递增。
  • CLOCK_PROFCPU 在用户或内核模式下运行时递增。
  • CLOCK_PROCESS_CPUTIME_ID返回调用进程的执行时间。
  • CLOCK_THREAD_CPUTIME_ID返回调用线程的执行时间。
  • CLOCK_REALTIME_PRECISE像挂钟一样递增。

所以你有很多时钟可供选择。 在Linux中,时钟的数量减少了,但无论如何,大多数时候你可以对此有所了解。

注意

从您的评论中:

@ЯрославМашко 我已经尝试过了,答案为 15 毫秒,但是有没有办法通过创建进程到全 CPU 来观察时间片切换来解决它?

你不能在用户进程中这样做,因为显而易见的原因,它将被内核调度出来,以允许其他进程做,然后你什么都不能测量。 从这个意义上说,任何事情都需要接触大量的内核代码,并且使您的系统效率非常低,因为它需要时间在每个上下文切换时收集所有信息。 但是您拥有完整的内核源代码,也许您可以研究这种方法。 普通工具,如top(1)htop(1)确实会访问内核更新计数器的内核变量,并获得内核正在执行的操作的一些平均值......这是因为记录一个进程要处理的所有内核活动是一种递归情况,您所做的所有进程也必须考虑在内,并且您将陷入无限递归循环,其中系统负载受到更严重的损坏,因为您想要的结果更精细。

有些处理器(很可能是基于ARM的)具有调试模块,允许它们在专用线路上吐口水,它们在全速运行时执行的所有活动。 但是它们提供的信息量通常由更强大的系统处理,能够消化这些CPU发出的大量信息。 在任何情况下,由于信息永远不会在调试的系统中消耗,这并不代表问题(递归性打破了循环)

顺便说一句,检查您在发布的另一条评论中是否获得了 15 毫秒似乎很奇怪。 你在 15 毫秒内被重新安排了,但要进行测量,你必须再做两次系统调用(总共三次,两次系统调用要求时钟时间,一次休眠最短时间)这意味着什么,因为内核通常允许进程正常运行更多时间,如果必须这样做。 进行上下文切换意味着切换其所有虚拟地址空间,这意味着使大量内存缓存信息无效,并且会大大降低 CPU 的速度,因此通常内核允许进程片超过此范围,以防需要它。 如果您能够在如此短的时间内再次切换回您,可能是因为您的进程是唯一有资格运行的进程,在这种情况下,最可能的事情是内核在这段时间内没有安排任何内容。 内核允许进程运行的最长时间,因此系统不会被一个耗时的 CPU 进程锁定。 但是没有进程完全消耗它的时间段也是正常的......因此,要从这个意义上进行任何测试,您需要多个以完整 CPU 运行的进程,以查看内核如何为每个进程提供 CPU。

在正常的 64 位英特尔 CPU 中, FreeBSD 上的内核以 1000ticks/s 的速度运行, 这意味着, 通常情况下, 内核以 1/1000 秒的间隔决定, 如果它切换 CPU 到一个进程或另一个进程。 但很多时候它决定不切换进程,而是继续更多地运行 cpu 内进程。 在 Linux 中,你可以让它不滴答作响,这意味着计时器不会以固定的速率中断 CPU,而只是当某些东西打开要唤醒的计时器时。

最新更新