linux - 使用TSC作为时钟源是否提高定时器和调度粒度?

标签 linux timer linux-kernel operating-system

在支持时间戳计数器 (TSC) 的处理器中,Linux 使用 TSC 提供高分辨率计时器选项。据我了解,TSC 是一个可以读取的寄存器,但不提供以配置的速率中断 CPU 的选项。因此,对于 Linux 中的定时器中断生成,仍然必须依赖 I/O APIC(在 x86 上),HZ 值通常设置为 1000 或 250。

即使 TSC 以微秒为粒度提供时间戳,定时器/调度粒度仍为 4 毫秒或 1 毫秒,具体取决于 HZ 值。这种理解是否正确?或者是否有使用 TSC 改进计时器粒度的选项?

最佳答案

在默认的 Linux 2.6 内核中,可编程中断 Controller (PIT)(适用于所有 PC)用作系统计时器 [1]。 PIT,顾名思义,可以通过编程(通常是在内核启动时)以预定的速率中断 CPU。这个预定的速率就是你所指的HZ值,它是一个静态编译的值,等于内核编译参数CONFIG_HZ。[2]因此,您可以在编译时修改 CONFIG_HZ,PIT 将以上述频率开始中断 CPU。但是,请记住,PIT 由大约 1.193 MHZ 的时钟内部驱动,因此将 CONFIG_HZ 设置为大于此值并不是一个好主意。正如 [3] 中指出的那样

the timer of the local APIC (Advanded Programmable Interrupt Controller) in multiprocessor systems is used for interprocessor synchronization

根据 [1] 中的解释,我相信它的 PIT(而不是本地 APIC)与 HZ 值相关(至少直到 2.6 内核)。

现在,回到你的问题,理论上你的想法看起来是正确的。与本地 APIC 和 PIT 一样的时间戳计数器是另一种时间源[1]。在 [4] 中,您可以找到对此的确认。

Linux may take advantage of this register to get much more accurate time measurements than those delivered by the Programmable Interval Timer. To do this, Linux must determine the clock signal frequency while initializing the system. In fact, because this frequency is not declared when compiling the kernel, the same kernel image may run on CPUs whose clocks may tick at any frequency.

但是,请记住时间戳计数器在每个 CPU 时钟周期递增。这给我们带来了与 CPU 时钟周期相关的计数器相关的棘手陷阱 [5]。一个例子是现代 CPU 可以改变它们的 CPU 时钟速率以节省电力,这会影响存储在时间戳计数器中的值。如果发生这种情况,您可以估计它对您的时间测量的影响。此外,绝对空闲的内核可能会调用 HALT 指令,该指令会完全停止处理器,直到接收到外部中断。一直以来,TSC 永远不会增加,您会失去一些宝贵的“增量”,否则会使您的测量更加精确。简而言之,处理 TSC 是一个难题,不是特别适合用作可编程中断。

  1. Robert Love,LKD -- 第 3 版。 (第 11 章)
  2. http://lxr.linux.no/linux+v2.6.31/arch/x86/include/asm/param.h#L5
  3. http://www.6test.edu.cn/~lujx/linux_networking/0131777203_ch02lev1sec7.html
  4. http://www.makelinux.net/books/ulk3/understandlk-CHP-6-SECT-1
  5. http://lwn.net/Articles/209101/

关于linux - 使用TSC作为时钟源是否提高定时器和调度粒度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13950264/

相关文章:

c - Linux 中系统调用的返回值大小或类型

php - 使用 NodeJS + 实时输出从 Web 运行 Linux 命令

linux - 在sed中替换具有正斜杠的字符串

c++ - linux中进程的堆栈大小是否有限制

c# - 1 综合计时器 vs. 多个计时器,每个对象一个计时器

c - Linux - 为什么阻塞和忽略的信号处于待处理状态?

lxml 安装期间出现 python gcc 和 setuptools 错误

java - 如何每天下午 2 点运行 TimerTask?

ios - swift : How to update a label every second (or shorter) with a timer?

c - Linux 内核 0.11 中的进程 0 堆栈