Хабрахабр

Шина PCIe: только ли физические ограничения влияют на скорость передачи?

Начну издалека. Прошлой зимой довелось мне делать USB-устройство с ядром, размещаемым в ПЛИС. Само собой, очень мне хотелось проверить реальную пропускную способность этой шины. Ведь в контроллере — там слишком много всего наверчено. Всегда можно сказать, что вот тут внесена задержка, или вон там. В случае же с ПЛИС — я вижу блок, прокачивающий данные, вот он сказал мне, что в нём данные есть. А вот я выставил, что всё обработано, и я готов принимать новую порцию (при этом, он уже принимает данные во второй буфер этой же конечной точки). Отлично, ставим готовность с первого же такта и смотрим, что получается, когда USB может «молотить» без остановки.

Если USB 2.
А получается удивительная вещь. 0), то скорость получается одна. 0 устройство воткнуто в «голубенький» разъём (это который USB 3. Вот мой график зависимости скорости записи в USB от длины передаваемых данных. Если в «чёрненький» — другая. 0 HS. USB3 и USB2 — это тип разъёма, устройство всегда USB 2.

Результат — близок. Я пробовал в разных машинах. Уже потом я нашёл наиболее вероятную причину. Никто не мог объяснить мне этот феномен. Вот свойства контроллера USB 2. А причина очень проста. 0:

А разница — как раз примерно процентов 20. У контроллеров, управляющих «голубеньким» разъёмом такого нет.

Иногда накладываются ещё какие-то вещи. Из этого мы делаем вывод, что не всегда ограничения пропускной способности определяются физическими свойствами шины. Переходим с этими знаниями в наши дни.

Первичный эксперимент

Итак. Всё начиналось весьма буднично. Шла проверка одной программы. Проверялся процесс записи данных одновременно на несколько дисков. Аппаратура простая: имеется материнская плата с четырьмя PCIe-слотами. Во все слоты воткнуты совершенно одинаковые карточки с AHCI-контроллерами, каждый из которых поддерживает исключительно PCIe x1.

Берём один диск и начинаем записывать на него данные. Каждая карта обслуживает 4 накопителя.
И вот выясняется следующий эффект. Получаем скорость от 180 до 220 мегабайт в секунду (здесь и далее, мегабайт — это 1024*1024 байт):

Скорость записи на него — от 170 до 190 МБ/с: Берём второй накопитель.

Пишем сразу на оба — получаем просадку скорости:

Но удивительность состоит в том, что отлаживали (так получилось) эту программу мы на тех же накопителях, но на других каналах. Суммарная скорость получается в районе 290 МБ/с. Быстро перетыкаем в те каналы (они будут идти через другую карту), получаем прекрасную работу: И там всё было хорошо.

Куплю слот в хорошем районе

Сразу скажу, что винить во всём какие-то чужие компоненты не стоит. Здесь всё написано нами, начиная от самой программы, заканчивая драйверами. Так что весь путь прохождения данных может быть проконтролирован. Неизвестность наступает только когда запрос ушёл в аппаратуру.

Длинные — это куда можно вставить карты x16 (правда, один из них работает в режиме не выше x4), а короткие — только для карт x1. После первичного разбора выяснилось, что скорость не ограничивается в «длинных» слотах PCIe и ограничивается в «коротких».

То есть, все контроллеры должны быть в абсолютно идентичных условиях, независимо от длины слота! Всё бы ничего, но контроллеры в текущих картах в принципе не могут работать в режиме, отличном от PCIex1. Кто живёт в «длинном» — работает быстро, кто в «коротком» — медленно. Ан нет. А быстро — насколько быстро? Хорошо. Добавляем третий накопитель, пишем на все три.

В «коротких» слотах ограничение всё ещё в районе 290 МБ/с:

В «длинных» — в районе 400 МБ/с:

Во-первых, через некоторое время я уже смеялся со статей, где говорится о том, что пропускная способность PCIe gen 1 и gen 2 для x1 составляет 500 МБ/с. Я перерыл весь Интернет. За счёт оверхеда (я использую это нерусское слово, чтобы обозначить служебный обмен, идущий по тем же линиям, что и основные данные) получается именно 400 мегабайт в секунду полезного потока. Это «сырые» мегабайты. Во-вторых, я упорно не мог найти ничего про магическую цифру 290 (забегая вперёд — до сих пор не нашёл).

Пытаемся глянуть на топологию включения наших контроллеров. Отлично. Зелёные —быстрые, красные — медленные. Вот она (013-015 — это суффиксы имён устройств, по которым я сопоставил их, чтобы как-то различать).

Он живёт в привилегированном слоте, предназначенном для видеокарты. Контроллер «015» мы даже не рассматриваем. Чем он отличается? Но 013-й подключён к тому же коммутатору, что и 012-й с 014-м.

Я изучил конфигурационное пространство всех карт — этот параметр стоит у всех в одном и том же, минимально возможном значении. Отдельные статьи говорят, что разные карты могут отличаться параметрами Max Payload. Мало того, в документации на чипсет этой материнки сказано, что иного значения и быть не может.

А скорость разная! В общем, я перерыл всё в конфигурационном пространстве — всё настроено идентично. Приоритеты — да, что-то про них написано, но тесты же ведутся при полном отсутствии нагрузки по другим каналам! Многократно перечитал документацию на чипсет — никаких настроек пропускной способности. То есть дело не в них.

Нагрузка на процессор возросла до безумных величин, ведь теперь он постоянно тупо читает бит готовности, но показания скорости не изменились. На всякий случай, я даже отключил работу программы по прерываниям. Так что обвинить в проблемах эту подсистему тоже нельзя.

А что там у других плат?

Попробовали поменять материнскую плату на точно такую же. Никаких изменений. Попробовали заменить процессор (были основания считать, что он барахлит). Тоже никаких изменений скорости (но старый процессор и правда барахлил). Поставили материнскую плату более нового поколения — всё просто летает на всех слотах. Причём предельная скорость уже не 400, а 418 мегабайт в секунду, хоть в «длинных», хоть в «коротких» слотах:

Привычным движением руки (за эти дни уже привык) считываем конфигурационное пространство и видим, что параметр Max Payload установлен не на 128, а на 256 байт. Но здесь — никаких чудес.

Меньше оверхед на их пересылку — больше полезных данных успевает пробежать за то же время. Больше размер пакета — меньше количество пакетов. Всё верно.

Так кто же виноват?

Точного ответа на вопрос из заголовка, со ссылкой на документы, я не дам. Но мысль моя пошла по следующему пути: допустим, что ограничение потока задано внутри чипсета. Его нельзя программировать, оно задано намертво, но оно есть. Например, оно равно 290 мегабайт в секунду на каждую дифф. пару. Больше — режется уже где-то внутри чипсета на его внутренних механизмах. Поэтому в «длинном» слоте (куда можно воткнуть карты вплоть до x4) внутри чипсета для нашей карты ничего не режется, а мы упираемся в физический предел шины x1. В «коротком» же разъёме мы упираемся в это ограничение.

Втыкаем в 013-й слот не AHCI, а SAS-контроллер, который обслуживает сразу 8 накопителей и может работать в режимах PCIe вплоть до x4. На самом деле, проверить это не просто, а очень просто. Смотрим скорость записи — аж душа радуется: Подключаем ему 4 шустрых SSD накопителя.

Скорость работы SSD предсказуемо просела: Теперь добавляем те 4 диска, которые фигурировали в первых тестах.

Делим на 4 (столько линий идёт в «длинный» слот), получаем… Барабанная дробь… 293 мегабайта в секунду. Вычисляем суммарную скорость, проходящую через SAS-контроллер, получаем 1175 мегабайт в секунду. Где-то я это число уже видел!

Была выведена методика подбора материнских плат, которые могут быть использованы в проекте. Итак, в рамках данного проекта было доказано, что дело не в нашей программе или драйвере, а в странных ограничениях чипсета, которые наверняка «зашиты» намертво. А в целом, выводы делаем следующие.

Заключение

  • Зачастую в реальной жизни аппаратура имеет меньшую производительность, чем теоретически возможная. Ограничения могут накладываться даже драйверами, как показано в случае USB. Иногда удаётся подобрать такую аппаратуру, которая (или драйверы которой) не имеет таких ограничений.
  • Ограничения могут быть даже недокументированными, но чётко выраженными.
  • Масса статей, в которых говорится, что одна дифференциальная пара PCIe gen. 1 и gen 2 даёт примерно 500 мегабайт в секунду, ошибочны. Они копируют друг у друга одну и ту же ошибку — 500 мегабайт «сырых» байтов в секунду. Оверхед накапливается на нескольких уровнях интерфейса. При Max Payload 128 байт, реально получается около 400 мегабайт в секунду. В более новых поколениях PCIe всё должно быть чуть лучше, так как там физическое кодирование не 8b/10b, а более экономичное, но пока не найдено ни одного контроллера дисков, на которых можно было бы проверить это на практике.
Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть