Что такое переключение контекста и почему оно дорогое?
- Почему тысяча потоков работает медленнее, чем восемь?
- Сколько стоит переключение между потоками?
Ядро останавливает один поток, сохраняет его регистры и состояние и загружает другой. Прямая цена — единицы микросекунд, но главное — остывшие кэши процессора.
- Между процессами дороже: меняется адресное пространство, сбрасывается TLB
- Причины: истёк квант времени, поток ушёл ждать ввода-вывода или блокировки
- Потоков больше, чем ядер, — больше переключений и меньше полезной работы
А ещё Отсюда пулы потоков, event loop и виртуальные потоки
Подробно
На ядре процессора в каждый момент выполняется один поток. Чтобы выполнялись многие, ядро ОС переключает их: сохраняет регистры, счётчик команд и указатель стека текущего потока в его структуре, выбирает следующий по правилам планировщика и восстанавливает его состояние.
Когда переключаются:
- вытеснение — поток израсходовал квант времени (единицы миллисекунд), или проснулся поток с более высоким приоритетом;
- добровольно — поток ушёл ждать: чтение с диска или из сети, захват занятого мьютекса,
sleep, ожидание условия.
Из чего цена:
- прямая — вход в ядро, сохранение и восстановление регистров, работа планировщика. Порядок единиц микросекунд;
- косвенная — новый поток работает с другими данными, кэши L1/L2 и предсказатель переходов заполнены чужим. Первое время он работает медленно, пока кэши не прогреются. Это часто дороже прямой части;
- между процессами — ещё и смена таблиц страниц, сброс TLB (кэша трансляции адресов).
Практические следствия:
- для вычислений потоков больше, чем ядер, не нужно — они только мешают друг другу;
- для ввода-вывода раньше заводили поток на соединение, и при десятках тысяч соединений система тратила время на переключения и память на стеки. Отсюда неблокирующий ввод-вывод и event loop (nginx, Node.js, asyncio), а в Java 21 — виртуальные потоки: переключение между ними делает JVM в пользовательском пространстве, без ядра;
- захват спорной блокировки — это тоже переключение: поток засыпает и просыпается. Поэтому короткие критические секции и спин-блокировки на короткое ожидание.
Посмотреть число переключений: vmstat 1 (колонка cs), pidstat -w.
Пример
vmstat 1
procs ---------memory-------- ---system-- ------cpu-----
r b swpd free ... in cs us sy id wa
32 0 0 812344 ... 9100 185000 41 38 21 0
Сотни тысяч переключений в секунду и высокий sy (время в ядре) — признак того, что потоков слишком много или они дерутся за блокировку.
Что хотят услышать
- Что сохраняется и восстанавливается.
- Две причины: вытеснение и ожидание.
- Косвенная цена через кэши, а не только прямая.
- Вывод: число потоков под задачу, пулы, event loop, виртуальные потоки.
Частые ошибки
- «Больше потоков — быстрее» для вычислительной задачи.
- Считать, что переключение между потоками и процессами стоит одинаково.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✓Главная цена переключения — остывшие кэши процессора; между процессами дороже из-за смены адресного пространства
- ✗Переключение контекста бесплатно на современных процессорах
- ✗Чем больше потоков сверх ядер, тем выше производительность
- ✗Переключение между потоками дороже, чем между процессами: потоки делят память, и ядру приходится копировать всю кучу при каждом переключении
Что спросят дальше
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.