Receive buffers что это
Как настроить сетевой адаптер на Windows 7: самое важное
Иногда при подключении интернета или использовании ресурсов локальной сети возникают проблемы. Могут вылезать ошибки подключения, получения IP адресов или конфигурации сетевого оборудования. Внутри компьютера или ноутбука, функцией подключения к локальной или глобальной сети, занимается сетевой адаптер. В статье мы как раз и поговорим про настройку сетевого адаптера для улучшения связи в интернете. Инструкция будет ходовая для всех версий Windows 7, 8 и 10.
Более подробная настройка
Мне постоянно приходят письма с вопросами – как более детально настроить сетевой адаптер для меньшего пинга в играх, для лучшего просмотра кино и большей скорости скачивания. Поэтому я решил написать более детальную статью. Ну, поехали! По идее она настраивается автоматически под рациональное использование ресурсов системы и самого устройства. Но конфигурацию можно корректировать под свои нужды.
Переходим во вкладку «Дополнительно». И так смотрите, у нас есть определённые свойства, которые мы можем включать (Enebled) или выключать (Disable). На новых версиях «Виндовс» может быть написано «Вкл» или «Выкл». А теперь разбёрем каждое свойство:
ВНИМАНИЕ! Параметры адаптера могут в какой-то степени улучшить показатели, в каком-то моменте ухудшить. Изменяя установки сетевого адаптера, лучше возьмите листочек и выпишите – что именно вы изменили, чтобы в случаи чего вернуть параметры обратно. Также я рекомендую скачать последнюю версию драйвера для вашей сетевой карты или Wi-Fi модуля и установить его. Только после этого заходим в характеристики
После изменения, следует перезагрузить компьютер или ноутбук, чтобы некоторые изменения вступили в силу. Установки сетевого адаптера всегда можно откатить обратно, самое главное не потеряйте тот листок с настройками.
ПРОСЬБА! Если я что-то не указал, или написал что-то не так – пишите смело в комментариях свои исправления или замечания, буду рад поучиться чему-то у своих читателей.
Память сети: как сохранить пакет
Настоятельно рекомендую ознакомиться с 15-м выпуском СДСМ перед тем, как приступить к чтению.
Содержание
Терминология
Назначение буферов
Будучи неоднократно обвинённым при рецензировании этой статьи, чувствую необходимость ещё раз повторить это: внутри чипа коммутации заголовки отделяются от тела пакета. В то время, как изначальные заголовки анализируются, помогают сделать лукап, уничтожаются, формируются новые, тело находится в одном месте физической памяти, не перемещаясь. Даже в тот момент, когда Traffic Manager выстраивает пакеты в очередь согласно их приоритетам, производит их диспетчеризацию и Congestion Avoidance, фактически он работает со внутренними временными заголовками, не двигая пакеты по памяти.
MMU занимается размещением пакетов в буферах, их извлечением или отбрасыванием. Он же контролирует разделение памяти на области (dedicated, shared, headroom, voq) и их загрузку.
Есть два подхода к размещению тел в буферах: Store-and-Forward и Cut-Through.
Store-and-Forward vs Cut-Through
Многие производители сегодня по умолчанию устанавливают режим Cut-Through, поскольку ошибки на Ethernet сегодня явление сравнительно нечастое, а приложение обычно само может обнаружить проблему и запросить переотправку (или не запрашивать, кстати).
Перегрузки: причины и места
Причины перегрузок
Поэтому однозначно нужно побольше памяти для буферизации. Но фактически это место, где пакеты обрастают задержкой. Так на заре 1G буферизация вызывала массу головной боли у трейдеров, чьи приложения получали свой бесценный трафик с задержкой и джиттером.
И поэтому тут уже недостаточно везде FIFO. Это задача, во благо которой трудится QoS.
Но в каком месте располагать эту память и где реализовывать QoS?
Места возникновения перегрузок
Но никто не хочет бороться с перегрузками в четырёх местах.
Поэтому обычно:
А) Чип делают такой производительности, чтобы он смог обработать весь трафик, даже если тот начал одновременно поступать со всех портов на этой линейной карте. Поэтому для устройства со 128 портами 100Гб/с используется чип с производительностью 12,8Тб/с.
Очевидно, бывают и исключения. Тогда или имеем непредсказуемые потери, или (чаще) невозможность использовать часть портов.
Б) Фабрику также делают без переподписки, чтобы она могла провернуть весь трафик, который пытаются в неё передать все линейные карты, даже если они делают это одновременно на полной скорости. Таким образом, не нужно буферизировать трафик и перед отправкой на фабрику.
В) Управление перегрузками на выходном чипе и выходном интерфейсе сводят в одно место.
Архитектура буферов
Crossbar
Это, скорее, умозрительный эксперимент, потому что в плане сложности, стоимости реализации и эффективности это проигрышный вариант.
Shared Buffer
По числу существующих в мире коробок этот вариант, однозначно, на первом месте.
Используется Shared Buffer на немодульных устройствах без фабрики коммутации, в которых установлен один чип (обычно, но может быть больше).
Итак, есть соблазн эту память взять и просто равномерно разделить между всеми портами. Такой статический дизайн имеет право на жизнь, но сводит на нет возможность динамически абсорбировать всплески трафика.
Гораздо более привлекательным выглядит следующий вариант:
Dedicated + Shared
Наличие Shared Buffer»а решает огромную проблему, позволяя сглаживать всплески трафика, когда перегрузку испытывает один или несколько интерфейсов.
Поэтому, зачастую, помимо Dedicated и Shared буферов, резервируют ещё Headroom buffers.
Headroom buffers
Коммутатор, заметив заполнение общего буфера, отправляет Pause для более низкого приоритета, тем самым притормаживая репликацию, но не RoCE.
Задача буфера Headroom здесь в том, чтобы сохранить те пакеты приоритетной очереди, что сейчас в кабеле, пока Pause летит к отправителю с просьбой притормозить. То есть пакеты репликации начнут дропаться, когда заполнится общий буфер, а пакеты RoCE будут складываться в Headroom.
Помимо lossless headroom бывает и headroom для обычного трафика, чтобы помочь сохранить более приоритетный. Но это на домашнее задание.
Разумеется, описанное выше лишь частный пример, и от вендора к вендору ситуация может различаться (разительно).
Например, бродкомовские чипы (как минимум, Trident и Tomahawk) имеют внутреннее разделение памяти по группам портов. Общая память делится на порт-группы по 4-8 портов, которые имеют свой собственный кусочек общего буфера. Порты из одной группы, соответственно буферизируют пакеты только в своём кусочке памяти и не могут занимать другие. Это тоже один из способов снизить влияние перегруженных портов друг на друга. Такой подход иногда называют Segregated Buffer.
Admission Control
В случае Shared Buffer оба механизма срабатывают в момент первичного помещения пакета в буфер. То есть, никакой двойной буферизации и проверки не происходит.
Как именно понять, сколько буфера занято конкретным портом/очередью и главное, сколько ещё можно ему выдать? Это может быть статический порог, одинаковый для всех портов, а может быть и динамически меняющийся, регулируемый параметром Alpha.
Alpha
Итак, почти во всех современных чипах память распределяется динамически на основе информации о том, сколько общей памяти вообще свободно и сколько ещё можно выделить для данного порта/очереди.
Предполагаем тут, что значение alpha одинаково для всех регионов, хотя оно может быть настроено отдельно для каждого.
При получении каждого пакета, механизм Admission Control вычисляет актуальный порог для региона, которому принадлежит пакет. Если порог меньше размера пакета, тот отбрасывается.
Если же больше, то он помещается в буфер и уже не будет отброшен никогда, даже если регион исчерпал все лимиты. Объём свободной памяти уменьшается на размер пакета.
Это происходит для каждого приходящего на чип пакета.
Написанное выше об Admission Control и Alpha может быть справедливо не только для Shared Buffers, но и для других архитектур, например, VoQ.
Output Queueing
Input Queuing
Более удачным вариантом оказывается буферизировать пакеты на входной плате после лукапа, когда уже становится понятно, куда пакет слать. Если выходной интерфейс заведомо занят, то и смысла гнать камикадзе на фабрику нет.
Постойте! Как же входной чип узнает, что выходной интерфейс не занят?
Combined Input and Output Queueing
Кроме того, для обеспечения QoS придётся хоть какой-то минимум его функций реализовывать в двух местах, что опять же скажется на цене продукта.
Представьте себе ситуацию: однополосная дорога, перекрёсток, машине нужно повернуть налево, сквозь встречный поток. Она останавливается, и ждёт, когда появится окно для поворота. А за ней стоит 17 машин, которым нужно проехать прямо. Им не мешает встречный поток, но им мешает машина, которая хочет повернуть налево.
Трагическая история, как в реальной жизни, так и на сетевом оборудовании.
Virtual Output Queueing
Ровно то же самое сделали разработчики сетевого оборудования.
Они взяли входной буфер побольше и подробили его на множество очередей.
Для каждого выходного интерфейса они создали по 8 очередей на каждом чипе коммутации. То есть перенесли все задачи по обеспечению QoS на входной чип. На выходном же при этом остаётся самая базовая FIFO очередь, в которой никогда не будет заторов, потому что их контроль взял на себя входной чип.
Если взять, грубо говоря, коробку со 100 интерфейсами, то на каждой плате в буферах нужно будет выделить 800 очередей. Если в коробке всего 10 линейных карт, то общее число очередей на ней будет 100*8*10 = 8000.
На сегодняшний день подавляющее большинство модульных сетевых устройств используют архитектуру VOQ.
Shallow vs Deep Buffers
Чуть позже мы поговорим о том, что такое хорошо, а что такое плохо. А пока посмотрим на реализации.
Такие буферы порой даже называют Extremely shallow buffers.
Очевидно, что не для всех задач такие маленькие буферы подходят. В частности, модульные коробки с VOQ явно не могут позволить себе дробить 64 Мб на несколько тысяч очередей (на самом деле могут).
Как такая память реализована зависит уже от чипа и коробки.
Например, Broadcom Jericho+ сгружает пакеты во внешнюю память в размере 4ГБ. Это обычная широко известная GDDR5, использующаяся в видеокартах.
А вот и фото Jericho2:
Фото чипа ZX EXPRESS:
А вот так выглядит сетевой процессор Cisco с внешней памятью:
Кастомный джуниперовский HMC обещает 1,25 Тб/с в обоих направлениях.
Если верить вики, то HBM 2-го поколения, используемый в последнем чипе Broadcom Jericho2, выдаёт порядка 2Тб/с.
Но это всё ещё далеко от реальной производительности сетевого ASIC. Фактически, шины до этой внешней памяти является узким местом, которое и определяет производительность чипа.
Hybrid Buffering
Данный параграф отменяет сказанное выше о том, что on-chip памяти не хватит для VOQ. Фактически, в случае гибридной буферизации она всё же дробится на тысячи очередей очень маленькой длины, чтобы обеспечить VOQ. Просто в нормальных условиях этой длины хватает, чтобы пропускать трафик мимо внешней памяти. При этом, в первую очередь начнёт офлоадиться на внешнюю память массивный трафик, идущий в низкоприоритетных очередях, а требовательный к задержками будет по-прежнему пролетать фаст-пасом.
В целом, это довольно старая дилемма. Подольше похранить или пораньше дропнуть?
Проект www.bufferbloat.net иронично определил этот термин, как «ухудшение производительности Интернета, вызванное предыдущими попытками её улучшения».
Особая история на границе датацентра (или на устройствах доступа в сети провайдера или на магистральных сетях).
Во-первых, это места, которые обычно заведомо строятся с переподпиской, поскольку WAN-линки дорогие, что автоматически означает, что ситуации, в которых трафика приходит больше, чем способен переварить интерфейс, ожидаемы. А значит нужна возможность пакеты хранить и обрабатывать их в соответствии с приоритетами. Большие буферы позволяют сгладить всплески.
Во-вторых, обычно приложения настолько чувствительные к задержкам, никто не будет пытаться растягивать на этот сегмент. Например, RoCE или распределённое хранилище. Для чуть менее чувствительных, таких как телефония, в больших буферах выделяется приоритетная очередь.
В-третьих, тут задержки на устройстве всё ещё делают основной вклад в общее время доставки, но уже не настолько драматический.
Итак, устройства с большим объёмом памяти годятся в места где заложена переподписка или могут появиться заторы.
Storage. Это штука крайне чувствительная к потерям и тоже гоняющая массивные объёмы данных. В случае хранилки тоже лучше не терять ничего. Но обычно она при этом и к задержкам предъявляет строгие требования, поэтому такие приложения обсудим пониже.
Однако, при этом крайне редко они единственные потребители сети в датацентрах, другим приложениям нужна низкая задержка.
Впрочем, это легко решается выделением очередей QoS с ограничением максимальной доступной глубины. И весь вопрос заключается тогда только в том, готова ли компания заплатить за глубокие буферы, возможно, не использовать их и поддерживать конфигурацию QoS.
Кстати, показательная таблица типичных задержек:
Low-latency lossless сети
Так что же можно сделать? На самом деле, как я уже говорил выше, условия сети датацентра хороши тем, что информация о перегрузке очень быстро доносится до отправителей. Поэтому и реакция на потерянный пакет не заставит себя долго ждать.
ECN-Based
Транзитное устройство, готовящееся испытать перегрузку, явным образом сообщает отправителям о том, что нужно охладить свою страсть.
Надолго забытый механизм сегодня извлекают из ящика стола, сдувают с него пыль, и вставляют в шкатулку, на которой нацарапано или DCTCP.
Транзитное устройство при заполнении буфера больше, чем до определённого порога, выставляет в заголовках IP обрабатываемых пакетов бит CE (Congestion Encountered) и отправляет пакет дальше.
Получатель, увидев в пришедшем пакете этот флаг, сообщает отправителю о перегрузке, и о том, что нужно снизить скорость.
Классический TCP может обнаружить только уже существующую перегрузку, а DCTCP, используя ECN, узнаёт о том, что она только приближается, и пробует её избежать.
Есть и другие реализации TCP, поддерживающие ECN, например, HTCP.
Нюанс с ECN-based Congestion Control механизмами в том, что до поры до времени они ничего не знают о надвигающейся перегрузке, а потом должен пройти ещё целый RTT, чтобы отправитель узнал, что какое-то транзитное устройство к ней близко. К тому времени, как отправители начнут снижать скорость, перегрузка уже может или рассосаться или наоборот дойти до уровня, когда начнутся дропы.
Bandwidth-Delay Product Based
Другие реализации замеряют эффективную полосу сети совместно с RTT, то есть сколько можно ещё напихать в трубу до того, как это создаст затор и увеличит задержку.
Примерами таких протоколов являются BBR и H-TCP.
RTT-BASED
В конце концов есть элегантные механизмы, которые замеряют время прохода трафика туда-обратно. Идея провальная для MAN/WAN-сегментов, и, честно говоря, при попытке программной вычисления RTT тоже. TIMELY от Google с аппаратным offload»ом вычисления RTT один из наиболее удачных примеров.
На самом деле, если бы не видео с прекрасной девушкой, рассказывающей про технические детали TIMELY, не знаю даже стал ли бы я упоминать про него. Наслаждайтесь, но берегите уши: TIMELY: RTT-based Congestion Control for the Datacenter.
Полезные ссылки
Заключение
Большие потоки трафика и управление прерываниями в Windows
Мне очень понравился топик про распределение нагрузки от прерываний сетевого адаптера по процессорам, поэтому я решил описать как это делается в 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: