Современный графический процессор способен исполнять тысячи потоков параллельно, но этот параллелизм имеет обратную сторону: когда на устройстве уже работает длительное вычислительное ядро, любая новая задача вынуждена ждать. Механизм вытеснения вычислений, Compute Preemption, позволяет прервать исполняющееся ядро, сохранить его состояние и передать устройство более срочной работе. Для графических конвейеров это вопрос отзывчивости интерфейса, для смешанных вычислений вопрос дедлайнов, для многопользовательских систем вопрос честного разделения. Однако вытеснение не бесплатно, и его неправильное использование способно замедлить систему сильнее, чем отсутствие всякого вытеснения. Разберём, как эта механика устроена и как выжать из неё пользу.
Уровни вытеснения и их стоимость
Железо поддерживает несколько гранулярностей прерывания вычислений. Самый грубый уровень это вытеснение по границе ядра: новая задача ждёт завершения текущей решётки исполнения. Такая модель проста и дешёва, но длительное ядро блокирует устройство на миллисекунды и дольше, что недопустимо для интерактивных задач.
Средний уровень это вытеснение на границе блока потоков. Устройство дожидается завершения текущих блоков, не запускает новые и переключает контекст. Состояние видеопамяти при этом не требует сохранения, потому что незавершённых блоков внутри нет, и цена переключения заметно ниже полного снимка состояния.
Самый тонкий уровень вытесняет исполнение на уровне инструкций или групп потоков. Оборудование сохраняет регистры, счётчики адресов и внутреннее состояние исполняющихся групп, чтобы возобновить их позже с той же точки. Гибкость максимальна, но сохранение сотен килобайт контекста каждой группы стоит пропускной способности памяти, и цена вытеснения на этом уровне может достигать десятков и сотен микросекунд.
Из этой градации следует простой управленческий вывод. Тонкое вытеснение включают там, где дедлайны жёсткие и длительные ядра неизбежны, а для пакетных вычислений чаще выгоднее грубое переключение по границам ядер, которое почти ничего не стоит.
Где вытеснение реально спасает отзывчивость
Классический сценарий это рабочая станция, где один процесс занимается длительным рендером или обучением модели, а система должна отрисовывать интерфейс каждые шестнадцать миллисекунд. Без вытеснения интерфейс дёргается, потому что композитор монотонно ждёт освобождения устройства. С включённым вытеснением на уровне блоков короткие графические задачи протискиваются между вычислительными, уборка кадров удерживается в пределах нормы, и пользователь не подозревает о фоновой работе.
Многопользовательские серверы получают от вытеснения другое: гарантию качества обслуживания. Лимитированная очередь не позволяет арендатору с недельным расчётом задавить соседа с интерактивным запросом, потому что планировщик устройства умеет прерывать тяжёлые задания. Тонкость в том, что частые вытеснения накапливают оверхед, и оператор должен выбрать баланс между справедливостью и суммарной производительностью.
Встроенные системы и робототехника рассматривают вытеснение как средство обеспечения дедлайнов. Задача обработки датчиков обязана исполняться каждые несколько миллисекунд, а фоновое планирование маршрута готово ждать. Тонко настроенное вытеснение здесь заменяет полноценное планирование заданий устройства более сложных систем.
Изменение задержек при смешанной нагрузке на практике
Эмпирическая оценка эффекта строится на двух измерительных потоках. Тяжёлое вычислительное ядро с миллионами машинных операций запускается в фоне, поверх него периодически подаётся короткое критичное ядро, и замеряется время от подачи до завершения последнего. Без вытеснения это время стабилизируется около длительности тяжёлого ядра, потому что короткое реально ждёт в очереди. С вытеснением по блокам оно падает до суммы остатка текущего блока и стоимости переключения.
Числа зависят от архитектуры и размера блоков, поэтому производственное измерение обязано повторяться на целевом железе. Типичный результат на современных устройствах: вытеснение по границе блоков удерживает отклик в пределах долей миллисекунды, инструкционное вытеснение доводит его до сотен микросекунд ценой заметного замедления фоновой работы.
Особый случай это конкуренция вычислений и копий памяти. Операции копирования между хостом и устройством обслуживаются отдельными модулями, и их взаимодействие с вытеснением вычислительных блоков специфично для платформы. На некоторых архитектурах запущенная копия мешает вытеснению соседнего ядра, и картину задержек под реальной смесью следует собирать экспериментально.
Настройка вытеснения через средства конфигурации
Управление поведением вытеснения обычно доступно на уровне драйвера, контекста или очередей команд. Приложения группируют свои задания по классам критичности, и высокоприоритетные очереди получают право прерывать низкоприоритетные. Примерная последовательность конфигурации выглядит так:
- Определить классы задач по требованиям к задержке и назначить им очереди разных приоритетов;
- Включить вытеснение на уровне блоков для смешанных нагрузок и оценить цену переключения на целевом железе;
- Зарезервировать инструкционное вытеснение только для случаев, когда короткие дедлайны действительно несовместимы с длиной блока;
- Настроить мониторинг количества вытеснений, чтобы исключить паттерн, где система проводит половину времени в переключениях.
Драйверные настройки влияют тонко. На платформах с переключаемыми режимами планирования устройств административный выбор между режимом, ориентированным на графику, и режимом общих вычислений меняет поведение вытеснения по умолчанию. Документация на конкретную версию драйвера здесь важнее общих рекомендаций.
Форму параметров блоков тоже подгоняют под механику преемпции. Маленькие блоки завершаются быстрее и позволяют планировщику прерывать работу чаще с меньшими затратами, но снижают утилизацию широкого устройства. Выбор размера блока становится компромиссом между отзывчивостью и скоростью фоновой работы.
Влияние на совокупную пропускную способность
Частые вытеснения несут явный налог на общую производительность, и игнорировать его нельзя. Каждое переключение это сброс внутренних конвейеров, отказ от накопленной локальности кэша, иногда сохранение состояния в отдельные области памяти. При агрессивной настройке приоритетных очередей устройство способно тратить на вытеснения больше времени, чем на полезную работу.
Измерение этого налога прямолинейно: фоновая работа фиксированного объёма прогоняется в одиночестве и под периодическими вытеснениями, разница времён и есть стоимость сервиса. Порог здравого смысла обычно считают в единицах процентов, всё сверх этого требует пересмотра политики приоритетов.
Подавлять налог помогают два приёма. Первый это реже вытеснять и чаще дожидаться коротких естественных границ, чему способствуют мелкие ядра с короткими блоками. Второй это укрупнение критических заданий так, чтобы одно вытеснение закрывало целый пакет срочной работы, а не каждое срабатывание датчика.
Архитектурные приёмы под вытеснение
Приложение, проектируемое с учётом преемпции, дробит вычисления на ядра с управляемой длительностью. Запускать одну решётку на десятки миллисекунд в системе, где требуются быстрые отклики, это само по себе жёсткое ограничение, которое не снимает никакое железо. Короткие ядра предоставляют планировщику естественные точки переключения, и цена вытеснения почти исчезает.
Состояние, необходимое для возобновления, лучше держать компактным. Алгоритмы, организованные как итерации, обновляющие небольшой объём аккумуляторов, легче переносят прерывание и удобно восстанавливаются при переезде между устройствами. Раздутое состояние делает и вытеснение, и миграцию дорогими, а также усложняет отладку численной стабильности.
Наконец, заявка на вытеснение это только обещание, а не мгновенная гарантия. Строгие дедлайны на графических процессорах обеспечиваются не вытеснением одним, а комбинацией выделенных устройств, резервирования пропускной способности памяти и дисциплинированного дробления работы. Вытеснение здесь это последний рубеж, которому не следует доверять всё.
Типичные проблемы отладки и контроль в эксплуатации
Первая жалоба после включения вытеснения обычно звучит одинаково: производительность упала без видимой причины. Причиной почти всегда служит зоопарк приоритетов, где десятки потоков конкурируют за высокий приоритет и вытесняют друг друга по кругу. Диагностика ведётся через счётчики переключений и через трассировку событий планировщика, если драйвер её предоставляет. Лечение состоит в ужесточении прав: право прерывать получает один-два класса задач, а остальные дисциплинированно ждут своей очереди.
Вторая проблема тоньше: периодические всплески задержки при внешне пустой системе. Виновником оказывается фоновая активность самого графического стека, композиция окон, аппаратное декодирование видео, служебные копии памяти. Каждая из этих работ способна вытеснять вычисления пользователя. Отладка требует полной инвентаризации того, что вообще исполняется на устройстве, включая неочевидные системные очереди.
Третья трудность касается воспроизводимости. Вытеснение меняет расписание исполнения, и бенчмарки, измерявшиеся на эксклюзивном устройстве, при включённой преемпции показывают другие цифры. Аналитический отчёт без указания режима вытеснения это документ, который лучше не писать: выводы на его основании повторить невозможно. Каждая публикация результатов обязана фиксировать конфигурацию приоритетов, версию драйвера и состояние механизмов прерывания.
Отдельного упоминания заслуживают ошибки взаимоблокировки. Критическая задача, которая после вытеснения фоновой ждёт от неё данных, создаёт циклическое ожидание, и устройство молча простаивает. Структурная защита проста: зависимости между задачами разных приоритетов проектируют так, чтобы высокоприоритетная работа никогда не ожидала результата от низкоприоритетной.
Продуктовая эксплуатация требует видимости поведения планировщика устройства. Полезные метрики включают число вытеснений за интервал, суммарную длительность переключений и распределение задержки отклика критических задач в девяностые девятые процентили. Изменение этих метрик после обновления драйвера или изменения состава нагрузки немедленно сигнализирует о сломанных предположениях.
Регрессионный стенд для смешанных нагрузок автоматизирует пару тяжёлое плюс лёгкое ядро и фиксирует отклик по кругу релизов. Уклонение от канала в пятнадцать процентов требует объяснения прежде, чем изменение уедет в прод.
Вывод прост. Compute Preemption это мощный рычаг обеспечения отзывчивости и изоляции, но как всякий рычаг он требует расчёта усилия. Измеренная цена переключения, осмысленная гранулярность ядер и внимательный мониторинг превращают механизм из источника неожиданностей в предсказуемый инструмент, и именно в этом состоянии он приносит пользу, задуманную архитекторами.
Наконец, стоит держать под рукой конфигурационный рычаг отключения. Возможность одним параметром вернуть эксклюзивный режим исполнения превращает отладку ночных инцидентов из рулетки в контролируемый эксперимент, где подозреваемый механизм вычитают из уравнения за одну перезагрузку сервиса, а выводы подтверждаются измерениями, а не ощущениями.
Опытные команды дополнительно ведут журнал решений: какие приоритеты кому назначены, почему выбран такой уровень гранулярности и какие цифры эти решения подтверждали. Когда состав нагрузки меняется, а он меняется неизбежно, такой журнал позволяет пересматривать конфигурацию осознанно, опираясь на прошлые замеры, а не восстанавливая логику выбора по памяти участников.