В этой заметке речь пойдёт об известной настройке планировщика - Win32PrioritySeparation, позволяющей настраивать количество квантов времени, выделяемых фоновым (background) и активным (foreground) процессам.
Этот параметр - поле в реестре с типом REG_DWORD:
HKLM\System\CurrentControlSet\Control\PriorityControl\Win32PrioritySeparation
Во многих источниках есть описания возможных значений без объяснения внутреннего устройства этого параметра - эти пробелы и призвана закрыть эта статья.
Итак, это поле представляет собой группу из трёх двухбитных значений - всего 6 бит.
Допустимый диапазон - 0x00000000..0x0000003F
Обозначим каждую двухбитную группу буквами: AA (старшие 2 бита), BB (2 бита в середине) и CC (младшие 2 бита) - AABBCC.
Группа AA (Shorter/Longer) определяет длительность интервалов, отводимых потоку до переключения контекста:
00 или 11: короткие интервалы на клиентских редакциях Windows и длинные интервалы на Windows Server
01: Longer - длинные интервалы
10: Shorter - короткие интервалы
Группа BB (Variable/Fixed) определяет, будет ли активным процессам (foreground) выделяться больше времени, чем фоновым (background):
00 или 11: на клиентских редакциях Windows активным процессам отводится больше времени, на серверных - одинаково
01: Variable - активным процессам отводится больше времени
10: Fixed - равное количество квантов и для фоновых, и для активных процессов
Группа CC (Ratio) определяет соотношение между количеством квантов для активных процессов и количеством квантов для фоновых процессов (1:1, 2:1 или 3:1), имеет значение только при BB = 01b (Variable):
00: равное количество квантов для фоновых и активных процессов (1:1)
01: соотношение 2:1 (активным процессам отводится в 2 раза больше квантов, чем фоновым)
10 или 11: соотношение 3:1
По-умолчанию значение Win32PrioritySeparation численно равно 2 (константа PsRawPrioritySeparation, задающая дефолтное значение на ранних этапах запуска системы в ntoskrnl.exe!PspInitPhase0), что соответствует коротким интервалам и соотношению количества квантов у активных процессов к фоновым 3:1 (активные процессы получают в 3 раза больше процессорного времени, чем процессы в фоне).
А теперь рассмотрим, что значат эти значения в абсолютных цифрах.
Рассмотрим функции PsChangeQuantumTable и PspComputeQuantum в ntoskrnl.exe (за основу взято ядро Win10 x64 1909, но эти же функции можно посмотреть и в WRK):
Как видим, на основе параметра BB (Variable/Fixed) выбирается или массив PspVariableQuantums, или массив PspFixedQuantums со значениями количества квантов для разных вариантов AA и BB.
Значения этих таблиц неизменны и на Win2k, и на новейших Win 10:
Каждое значение получено путём умножения фиксированного значения THREAD_QUANTUM на множитель (см. ke.h и psinit.c в WRK):
PspFixedQuantums PspVariableQuantums 18 6 18 12 18 18 36 12 36 24 36 36Итак, мы выбрали массив количества квантов.Код (C):
// ke.h: #define CLOCK_QUANTUM_DECREMENT 3 #define READY_SKIP_QUANTUM 2 #define THREAD_QUANTUM (READY_SKIP_QUANTUM * CLOCK_QUANTUM_DECREMENT) // psinit.c: const SCHAR PspFixedQuantums[6] = { 3*THREAD_QUANTUM, 3*THREAD_QUANTUM, 3*THREAD_QUANTUM, 6*THREAD_QUANTUM, 6*THREAD_QUANTUM, 6*THREAD_QUANTUM }; const SCHAR PspVariableQuantums[6] = { 1*THREAD_QUANTUM, 2*THREAD_QUANTUM, 3*THREAD_QUANTUM, 2*THREAD_QUANTUM, 4*THREAD_QUANTUM, 6*THREAD_QUANTUM };
Каждый массив условно можно разделить на две группы (для коротких и длинных квантов) по три элемента: элементы 0..2 отвечают за короткие кванты, элементы 3..5 - за длинные.
Параметр AA определяет группу, с которой мы работаем. Если выбраны "длинные" кванты (CC = 01b), адрес массива количества квантов сдвигается на 3 элемента - таким образом, мы будем работать с блоком для длинных квантов. Этот адрес записывается в PspForegroundQuantum, а параметр CC (Ratio) сохраняется в глобальную переменную PsPrioritySeparation (этой переменной нет в символах ntoskrnl.exe, поэтому вы увидите вместо неё KeNumberProcessorsGroup0[6], хотя KeNumberProcessorsGroup0 - не массив, а переменная, не имеющая никакого отношения к нашей теме).
Заключительный этап - расчёт количества квантов для процесса в функции PspComputeQuantum.
В WRK реализация этой функции немного отличается от реализации в Windows 10, но, в общих чертах, всё одинаково (см. PspComputeQuantumAndPriority в psquery.c):
Т.к. CC (Ratio) - индекс в массиве из трёх элементов, становится объяснимым ограничение на его диапазон значений от [0..2] в PsChangeQuantumTable.
Теперь, зная внутреннее устройство параметра Win32PrioritySeparation, мы можем составить полную и исчерпывающую таблицу всех возможных соотношений количества квантов для всех вариаций параметров AA (Longer/Shorter), BB (Variable/Fixed) и CC (Ratio):
На клиентских редакциях Windows значения AA = 0 и BB = 0 интерпретируются, как AA = 10b (shorter) и BB = 01b (variable); на Windows Server - AA = 01b (longer), BB = 10b (fixed).
AA (Longer/ Shorter) BB (Variable/ Fixed) CC (Ratio) Win32PrioritySeparation (dec or hex) Foreground/ Background quantums count01 (longer) 01 (variable) 00 (1:1) 20 or 0x14 12:12 01 (longer) 01 (variable) 01 (2:1) 21 or 0x15 24:12 01 (longer) 01 (variable) 10 or 11 (3:1) 22 or 0x16 (23 or 0x17) 36:12 10 (shorter) 01 (variable) 00 (1:1) 36 or 0x24 6:6 10 (shorter) 01 (variable) 01 (2:1) 37 or 0x25 12:6 10 (shorter) 01 (variable) 10 or 11 (3:1) 38 or 0x26 (39 or 0x27) 18:6 01 (longer) 10 (fixed) 00 (1:1), 01 (2:1) or 10/11 (3:1) [24..27] or [0x18..0x1B] 36:36 10 (shorter) 10 (fixed) 00 (1:1), 01 (2:1) or 10/11 (3:1) [40..47] or [0x28..0x2B] 18:18
Исходя из этих значений, дефолтное значение Win32PrioritySeparation, равное 2, сводится к следующим соотношениям количества квантов:
- 18:6 на клиентских Windows
- 36:36 на Windows Server
Как итог:
Если вы хотите оптимизировать планировщик для достижения, например, лучшей производительности в играх, стоит брать соотношения с бОльшим количеством квантов для активных процессов. Для серверов же, где параллельно работает множество фоновых сервисов, стоит использовать фиксированные длинные интервалы, дабы поток успел обработать запрос до переключения контекста.
Квантовая сепарация или разбираемся с Win32PrioritySeparation
Дата публикации 9 мар 2020
| Редактировалось 1 апр 2020