Квантовая сепарация или разбираемся с Win32PrioritySeparation

Дата публикации 9 мар 2020 | Редактировалось 1 апр 2020
В этой заметке речь пойдёт об известной настройке планировщика - 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):
upload_2020-3-9_0-57-6.png

Как видим, на основе параметра BB (Variable/Fixed) выбирается или массив PspVariableQuantums, или массив PspFixedQuantums со значениями количества квантов для разных вариантов AA и BB.

Значения этих таблиц неизменны и на Win2k, и на новейших Win 10:
PspFixedQuantumsPspVariableQuantums
18​
6​
18​
12​
18​
18​
36​
12​
36​
24​
36​
36​
Каждое значение получено путём умножения фиксированного значения THREAD_QUANTUM на множитель (см. ke.h и psinit.c в WRK):
Код (C):
  1. // ke.h:
  2. #define CLOCK_QUANTUM_DECREMENT 3
  3. #define READY_SKIP_QUANTUM 2
  4. #define THREAD_QUANTUM (READY_SKIP_QUANTUM * CLOCK_QUANTUM_DECREMENT)
  5.  
  6. // psinit.c:
  7. const SCHAR PspFixedQuantums[6] = {
  8.     3*THREAD_QUANTUM,
  9.     3*THREAD_QUANTUM,
  10.     3*THREAD_QUANTUM,
  11.     6*THREAD_QUANTUM,
  12.     6*THREAD_QUANTUM,
  13.     6*THREAD_QUANTUM
  14. };
  15.  
  16. const SCHAR PspVariableQuantums[6] = {
  17.     1*THREAD_QUANTUM,
  18.     2*THREAD_QUANTUM,
  19.     3*THREAD_QUANTUM,
  20.     2*THREAD_QUANTUM,
  21.     4*THREAD_QUANTUM,
  22.     6*THREAD_QUANTUM
  23. };
Итак, мы выбрали массив количества квантов.
Каждый массив условно можно разделить на две группы (для коротких и длинных квантов) по три элемента: элементы 0..2 отвечают за короткие кванты, элементы 3..5 - за длинные.
Параметр AA определяет группу, с которой мы работаем. Если выбраны "длинные" кванты (CC = 01b), адрес массива количества квантов сдвигается на 3 элемента - таким образом, мы будем работать с блоком для длинных квантов. Этот адрес записывается в PspForegroundQuantum, а параметр CC (Ratio) сохраняется в глобальную переменную PsPrioritySeparation (этой переменной нет в символах ntoskrnl.exe, поэтому вы увидите вместо неё KeNumberProcessorsGroup0[6], хотя KeNumberProcessorsGroup0 - не массив, а переменная, не имеющая никакого отношения к нашей теме).

Заключительный этап - расчёт количества квантов для процесса в функции PspComputeQuantum.
В WRK реализация этой функции немного отличается от реализации в Windows 10, но, в общих чертах, всё одинаково (см. PspComputeQuantumAndPriority в psquery.c):
upload_2020-3-9_1-48-30.png

Т.к. CC (Ratio) - индекс в массиве из трёх элементов, становится объяснимым ограничение на его диапазон значений от [0..2] в PsChangeQuantumTable.

Теперь, зная внутреннее устройство параметра Win32PrioritySeparation, мы можем составить полную и исчерпывающую таблицу всех возможных соотношений количества квантов для всех вариаций параметров AA (Longer/Shorter), BB (Variable/Fixed) и CC (Ratio):
AA (Longer/ Shorter)​
BB (Variable/ Fixed)​
CC (Ratio)​
Win32PrioritySeparation (dec or hex)​
Foreground/ Background quantums count​
01 (longer)01 (variable)00 (1:1)20 or 0x1412:12
01 (longer)01 (variable)01 (2:1)21 or 0x1524: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 0x246:6
10 (shorter)01 (variable)01 (2:1)37 or 0x2512: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
На клиентских редакциях Windows значения AA = 0 и BB = 0 интерпретируются, как AA = 10b (shorter) и BB = 01b (variable); на Windows Server - AA = 01b (longer), BB = 10b (fixed).

Исходя из этих значений, дефолтное значение Win32PrioritySeparation, равное 2, сводится к следующим соотношениям количества квантов:
- 18:6 на клиентских Windows
- 36:36 на Windows Server

Как итог:
Если вы хотите оптимизировать планировщик для достижения, например, лучшей производительности в играх, стоит брать соотношения с бОльшим количеством квантов для активных процессов. Для серверов же, где параллельно работает множество фоновых сервисов, стоит использовать фиксированные длинные интервалы, дабы поток успел обработать запрос до переключения контекста.

2 13.170
HoShiMin

HoShiMin
Well-Known Member

Регистрация:
17 дек 2016
Публикаций:
5

Комментарии


      1. Bedolaga 24 мар 2020
        Почему публикация до сих пор у меня в непрочитанных висит?
        ormoulu нравится это.
      2. HoShiMin 9 мар 2020
        Indy_, сравнил в Cinebench - разница между режимами меньше процента, и та плавает в обе стороны.
        Каждый тест выполнял два раза, сравнивал результаты вторых прогонов.
        i9-9900k, 8/16, тест в 16 потоков.

        Результаты в баллах:
        Shorter & Variable:
        6:6 - 4864
        12:6 - 4852
        18:6 - 4837 (дефолтный, то же самое, что Win32PrioritySeparation == 2)

        Longer & Variable:
        12:12 - 4839
        24:12 - 4835
        36:12 - 4857

        Shorter & Fixed:
        18:18 - 4869

        Longer & Fixed:
        36:36 - 4847

        Не слишком показательные результаты. Нужно тестить на каких-то реальных длительных задачах.
        Indy_ нравится это.
      3. Indy_ 9 мар 2020
        Начать нужно было с тестов. А без них эта инфа бесполезна. Где результат снятия профайла ?