qhb_test_timing
qhb_test_timing — оценить издержки измерения времени
Синтаксис
pg_test_timing [параметр...]
Описание
qhb_test_timing — это утилита для оценки издержек измерения времени в вашей
системе и подтверждения того, что системное время никогда не идет назад. Системы,
в которых сбор данных по времени проходит медленно, могут дать менее точные
результаты EXPLAIN ANALYZE
.
Параметры
Утилита qhb_test_timing принимает следующие параметры командной строки:
-d продолжительность
--duration=продолжительность
Задает продолжительность проверки, в секундах. Увеличение продолжительности дает
чуть более высокую точность и повышенную вероятность обнаружить проблемы с обратным
ходом системных часов. Продолжительность проверки по умолчанию — 3 секунды.
-V
--version
Вывести версию qhb_test_timing и завершиться.
-?
--help
Показать справку об аргументах командной строки qhb_test_timing и
завершиться.
Использование
Интерпретация результатов
В случае хороших результатов будет показано, что почти все (>90%) отдельные вызовы замеров времени занимают меньше одной микросекунды. Средние издержки замера на цикл будут еще ниже, менее 100 наносекунд. Этот пример из системы Intel i7-860 с источником времени TSC показывает отличную производительность:
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), тогда как продолжительность отдельных вызовов замера времени — только с точностью до одной микросекунды (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 нс, примерно вдвое больше, чем предположила qhb_test_timing.
Даже с такой относительно небольшой издержкой оператор COUNT
с полным замером
времени выполняется почти на 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
Другие системы могут допускать настройку источника времени только при загрузке. В более старых системах единственным способом выполнить такое изменение является настройка параметра ядра «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 (Time Stamp Counter, Счетчик отметок времени) является наиболее точным из всех доступных для процессоров текущего поколения. Его предпочтительнее использовать для отслеживания системного времени, когда он поддерживается операционной системой и показания часов TSC надежны. Есть несколько ситуаций, в которых TSC не сможет предоставить точный источник замера времени и окажется ненадежным. В старых системах могут быть часы TSC, зависящие от температуры процессора, что делает их непригодными для замера времени. При попытке использовать TSC в некоторых старых многоядерных процессорах можно получить на разных ядрах несогласованное время. Это может привести к обратному ходу времени — проблеме, которую выявляет эта программа. И даже в самых современных системах можно получить неточные замеры времени через TSC в режимах очень агрессивного энергосбережения.
Современные операционные системы могут проверять наличие известных проблем TSC и переключаться на более медленный и стабильный источник времени, когда те выявляются. Если ваша система поддерживает источник TSC, но не выбирает его по умолчанию, возможно, он отключен по веской причине. А некоторые операционные системы могут не обнаруживать все возможные проблемы или позволяют использовать TSC даже в ситуациях, когда он заведомо неточен.
HPET (High Precision Event Timer, Таймер событий высокой точности) предпочтительней использовать в системах, где он доступен, а TSC неточен. Сам чип этого таймера можно запрограммировать для разрешения точности до 100 наносекунд, но, возможно, системное время с такой точностью вы не увидите.
ACPI (Advanced Configuration and Power Interface, Расширенный интерфейс конфигурации и питания) предоставляет таймер PM (Power Management, Управление питанием), который в Linux называется acpi_pm. Время, поступающее из acpi_pm, в лучшем случае будет обеспечивать разрешение в 300 наносекунд.
На старом компьютерном оборудовании использовались таймеры 8254 PIT (Programmable Interval Timer, Программируемый интервальный таймер), RTC (real-time clock, часы реального времени), таймер APIC (Advanced Programmable Interrupt Controller, Расширенный программируемый контроллер прерываний) и таймер Cyclone. Эти таймеры обеспечивают разрешение до миллисекунд.