Уменьшение времени загрузки «AlphaRS»

„AlphaRS” system
Система „AlphaRS”.
Фотография: Alpha Omega.

Проблема

Устройство «AlphaRS» не является частью компьютера пользователя. Это дополнительная коробка, которая получает электричество от её собственного блока питания, подсоединённая к компьютеру пользователя только кабелем Ethernet. Соответственно, пользователь — нейрохирург или нейрофизиолог — может включать и выключать её независимо от своего компьютера. Поскольку код устройства «AlphaRS» не сохраняется на самом устройстве, возникает необходимость каждый раз после включения «AlphaRS» передавать его на устройство с нуля.

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

Загрузка кода выполняется стоковым Ethernet-загрузчиком Texas Instruments, поставляющимся вместе с DSP. Загрузчик передавал бинарный файл кода для всех восьми ядер (примерно 12 мегабайт) из заранее заданной папки в файловой системе компьютера нейрохирурга. После трансфера файла на устройство загрузчик распаковывал полученный файл, переносил скомпилированный код для каждого ядра в память соответствующего ядра, устанавливал instruction pointer каждого ядра на начало функции c_int00() и начинал выполнение этого кода. Этот процесс подробно описан в документации загрузчика TI.

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

Решение

Во-первых, я тщательно изучил процесс загрузки кода по Ethernet.

Если вкратце, то устройство, которое хочет, чтобы его загрузили по сети, инициализирует Ethernet-адаптер и начинает рассылать стандартный пакет, называемый BOOTP request, то есть буквально просит «Пожалуйста, загрузите меня кто-нибудь, мой адрес <MAC-адрес Ethernet-адаптера>». Эта просьба рассылается по всей доступной сети каждые несколько секунд.

Поскольку наша программа на компьютере нейрохирурга знает, какой MAC-адрес у устройства «AlphaRS», то до установления связи она выполняет polling: она прослушивает весь сетевой трафик на одном из сетевых адаптеров и фильтрует его при помощи npcap. Когда в сетевом трафике появляется пакет BOOTP request, отправленный с MAC-адреса «AlphaRS», программа начинает свою часть работы: отправляет по этому MAC-адресу конфигурацию TCP/IP и добавляет свой обратный адрес в поле «BOOTP server». Получив этот ответ, «AlphaRS» применяет полученные настройки TCP/IP и — уже через TCP/IP — просит у BOOTP сервера, то есть у компьютера пользователя, скомпилированный файл с кодом для «AlphaRS».

Я сделал несколько предположений:

  • Во-первых, подключение между компьютером пользователя и устройством «AlphaRS» проводное и выполнено при помощи Ethernet-кабеля, без хабов, свитчей и тому подобных раутеров. (На самом деле, это одно из требований к подключению).
  • Во-вторых, адаптер сконфигурирован с поддержкой IPv4. (На момент разработки этой версии «AlphaRS» мы ещё не поддерживали IPv6).
  • В-третьих, вряд ли пользователь будет часто менять способ подключения «AlphaRS» к своему компьютеру; например, он не будет каждый раз подключать устройство к другому сетевому адаптеру.

После этого я изучил, как наша программа, запускаемая на компьютере нейрохирурга, конфигурирует фильтр npcap.

Оказалось, что в момент запуска программы она создаёт список всех сетевых адаптеров, о которых знает Windows®, и прослушивает трафик на каждом из них по очереди, конфигурируя npcap для поиска пакета BOOTP request с заранее известным MAC-адресом устройства «AlphaRS» во всём трафике на этом адаптере. Каждый адаптер прослушивается в течение одной секунды, и если пакет BOOTP request не был обнаружен, программа переконфигурирует npcap для прослушивания следующего адаптера. Этот цикл повторяется раз за разом, до тех пор, пока пакет BOOTP request не будет обнаружен.

Список всех сетевых адаптеров, определённых в Windows®, может быть довольно большим, даже если реальных, физических сетевых адаптеров, связанных с гнездом 8P8C, находящимся где-нибудь в компьютере, не так много. Но устройство «AlphaRS» может быть подключено только к последним. Например, сетевой адаптер loopback можно спокойно пропустить, — «AlphaRS» к нему не будет подключено никогда. Точно так же можно пропустить все беспроводные адаптеры, виртуальные адаптеры и сетевые мосты. Это сильно сокращает список, — вплоть до того, что из 27 сетевых адаптеров остаются под подозрением всего 3 или 4.

Последнее сделанное мной предположение привело меня к мысли, что я могу записать идентификатор того сетевого адаптера, через который устройство «AlphaRS» было подключено в предыдущий раз, и начать поиск именно с него. Если пользователь подключил провод Ethernet от «AlphaRS» к другому физическому сетевому адаптеру в своём компьютере, то я потеряю несколько секунд, — ну и ладно. Но если подключение осталось нетронутым, — что, согласно предположению, наиболее вероятно, — то я могу сэкономить десятки секунд.

Вдобавок, я проверил код, который настраивает фильтр npcap, и обнаружил, что для каждого адаптера сетевой трафик прослушивается на протяжении одной секунды. А пакет BOOTP request посылается каждые три секунды. Это приводило к огромному количеству ложноотрицательных заключений, когда программа решала, что устройство «AlphaRS» не подключено к прослушиваемому адаптеру, хотя на самом деле программа просто не успевала дождаться следующего пакета «BOOTP request». Я увеличил время прослушивания каждого адаптера до четырёх секунд.

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

Результат

Время загрузки устройства «AlphaRS» сократилось с 3-5 минут в худшем случае до 3-5 секунд в худшем случае.