Часто ли хочется переписать что-то с чистого листа? Часто ли резрешают это сделать? Что думают QA о регрессиях? Legacy-код навязчиво предлагает готовые решения, от которых будет только хуже? Иногда хочется отказаться от привычных средств и написать по-другому. Иногда на этот шаг вынуждают обстоятельства. И под убегающим влево курсором исчезает то, что давно пора было отрезать.
Задача была проста и тривиальна - снизить сетевой latency в 3 раза. Речь шла о библиотеке, которая подключалась к UDP multicast group, получала дейтаграммы, декодировала сообщения и отдавала их клиентскому коду. Декодирование и распаковка были вылизаны до предела, оставалось улучшать транспортный уровень. Существовавшая реализация базировалась на Boost.asio, выдавала 30 микросекунд на обработку одного сообщения, очень хорошо масштабировалась, не потребляла в работе много времени CPU и использовалась по умолчанию по всей библиотеке. Заказчик хотел снизить этот результат до 10 микросекунд. Поскольку речь шла о Взрослом Enterprise, оптимизацией циклов на asm никто не занимался, просто сменили сетевой API со стандартных UDP сокетов, на более быстрый, проприетарный. Всё волшебство быстрого API основывалось на сетевой карте за 1к и экспериментальных драйверах. Карточка несла на борту два SFP+ порта, два процессора и числилась в категории 10Gbit/s. На слайдах маркетинговой презентации для данной модели заявлялись цифры в 4.5 микросекунды на получение 200 байт из сети и аббревиатура HPC. Желание о 10 микросекундах казалось уже более обоснованным.
API драйвера в общих чертах повторял BSD сокеты, но имел два важных отличия:
- Сокет нужно было создавать на предварительно открытом сетевом interface с фиксированным IP
- Операции чтения у сокета не было. Вместо этого чтение предполагалось выполнять над interface, на котором были открыты сокеты. Операция recvfrom позволяла проверить, для какого из сокетов есть дейтаграмма, и прочитать её в буфер.
Релоцировались? Теперь вы можете комментировать без верификации аккаунта.