Например, я отправляю 100000 UDP-пакетов в Windows. Для каждого пакета мне нужно позвонить WSASendTo()
один раз, так что, вероятно, появится много служебных издержек системного вызова. Есть ли способ сделать массовую отправку и уменьшить накладные расходы? Я не мог найти решение для Windows после поиска в Google. Кроме того, я хотел бы знать, возможно ли это в Linux. Благодарю.Как уменьшить системные вызовы при отправке большого количества UDP-пакетов? (и Windows и Linux)
ответ
В Windows вы можете использовать новый Windows I/O API (RIO) на сервере 2012 и Windows 8 и более поздних версиях.
Я написал довольно много об этом here и провел несколько сравнений производительности с предыдущими API, которые доступны в Windows. Тесты производительности можно найти here.
Вкратце: «Зарегистрированные сетевые расширения ввода-вывода, RIO, это новый API, который был добавлен в Winsock для поддержки высокоскоростных сетей для повышения производительности сети с более низкой задержкой и джиттером. для серверных приложений и использования предварительно зарегистрированных буферов данных и очередей завершения для повышения производительности. Повышенная производительность возникает из-за того, что не нужно блокировать страницы памяти и копировать структуры в пространстве ядра при выдаче отдельных запросов, вместо этого полагаясь на блокированные буферы, фиксированные очереди завершения, необязательное уведомление о событиях при завершении и возможность возвращать несколько завершений из пространства ядра в пространство пользователя за один раз ».
Результаты моих тестов производительности, похоже, подразумевают, что они работают.
Отличный учебник по RIO! – Chen
Подождите. Параметр 'DataBufferCount'' RIOSend() 'в настоящее время может быть только 1 или 0, поэтому моя проблема все еще не решена:/Hope MS позволит нам указать ture' DataBufferCount' в будущих версиях Windows. – Chen
Ох. Возможно, я могу вызвать 'RIOSend()' с 'RIO_MSG_DEFER', чтобы отправить запросы отправки в очередь и в конечном итоге указать' RIO_MSG_COMMIT_ONLY', чтобы выполнить фактическую работу. Нужен бенчмаркинг, чтобы узнать, действительно ли это происходит быстрее. – Chen
Используйте TransmitPackets()
в Windows.
- 1. Системные вызовы и режим Linux Linux
- 2. Системные вызовы в Windows
- 3. Системные вызовы и системные программы
- 4. Системные вызовы Windows-программ
- 5. Параллельные системные вызовы в Linux
- 6. Сборочные и системные вызовы
- 7. Linux: Системные вызовы для кого
- 8. Системные вызовы Linux возвращают значение
- 9. Системные вызовы Linux и API зависят от дистрибутивов Linux?
- 10. Сокет закрывается при отправке большого количества данных?
- 11. Лаги при отправке большого количества данных
- 12. Как запретить системные вызовы, GNU/Linux
- 13. Дескрипторы файлов и системные вызовы
- 14. C Системные вызовы и сообщения
- 15. Системные вызовы в windows & Native API?
- 16. Какие ОС и системные вызовы Windows и Linux сделаны из malloc()?
- 17. glibc и системные вызовы, прерванные сигналами
- 18. Windows и системные процессы
- 19. Где в ядре linux отправляются системные вызовы?
- 20. открытые системные вызовы в C on linux
- 21. Системные вызовы в Perl
- 22. системные и вилочные вызовы блокируют порт 3000
- 23. Системные вызовы, управляющие каталогами
- 24. Системные вызовы и код ошибки EINTR
- 25. fork() - множественные процессы и системные вызовы
- 26. Все системные вызовы требуют SSDT в Windows?
- 27. Системные вызовы, команды и программы оболочки
- 28. Поведение и системные вызовы NaCl sel_ldr
- 29. C стандартная библиотека и системные вызовы
- 30. Различия b/w системные вызовы и вызовы пользователей в linux или любой ОС
OK. В Linux я могу использовать 'sendmmsg()'. Тогда этот вопрос касается только Windows. – Chen
'WSASendMsg()' кажется эквивалентом Windows 'sendmmsg()', но [документ MSDN] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms741693 (v = vs.85) .aspx) явно не говорит, что эта функция отправляет разные буферы в виде разных пакетов. – Chen
Нет, это не эквивалент 'sendmmsg' (и не работает' WSARecvFrom'). Вы можете предоставить более одного буфера и использовать разброс/сборку, да. Но у вас есть только одно значение для байтов для отправки/получения и одно единственное возвращаемое значение для байтов, полученных/отправленных. Это работает для одного потока TCP, но не для датаграмм UDP, где вам нужны N размеров для отправки и N размеров, отправленных (или успех/сбой) для N датаграмм. Насколько мне известно, Windows не имеет такой возможности для сокетов. – Damon