Чтение из сети и обработка
От: tryAnother  
Дата: 09.02.22 12:28
Оценка:
Приветствую.
Есть программа (windows сервис) которая принимает поток udp пакетов от специальной железки (в выделенной сети) примерно 20 000 пакетов в секунду примерно по 1 КБ.
Сейчас программа организована так, есть поток, который просыпается примерно раз в 20 мс и забирает из приемного буфера все принятые пакеты (размер приемного буфера устанавливается на примерно 5000 пакетов)
Вычитанные пакеты копируются каждый в свой буфер. Буферы складываются в лист. После того как вычитаны все пакеты в текущем такте обработке, данный список под критической секцией добавляется (splice) в другой и ставится event другому потоку о готовности.
Другой поток забирает список себе, сортирует в нем пакеты обрабатывает некоторые флаги складывает в новый список и ставит event следующему потоку обработки.
Следующий поток уже занимается собственно обработкой данных в пакетах, паковкой и тд.

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

Попробовал сделать вычитывание на основе синхронного и асинхронного boost::asio производительность оказалась недостаточная, стали происходить потери пакетов от железки (единицы пакетов в секунду при передаче 20000) при том что тестовый код никак больше не обрабатывал пакеты, а только смотрел за шагом номера пакета.
Поэтому сейчас оставлен периодически просыпающийся поток с setsockopt(sock, SO_RCVBUF, ...) и ioctlsocket(sock, FIONREAD, ...).

Пакет хранится в векторе, обернутом самодельным подсчетом ссылок и обрабатывается самодельным пулом (по историческим причинам), на сколько я знаю подсчет ссылок не лучший вариант для обработки в нескольких потоках из-за синхронизации кэшей процессора можно получить серьезную просадку производительности.
Что тут можно сделать? Перейти на boost подсчет ссылок но там смысл тот же.
В общем может кто подскажет интересные решения
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.