支持的版本:当前 (17) / 16 / 15 / 14 / 13
开发版本:开发版
不支持的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2

pg_test_timing

pg_test_timing — 测量计时开销

概要

pg_test_timing [选项...]

描述

pg_test_timing 是一个用于测量系统计时开销并确认系统时间永远不会倒退的工具。 收集计时数据较慢的系统可能会给出不太准确的 EXPLAIN ANALYZE 结果。

选项

pg_test_timing 接受以下命令行选项:

-d 时长
--duration=时长

指定测试时长,以秒为单位。 较长的时长可以提供稍微好一些的准确性,并且更有可能发现系统时钟倒退的问题。 默认测试时长为 3 秒。

-V
--version

打印 pg_test_timing 版本并退出。

-?
--help

显示有关 pg_test_timing 命令行参数的帮助信息,并退出。

用法

解释结果

良好的结果将显示大多数(> 90%)单个计时调用花费的时间少于 1 微秒。 每个循环的平均开销甚至更低,低于 100 纳秒。 以下来自使用 TSC 时钟源的 Intel i7-860 系统的示例显示了出色的性能:

Testing timing overhead for 3 seconds.
Per loop time including overhead: 35.96 ns
Histogram of timing durations:
  < us   % of total      count
     1     96.40465   80435604
     2      3.59518    2999652
     4      0.00015        126
     8      0.00002         13
    16      0.00000          2

请注意,每个循环的时间和直方图使用了不同的单位。 循环可以具有在几个纳秒(ns)内的分辨率,而单个计时调用只能解析到 1 微秒(us)。

测量执行器计时开销

当查询执行器使用 EXPLAIN ANALYZE 运行语句时,将对各个操作进行计时,并显示摘要。 您的系统的开销可以通过使用 psql 程序计算行数来检查:

CREATE TABLE t AS SELECT * FROM generate_series(1,100000);
\timing
SELECT COUNT(*) FROM t;
EXPLAIN ANALYZE SELECT COUNT(*) FROM t;

测得的 i7-860 系统在 9.8 毫秒内运行计数查询,而 EXPLAIN ANALYZE 版本花费 16.6 毫秒,每个版本处理超过 100,000 行。 这 6.8 毫秒的差异意味着每行的计时开销为 68 纳秒,大约是 pg_test_timing 估计的两倍。 即使是相对较小的开销,也使得完全计时的计数语句花费的时间增加了近 70%。 在更实质性的查询中,计时开销的问题会少得多。

更改时间源

在一些较新的 Linux 系统上,可以随时更改用于收集计时数据的时钟源。 第二个示例显示了从切换到较慢的 acpi_pm 时间源可能造成的减速,该系统与上面快速结果所用的系统相同:

# cat /sys/devices/system/clocksource/clocksource0/available_clocksource
tsc hpet acpi_pm
# echo acpi_pm > /sys/devices/system/clocksource/clocksource0/current_clocksource
# pg_test_timing
Per loop time including overhead: 722.92 ns
Histogram of timing durations:
  < us   % of total      count
     1     27.84870    1155682
     2     72.05956    2990371
     4      0.07810       3241
     8      0.01357        563
    16      0.00007          3

在此配置中,上面的示例 EXPLAIN ANALYZE 花费 115.9 毫秒。 计时开销为 1061 纳秒,同样是该实用程序直接测量的开销的小倍数。 如此大的计时开销意味着实际查询本身仅占所用时间的一小部分,而大部分时间都消耗在开销中。 在此配置中,任何涉及许多计时操作的 EXPLAIN ANALYZE 总数都会因计时开销而显著膨胀。

FreeBSD 也允许动态更改时间源,并且会记录有关启动期间选择的计时器的信息:

