Pull to refresh

Большие потоки трафика и управление прерываниями в Windows

Reading time 3 min
Views 21K
Мне очень понравился топик про распределение нагрузки от прерываний сетевого адаптера по процессорам, поэтому я решил описать как это делается в Windows.

Disclaimer: судя по некоторым комментариям в предыдущих постах, мне стоит повторить то, с чего я начал первый пост: я не даю (и не могу давать) общеприменимых рецептов. Особенно это касается производительности, где мельчайшая неучтенная деталь может катастрофически повлиять на результат. Вернее рекомендацию то я даю: ТЕСТИРОВАНИЕ И АНАЛИЗ. Смысл моей писанины в том, чтобы дать людям как можно больше информации для анализа, ведь, чем больше понимаешь в том, как что либо работает, тем легче находить пути устранения боттлнеков.

Итак, масштабируемость пропускной способности сети. Потребуется Windows Server 2003 SP2+. Сетевая карта, поддерживающая Receive Side Scaling (можно с достаточной долей уверенности сказать, что подойдет любая серверная сетевая карта, выпущенная в последние 5 лет или любая вообще 1Gb+ NIC, хотя частенько можно увидеть RSS и на 100Mb). Устанавливаем Windows Server и драйвера на карту…


ВСЕ. Настройка завершена. RSS по умолчанию включен во всех версиях Windows, в которых он поддерживается.

Тестирование


Возьмем не особо новый Dell-овый сервер с двумя четырехядерными ксеонами:


На борту две двухпортовые 1Gb сетевые карты и одна 10Gb, но я не нашел 10Gb свитча, так что завести не удалось — ну да ладно:


Что интересно в этих картах, так это то, что несмотря на поддержку RSS в 8 очередей, они не поддерживают ни MSI-X ни даже MSI. Более того, из четырех доступных линий pin-based прерываний на каждый сетевой порт отведена только одна (соответственно никакими способами заставить прерывания приходить на разные процессоры уже нельзя — это аппаратное ограничение данной конфигурации). 10 гигабитка зарегистрировала на себя то ли 32 то ли 64 (на глаз) вектора прерываний, но ее использовать — не судьба. Сможет ли индусская поделка для запуска игр справиться с задачей?


На всякий случай проверяем RSS (хотя если его не будет — будет заметно и так):


Для начала выключим RSS (включал обратно я уже после тестирования, но том же окне)


и запустим нагрузочный тест:
Полностью загружены два ядра, все остальные простаивают


Сеть загружена на треть:


50% одного процессора забито обработакой прерываний, еще 20% того же процессора — обработка DPC. Остальное — tcpip стек и приложение, которое отдает трафик.


Включаем RSS (скриншот выше). Процессор:


Сеть:


Треть одного процессора забита прерываниями, но DPC отлично распараллелены.


В общем, на данной конфигурации можно было бы отдавать порядка 3 гигабит (с одной сетевой карты) и только тогда мы бы встретили бутылочное горлышко.

На всякий случай, скажу, что у RSS есть менее известный родственник — Send Side Scaling. Если перед посылкой списка буферов выставить значение хеша, то прерывание после завершения посылки будет доставлено в соответствии с установленными indirection table-ами.

Вот здесь можно почитать про RSS, а здесь есть неплохая презентация в картинках поясняющая работу RSS. Если интересно, могу попробовать своими словами описать механизмы работы RSS, но как по мне — лучше читать первоисточники.

TCP Offload Engine


Если нечто подобное RSS в Linux вот-вот появится (не нашел никаких упоминаний о поддержке нормального аппаратного RSS в Linux: кто знает — дайте ссылку — проапдейчу пост). То с TOE в Linux все официально сложно. Патч от Chelsio (один из производителей high-end сетевых карт), реализующий поддержку TOE, был отклонен, а вместо этого начались какие то совершенно идиотские отмазки (при прочтении стоит иметь в виду, что BSD и Windows имеют нормальную поддержку TOE уже много лет).

Итак, что же это такое? TOE — это полная реализация TCPIP на аппаратном уровне: с подтверждением доставки, ретрансмитами при ошибках, контролем окна и пр.: сетевая карта по DMA прямо из памяти берет данные, режет на пакеты, присоединяет хедеры, а рапортует (при помощи прерываний) только в самых крайних случаях.

По умолчанию TOE стоит в automatic режиме. Смотреть Chimney Offload State:


Скриншот снимался во время активного тестирования, но в статистике видно, что ни одного «выгруженного» в сетевую карту соединения нет (о причинах позже). Включем принудительно (и через некоторое время запрашиваем статистику):


А вот и причина: в данную сетевую карту можно выгрузить только 1024 соединения (но реально система смогла выгрузить 1022). Довольно дорогой ресурс, чтоб можно было выгружать все подряд. Система эвристически пытается обнаруживать соединения (get/put больших файлов по http, пересылка файлового контента на файл-серверах и т.п.), которые проживут долго и выгружает в первую очередь их.

Но все же глянем, что получилось. Процессор разгрузился втрое:


Очень сильно уменьшилось количество (и время проводимое в) как ISR так и DPC:
Tags:
Hubs:
+79
Comments 35
Comments Comments 35

Articles