Стоимость переключения контекста между потоками одного и того же процесса в Linux - PullRequest
18 голосов
/ 11 мая 2011

Есть ли хорошие эмпирические данные о стоимости переключения контекста между потоками одного и того же процесса в Linux (в основном интерес представляют x86 и x86_64)?Я говорю о количестве циклов или наносекунд между последней инструкцией, которую один поток выполняет в пользовательском пространстве перед тем, как добровольно или невольно переводиться в спящий режим, и первой инструкцией, выполняемой другим потоком того же процесса после пробуждения на том же процессоре / ядре..

Я написал программу быстрого тестирования, которая постоянно выполняет rdtsc в 2 потоках, назначенных одному и тому же процессору / ядру, сохраняет результат в переменной volatile и сравнивает с соответствующей переменной volatile его дочернего потока.В первый раз, когда он обнаруживает изменение значения сестринского потока, он печатает разницу, а затем возвращается к циклу.Таким образом, на процессоре Atom D510 я получаю минимальное / среднее число циклов около 8900/9600 циклов.Кажется ли эта процедура разумной, и цифры кажутся правдоподобными?

Моя цель состоит в том, чтобы оценить, может ли в современных системах модель сервера с потоком на соединение быть конкурентоспособной или даже превосходить мультиплексирование по типу выбора.Это кажется правдоподобным в теории, поскольку переход от выполнения ввода-вывода на fd X к fd Y предполагает просто переход в спящий режим в одном потоке и пробуждение в другом, а не несколько системных вызовов, но это зависит от издержек переключения контекста.

1 Ответ

16 голосов
/ 11 мая 2011

(Отказ от ответственности: это не прямой ответ на вопрос, это всего лишь некоторые предложения, которые, я надеюсь, будут полезны).

Во-первых, числа, которые вы получаете, безусловно, звучат так, как будто они находятся на стадионе. Обратите внимание, однако, что задержка прерывания / прерывания может варьироваться лот среди разных моделей ЦП, реализующих один и тот же ISA. Это также другая история, если ваши потоки использовали операции с плавающей запятой или векторные, потому что если они не имеют, ядро ​​избегает сохранения / восстановления состояния с плавающей запятой или векторного модуля.

Вы должны быть в состоянии получить более точные числа, используя инфраструктуру трассировки ядра - perf sched, в частности, предназначено для измерения и анализа задержки планировщика.

Если ваша цель состоит в том, чтобы смоделировать серверы потоков на соединение, то вам, вероятно, не следует измерять задержку принудительного переключения контекста - обычно на таком сервере большинство переключений контекста будут произвольными, поскольку поток блокируется в read() в ожидании дополнительных данных из сети. Следовательно, лучший тестовый стенд может включать измерение задержки от блокировки одного потока в read() до другого, пробуждаемого из того же самого.

Обратите внимание, что на хорошо написанном сервере мультиплексирования под большой нагрузкой переход от fd X к fd Y часто будет включать в себя один и тот же системный вызов (так как сервер перебирает список дескрипторов активных файлов, возвращаемых из один epoll()). Один поток также должен иметь меньшую площадь кеша, чем несколько потоков, просто благодаря наличию только одного стека. Я подозреваю, что единственный способ урегулирования вопроса (для некоторого определения "урегулирования") мог бы состоять в контрольной перестрелке ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...