# dmesg | grep "Timecounter"
Timecounter "ACPI-fast" frequency 3579545 Hz quality 900
Timecounter "i8254" frequency 1193182 Hz quality 0
Timecounters tick every 10.000 msec
Timecounter "TSC" frequency 2531787134 Hz quality 800
# sysctl kern.timecounter.hardware=TSC
kern.timecounter.hardware: ACPI-fast -> TSC

其他系统可能只允许在启动时设置时间源。 在较旧的 Linux 系统上,“clock”内核设置是进行此类更改的唯一方法。 即使在一些较新的系统上,您看到的时钟源的唯一选项也可能是“jiffies”。 Jiffies 是较旧的 Linux 软件时钟实现,当有足够快的计时硬件支持时,它可以具有良好的分辨率,如本例所示:

$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
jiffies
$ dmesg | grep time.c
time.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.
time.c: Detected 2400.153 MHz processor.
$ pg_test_timing
Testing timing overhead for 3 seconds.
Per timing duration including loop overhead: 97.75 ns
Histogram of timing durations:
  < us   % of total      count
     1     90.23734   27694571
     2      9.75277    2993204
     4      0.00981       3010
     8      0.00007         22
    16      0.00000          1
    32      0.00000          1

时钟硬件和计时精度

收集准确的计时信息通常是在计算机上使用具有不同精度级别的硬件时钟来完成的。 对于某些硬件,操作系统可以将系统时钟时间几乎直接传递给程序。 系统时钟也可以从一个芯片衍生而来,该芯片只提供计时中断,即在某个已知时间间隔的周期性滴答。 无论哪种情况,操作系统内核都提供了一个时钟源来隐藏这些细节。 但是该时钟源的精度及其返回结果的速度取决于底层硬件。

不准确的时间记录可能会导致系统不稳定。 请非常仔细地测试对时钟源的任何更改。 有时会进行操作系统默认设置,以优先考虑可靠性而不是最佳准确性。 如果您使用的是虚拟机,请研究与之兼容的推荐时间源。 虚拟硬件在模拟计时器时面临其他困难,并且通常有供应商建议的每个操作系统的设置。

时间戳计数器 (TSC) 时钟源是当前一代 CPU 上可用的最精确的时钟源。 当操作系统支持 TSC 时钟并且 TSC 时钟可靠时,它是跟踪系统时间的首选方式。 TSC 有几种可能无法提供准确计时源的方式,使其不可靠。 较旧的系统的 TSC 时钟可能会根据 CPU 温度而变化,使其无法用于计时。 尝试在某些较旧的多核 CPU 上使用 TSC 可能会导致多个内核之间报告的时间不一致。 这可能会导致时间倒退,这是该程序检查的一个问题。 即使是最新的系统也可能无法在非常激进的节能配置下提供准确的 TSC 计时。

较新的操作系统可能会检查已知的 TSC 问题,并在发现问题时切换到较慢、更稳定的时钟源。 如果您的系统支持 TSC 时间但不默认使用它,则可能是有充分理由禁用它。 并且某些操作系统可能无法正确检测所有可能的问题,或者即使在已知不准确的情况下也允许使用 TSC。

在高精度事件计时器 (HPET) 可用且 TSC 不准确的系统上,HPET 是首选计时器。 计时器芯片本身是可编程的,允许高达 100 纳秒的分辨率,但是您可能在系统时钟中看不到那么多精度。

高级配置和电源接口 (ACPI) 提供了一个电源管理 (PM) 计时器,Linux 将其称为 acpi_pm。 从 acpi_pm 导出的时钟最多只能提供 300 纳秒的分辨率。

在较旧的 PC 硬件上使用的计时器包括 8254 可编程间隔计时器 (PIT)、实时时钟 (RTC)、高级可编程中断控制器 (APIC) 计时器和 Cyclone 计时器。 这些计时器的目标是毫秒分辨率。

另请参阅

EXPLAIN

提交更正

如果您在文档中发现任何不正确的内容、与特定功能的体验不符或需要进一步澄清的内容,请使用此表单报告文档问题。