Как справиться с 320 миллионами 272-байтовых UDP пакетов?
Таким образом, у меня есть входящий поток UDP, состоящий из 272 байтовых пакетов со скоростью передачи данных около 5,12 Гбит/с (около 320e6 пакетов в секунду). Эти данные передаются пользовательской платой на базе ПЛИС. Размер пакета-это ограничение на запускаемый цифровой дизайн, поэтому, хотя теоретически можно было бы увеличить его, чтобы сделать вещи более эффективными, это потребовало бы большого объема работы. На приемном конце эти пакеты считываются и интерпретируются сетевым потоком и помещаются в циклический поток. буфер совместно используется с потоком буферизации, который копирует эти данные на графический процессор для обработки.
Вышеописанная установка на приемном конце могла бы справиться с 5,12 Гб/с для пакета 4096 КБ (используемого на другом дизайне), используя простые вызовыrecv
, однако с текущим размером пакета мне трудно идти в ногу с потоком пакетов, слишком много времени "тратится" на переключение контекста и копирование небольших сегментов данных из пространства ядра в пространство пользователя. Я сделал быстрый тест реализации, которая использует recvmmsg
, однако ситуация не улучшилась намного. В среднем я могу обрабатывать около 40% входящих пакетов.
Итак, мне было интересно, можно ли получить дескриптор буфера данных UDP ядра для моего приложения (стиль mmap) или использовать какое-то нулевое копирование из ядра в пространство пользователя? Кроме того, знаете ли вы какой-либо другой метод, который уменьшил бы эти накладные расходы и был бы способен выполнять необходимую обработку?
Это выполняется на машине Linux (ядро 3.2.0-40) с использованием кода С.
1 ответ:
В Linux есть поддержка приема пакетов mmap.
Это не так просто использовать в качестве сокетов UDP, потому что вы будете получать пакеты, как из RAW сокета.
Смотрите это для получения дополнительной информации.